libstdc++
stl_uninitialized.h
Go to the documentation of this file.
1// Raw memory manipulators -*- C++ -*-
2
3// Copyright (C) 2001-2023 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/*
26 *
27 * Copyright (c) 1994
28 * Hewlett-Packard Company
29 *
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Hewlett-Packard Company makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
37 *
38 *
39 * Copyright (c) 1996,1997
40 * Silicon Graphics Computer Systems, Inc.
41 *
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Silicon Graphics makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
49 */
50
51/** @file bits/stl_uninitialized.h
52 * This is an internal header file, included by other library headers.
53 * Do not attempt to use it directly. @headername{memory}
54 */
55
56#ifndef _STL_UNINITIALIZED_H
57#define _STL_UNINITIALIZED_H 1
58
59#if __cplusplus >= 201103L
60#include <type_traits>
61#endif
62
63#include <bits/stl_algobase.h> // copy
64#include <ext/alloc_traits.h> // __alloc_traits
65
66#if __cplusplus >= 201703L
67#include <bits/stl_pair.h>
68#endif
69
70namespace std _GLIBCXX_VISIBILITY(default)
71{
72_GLIBCXX_BEGIN_NAMESPACE_VERSION
73
74 /** @addtogroup memory
75 * @{
76 */
77
78 /// @cond undocumented
79
80#if __cplusplus >= 201103L
81 template<typename _ValueType, typename _Tp>
82 constexpr bool
83 __check_constructible()
84 {
85 // Trivial types can have deleted constructors, but std::copy etc.
86 // only use assignment (or memmove) not construction, so we need an
87 // explicit check that construction from _Tp is actually valid,
88 // otherwise some ill-formed uses of std::uninitialized_xxx would
89 // compile without errors. This gives a nice clear error message.
90 static_assert(is_constructible<_ValueType, _Tp>::value,
91 "result type must be constructible from input type");
92
93 return true;
94 }
95
96// If the type is trivial we don't need to construct it, just assign to it.
97// But trivial types can still have deleted or inaccessible assignment,
98// so don't try to use std::copy or std::fill etc. if we can't assign.
99# define _GLIBCXX_USE_ASSIGN_FOR_INIT(T, U) \
100 __is_trivial(T) && __is_assignable(T&, U) \
101 && std::__check_constructible<T, U>()
102#else
103// No need to check if is_constructible<T, U> for C++98. Trivial types have
104// no user-declared constructors, so if the assignment is valid, construction
105// should be too.
106# define _GLIBCXX_USE_ASSIGN_FOR_INIT(T, U) \
107 __is_trivial(T) && __is_assignable(T&, U)
108#endif
109
110 template<typename _InputIterator, typename _ForwardIterator>
111 _GLIBCXX20_CONSTEXPR
112 _ForwardIterator
113 __do_uninit_copy(_InputIterator __first, _InputIterator __last,
114 _ForwardIterator __result)
115 {
116 _ForwardIterator __cur = __result;
117 __try
118 {
119 for (; __first != __last; ++__first, (void)++__cur)
120 std::_Construct(std::__addressof(*__cur), *__first);
121 return __cur;
122 }
123 __catch(...)
124 {
125 std::_Destroy(__result, __cur);
126 __throw_exception_again;
127 }
128 }
129
130 template<bool _TrivialValueTypes>
131 struct __uninitialized_copy
132 {
133 template<typename _InputIterator, typename _ForwardIterator>
134 static _ForwardIterator
135 __uninit_copy(_InputIterator __first, _InputIterator __last,
136 _ForwardIterator __result)
137 { return std::__do_uninit_copy(__first, __last, __result); }
138 };
139
140 template<>
141 struct __uninitialized_copy<true>
142 {
143 template<typename _InputIterator, typename _ForwardIterator>
144 static _ForwardIterator
145 __uninit_copy(_InputIterator __first, _InputIterator __last,
146 _ForwardIterator __result)
147 { return std::copy(__first, __last, __result); }
148 };
149
150 /// @endcond
151
152 /**
153 * @brief Copies the range [first,last) into result.
154 * @param __first An input iterator.
155 * @param __last An input iterator.
156 * @param __result An output iterator.
157 * @return __result + (__first - __last)
158 *
159 * Like copy(), but does not require an initialized output range.
160 */
161 template<typename _InputIterator, typename _ForwardIterator>
162 inline _ForwardIterator
163 uninitialized_copy(_InputIterator __first, _InputIterator __last,
164 _ForwardIterator __result)
165 {
167 _ValueType1;
169 _ValueType2;
170
171 // _ValueType1 must be trivially-copyable to use memmove, so don't
172 // bother optimizing to std::copy if it isn't.
173 // XXX Unnecessary because std::copy would check it anyway?
174 const bool __can_memmove = __is_trivial(_ValueType1);
175
176#if __cplusplus < 201103L
177 typedef typename iterator_traits<_InputIterator>::reference _From;
178#else
179 using _From = decltype(*__first);
180#endif
181 const bool __assignable
182 = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType2, _From);
183
184 return std::__uninitialized_copy<__can_memmove && __assignable>::
185 __uninit_copy(__first, __last, __result);
186 }
187
188 /// @cond undocumented
189
190 template<typename _ForwardIterator, typename _Tp>
191 _GLIBCXX20_CONSTEXPR void
192 __do_uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
193 const _Tp& __x)
194 {
195 _ForwardIterator __cur = __first;
196 __try
197 {
198 for (; __cur != __last; ++__cur)
199 std::_Construct(std::__addressof(*__cur), __x);
200 }
201 __catch(...)
202 {
203 std::_Destroy(__first, __cur);
204 __throw_exception_again;
205 }
206 }
207
208 template<bool _TrivialValueType>
209 struct __uninitialized_fill
210 {
211 template<typename _ForwardIterator, typename _Tp>
212 static void
213 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
214 const _Tp& __x)
215 { std::__do_uninit_fill(__first, __last, __x); }
216 };
217
218 template<>
219 struct __uninitialized_fill<true>
220 {
221 template<typename _ForwardIterator, typename _Tp>
222 static void
223 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
224 const _Tp& __x)
225 { std::fill(__first, __last, __x); }
226 };
227
228 /// @endcond
229
230 /**
231 * @brief Copies the value x into the range [first,last).
232 * @param __first An input iterator.
233 * @param __last An input iterator.
234 * @param __x The source value.
235 * @return Nothing.
236 *
237 * Like fill(), but does not require an initialized output range.
238 */
239 template<typename _ForwardIterator, typename _Tp>
240 inline void
241 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
242 const _Tp& __x)
243 {
245 _ValueType;
246
247 // Trivial types do not need a constructor to begin their lifetime,
248 // so try to use std::fill to benefit from its memset optimization.
249 const bool __can_fill
250 = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType, const _Tp&);
251
252 std::__uninitialized_fill<__can_fill>::
253 __uninit_fill(__first, __last, __x);
254 }
255
256 /// @cond undocumented
257
258 template<typename _ForwardIterator, typename _Size, typename _Tp>
259 _GLIBCXX20_CONSTEXPR
260 _ForwardIterator
261 __do_uninit_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
262 {
263 _ForwardIterator __cur = __first;
264 __try
265 {
266 for (; __n > 0; --__n, (void) ++__cur)
267 std::_Construct(std::__addressof(*__cur), __x);
268 return __cur;
269 }
270 __catch(...)
271 {
272 std::_Destroy(__first, __cur);
273 __throw_exception_again;
274 }
275 }
276
277 template<bool _TrivialValueType>
278 struct __uninitialized_fill_n
279 {
280 template<typename _ForwardIterator, typename _Size, typename _Tp>
281 static _ForwardIterator
282 __uninit_fill_n(_ForwardIterator __first, _Size __n,
283 const _Tp& __x)
284 { return std::__do_uninit_fill_n(__first, __n, __x); }
285 };
286
287 template<>
288 struct __uninitialized_fill_n<true>
289 {
290 template<typename _ForwardIterator, typename _Size, typename _Tp>
291 static _ForwardIterator
292 __uninit_fill_n(_ForwardIterator __first, _Size __n,
293 const _Tp& __x)
294 { return std::fill_n(__first, __n, __x); }
295 };
296
297 /// @endcond
298
299 // _GLIBCXX_RESOLVE_LIB_DEFECTS
300 // DR 1339. uninitialized_fill_n should return the end of its range
301 /**
302 * @brief Copies the value x into the range [first,first+n).
303 * @param __first An input iterator.
304 * @param __n The number of copies to make.
305 * @param __x The source value.
306 * @return Nothing.
307 *
308 * Like fill_n(), but does not require an initialized output range.
309 */
310 template<typename _ForwardIterator, typename _Size, typename _Tp>
311 inline _ForwardIterator
312 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
313 {
315 _ValueType;
316
317 // Trivial types do not need a constructor to begin their lifetime,
318 // so try to use std::fill_n to benefit from its optimizations.
319 const bool __can_fill
320 = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType, const _Tp&)
321 // For arbitrary class types and floating point types we can't assume
322 // that __n > 0 and std::__size_to_integer(__n) > 0 are equivalent,
323 // so only use std::fill_n when _Size is already an integral type.
324 && __is_integer<_Size>::__value;
325
326 return __uninitialized_fill_n<__can_fill>::
327 __uninit_fill_n(__first, __n, __x);
328 }
329
330#undef _GLIBCXX_USE_ASSIGN_FOR_INIT
331
332 /// @cond undocumented
333
334 // Extensions: versions of uninitialized_copy, uninitialized_fill,
335 // and uninitialized_fill_n that take an allocator parameter.
336 // We dispatch back to the standard versions when we're given the
337 // default allocator. For nondefault allocators we do not use
338 // any of the POD optimizations.
339
340 template<typename _InputIterator, typename _ForwardIterator,
341 typename _Allocator>
342 _GLIBCXX20_CONSTEXPR
343 _ForwardIterator
344 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
345 _ForwardIterator __result, _Allocator& __alloc)
346 {
347 _ForwardIterator __cur = __result;
348 __try
349 {
351 for (; __first != __last; ++__first, (void)++__cur)
352 __traits::construct(__alloc, std::__addressof(*__cur), *__first);
353 return __cur;
354 }
355 __catch(...)
356 {
357 std::_Destroy(__result, __cur, __alloc);
358 __throw_exception_again;
359 }
360 }
361
362#if _GLIBCXX_HOSTED
363 template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
364 _GLIBCXX20_CONSTEXPR
365 inline _ForwardIterator
366 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
367 _ForwardIterator __result, allocator<_Tp>&)
368 {
369#ifdef __cpp_lib_is_constant_evaluated
371 return std::__do_uninit_copy(__first, __last, __result);
372#endif
373 return std::uninitialized_copy(__first, __last, __result);
374 }
375#endif
376
377 template<typename _InputIterator, typename _ForwardIterator,
378 typename _Allocator>
379 _GLIBCXX20_CONSTEXPR
380 inline _ForwardIterator
381 __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
382 _ForwardIterator __result, _Allocator& __alloc)
383 {
384 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
385 _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
386 __result, __alloc);
387 }
388
389 template<typename _InputIterator, typename _ForwardIterator,
390 typename _Allocator>
391 _GLIBCXX20_CONSTEXPR
392 inline _ForwardIterator
393 __uninitialized_move_if_noexcept_a(_InputIterator __first,
394 _InputIterator __last,
395 _ForwardIterator __result,
396 _Allocator& __alloc)
397 {
398 return std::__uninitialized_copy_a
399 (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
400 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
401 }
402
403 template<typename _ForwardIterator, typename _Tp, typename _Allocator>
404 _GLIBCXX20_CONSTEXPR
405 void
406 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
407 const _Tp& __x, _Allocator& __alloc)
408 {
409 _ForwardIterator __cur = __first;
410 __try
411 {
413 for (; __cur != __last; ++__cur)
414 __traits::construct(__alloc, std::__addressof(*__cur), __x);
415 }
416 __catch(...)
417 {
418 std::_Destroy(__first, __cur, __alloc);
419 __throw_exception_again;
420 }
421 }
422
423#if _GLIBCXX_HOSTED
424 template<typename _ForwardIterator, typename _Tp, typename _Tp2>
425 _GLIBCXX20_CONSTEXPR
426 inline void
427 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
428 const _Tp& __x, allocator<_Tp2>&)
429 {
430#ifdef __cpp_lib_is_constant_evaluated
432 return std::__do_uninit_fill(__first, __last, __x);
433#endif
434 std::uninitialized_fill(__first, __last, __x);
435 }
436#endif
437
438 template<typename _ForwardIterator, typename _Size, typename _Tp,
439 typename _Allocator>
440 _GLIBCXX20_CONSTEXPR
441 _ForwardIterator
442 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
443 const _Tp& __x, _Allocator& __alloc)
444 {
445 _ForwardIterator __cur = __first;
446 __try
447 {
449 for (; __n > 0; --__n, (void) ++__cur)
450 __traits::construct(__alloc, std::__addressof(*__cur), __x);
451 return __cur;
452 }
453 __catch(...)
454 {
455 std::_Destroy(__first, __cur, __alloc);
456 __throw_exception_again;
457 }
458 }
459
460#if _GLIBCXX_HOSTED
461 template<typename _ForwardIterator, typename _Size, typename _Tp,
462 typename _Tp2>
463 _GLIBCXX20_CONSTEXPR
464 inline _ForwardIterator
465 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
466 const _Tp& __x, allocator<_Tp2>&)
467 {
468#ifdef __cpp_lib_is_constant_evaluated
470 return std::__do_uninit_fill_n(__first, __n, __x);
471#endif
472 return std::uninitialized_fill_n(__first, __n, __x);
473 }
474#endif
475
476 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
477 // __uninitialized_fill_move, __uninitialized_move_fill.
478 // All of these algorithms take a user-supplied allocator, which is used
479 // for construction and destruction.
480
481 // __uninitialized_copy_move
482 // Copies [first1, last1) into [result, result + (last1 - first1)), and
483 // move [first2, last2) into
484 // [result, result + (last1 - first1) + (last2 - first2)).
485 template<typename _InputIterator1, typename _InputIterator2,
486 typename _ForwardIterator, typename _Allocator>
487 inline _ForwardIterator
488 __uninitialized_copy_move(_InputIterator1 __first1,
489 _InputIterator1 __last1,
490 _InputIterator2 __first2,
491 _InputIterator2 __last2,
492 _ForwardIterator __result,
493 _Allocator& __alloc)
494 {
495 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
496 __result,
497 __alloc);
498 __try
499 {
500 return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
501 }
502 __catch(...)
503 {
504 std::_Destroy(__result, __mid, __alloc);
505 __throw_exception_again;
506 }
507 }
508
509 // __uninitialized_move_copy
510 // Moves [first1, last1) into [result, result + (last1 - first1)), and
511 // copies [first2, last2) into
512 // [result, result + (last1 - first1) + (last2 - first2)).
513 template<typename _InputIterator1, typename _InputIterator2,
514 typename _ForwardIterator, typename _Allocator>
515 inline _ForwardIterator
516 __uninitialized_move_copy(_InputIterator1 __first1,
517 _InputIterator1 __last1,
518 _InputIterator2 __first2,
519 _InputIterator2 __last2,
520 _ForwardIterator __result,
521 _Allocator& __alloc)
522 {
523 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
524 __result,
525 __alloc);
526 __try
527 {
528 return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
529 }
530 __catch(...)
531 {
532 std::_Destroy(__result, __mid, __alloc);
533 __throw_exception_again;
534 }
535 }
536
537 // __uninitialized_fill_move
538 // Fills [result, mid) with x, and moves [first, last) into
539 // [mid, mid + (last - first)).
540 template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
541 typename _Allocator>
542 inline _ForwardIterator
543 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
544 const _Tp& __x, _InputIterator __first,
545 _InputIterator __last, _Allocator& __alloc)
546 {
547 std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
548 __try
549 {
550 return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
551 }
552 __catch(...)
553 {
554 std::_Destroy(__result, __mid, __alloc);
555 __throw_exception_again;
556 }
557 }
558
559 // __uninitialized_move_fill
560 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
561 // fills [first2 + (last1 - first1), last2) with x.
562 template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
563 typename _Allocator>
564 inline void
565 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
566 _ForwardIterator __first2,
567 _ForwardIterator __last2, const _Tp& __x,
568 _Allocator& __alloc)
569 {
570 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
571 __first2,
572 __alloc);
573 __try
574 {
575 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
576 }
577 __catch(...)
578 {
579 std::_Destroy(__first2, __mid2, __alloc);
580 __throw_exception_again;
581 }
582 }
583
584 /// @endcond
585
586#if __cplusplus >= 201103L
587 /// @cond undocumented
588
589 // Extensions: __uninitialized_default, __uninitialized_default_n,
590 // __uninitialized_default_a, __uninitialized_default_n_a.
591
592 template<bool _TrivialValueType>
593 struct __uninitialized_default_1
594 {
595 template<typename _ForwardIterator>
596 static void
597 __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
598 {
599 _ForwardIterator __cur = __first;
600 __try
601 {
602 for (; __cur != __last; ++__cur)
604 }
605 __catch(...)
606 {
607 std::_Destroy(__first, __cur);
608 __throw_exception_again;
609 }
610 }
611 };
612
613 template<>
614 struct __uninitialized_default_1<true>
615 {
616 template<typename _ForwardIterator>
617 static void
618 __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
619 {
620 if (__first == __last)
621 return;
622
623 typename iterator_traits<_ForwardIterator>::value_type* __val
624 = std::__addressof(*__first);
625 std::_Construct(__val);
626 if (++__first != __last)
627 std::fill(__first, __last, *__val);
628 }
629 };
630
631 template<bool _TrivialValueType>
632 struct __uninitialized_default_n_1
633 {
634 template<typename _ForwardIterator, typename _Size>
635 _GLIBCXX20_CONSTEXPR
636 static _ForwardIterator
637 __uninit_default_n(_ForwardIterator __first, _Size __n)
638 {
639 _ForwardIterator __cur = __first;
640 __try
641 {
642 for (; __n > 0; --__n, (void) ++__cur)
644 return __cur;
645 }
646 __catch(...)
647 {
648 std::_Destroy(__first, __cur);
649 __throw_exception_again;
650 }
651 }
652 };
653
654 template<>
655 struct __uninitialized_default_n_1<true>
656 {
657 template<typename _ForwardIterator, typename _Size>
658 _GLIBCXX20_CONSTEXPR
659 static _ForwardIterator
660 __uninit_default_n(_ForwardIterator __first, _Size __n)
661 {
662 if (__n > 0)
663 {
664 typename iterator_traits<_ForwardIterator>::value_type* __val
665 = std::__addressof(*__first);
666 std::_Construct(__val);
667 ++__first;
668 __first = std::fill_n(__first, __n - 1, *__val);
669 }
670 return __first;
671 }
672 };
673
674 // __uninitialized_default
675 // Fills [first, last) with value-initialized value_types.
676 template<typename _ForwardIterator>
677 inline void
678 __uninitialized_default(_ForwardIterator __first,
679 _ForwardIterator __last)
680 {
681 typedef typename iterator_traits<_ForwardIterator>::value_type
682 _ValueType;
683 // trivial types can have deleted assignment
684 const bool __assignable = is_copy_assignable<_ValueType>::value;
685
686 std::__uninitialized_default_1<__is_trivial(_ValueType)
687 && __assignable>::
688 __uninit_default(__first, __last);
689 }
690
691 // __uninitialized_default_n
692 // Fills [first, first + n) with value-initialized value_types.
693 template<typename _ForwardIterator, typename _Size>
694 _GLIBCXX20_CONSTEXPR
695 inline _ForwardIterator
696 __uninitialized_default_n(_ForwardIterator __first, _Size __n)
697 {
698#ifdef __cpp_lib_is_constant_evaluated
700 return __uninitialized_default_n_1<false>::
701 __uninit_default_n(__first, __n);
702#endif
703
704 typedef typename iterator_traits<_ForwardIterator>::value_type
705 _ValueType;
706 // See uninitialized_fill_n for the conditions for using std::fill_n.
707 constexpr bool __can_fill
708 = __and_<is_integral<_Size>, is_copy_assignable<_ValueType>>::value;
709
710 return __uninitialized_default_n_1<__is_trivial(_ValueType)
711 && __can_fill>::
712 __uninit_default_n(__first, __n);
713 }
714
715
716 // __uninitialized_default_a
717 // Fills [first, last) with value_types constructed by the allocator
718 // alloc, with no arguments passed to the construct call.
719 template<typename _ForwardIterator, typename _Allocator>
720 void
721 __uninitialized_default_a(_ForwardIterator __first,
722 _ForwardIterator __last,
723 _Allocator& __alloc)
724 {
725 _ForwardIterator __cur = __first;
726 __try
727 {
729 for (; __cur != __last; ++__cur)
730 __traits::construct(__alloc, std::__addressof(*__cur));
731 }
732 __catch(...)
733 {
734 std::_Destroy(__first, __cur, __alloc);
735 __throw_exception_again;
736 }
737 }
738
739#if _GLIBCXX_HOSTED
740 template<typename _ForwardIterator, typename _Tp>
741 inline void
742 __uninitialized_default_a(_ForwardIterator __first,
743 _ForwardIterator __last,
744 allocator<_Tp>&)
745 { std::__uninitialized_default(__first, __last); }
746#endif
747
748 // __uninitialized_default_n_a
749 // Fills [first, first + n) with value_types constructed by the allocator
750 // alloc, with no arguments passed to the construct call.
751 template<typename _ForwardIterator, typename _Size, typename _Allocator>
752 _GLIBCXX20_CONSTEXPR _ForwardIterator
753 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
754 _Allocator& __alloc)
755 {
756 _ForwardIterator __cur = __first;
757 __try
758 {
760 for (; __n > 0; --__n, (void) ++__cur)
761 __traits::construct(__alloc, std::__addressof(*__cur));
762 return __cur;
763 }
764 __catch(...)
765 {
766 std::_Destroy(__first, __cur, __alloc);
767 __throw_exception_again;
768 }
769 }
770
771#if _GLIBCXX_HOSTED
772 // __uninitialized_default_n_a specialization for std::allocator,
773 // which ignores the allocator and value-initializes the elements.
774 template<typename _ForwardIterator, typename _Size, typename _Tp>
775 _GLIBCXX20_CONSTEXPR
776 inline _ForwardIterator
777 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
778 allocator<_Tp>&)
779 { return std::__uninitialized_default_n(__first, __n); }
780#endif
781
782 template<bool _TrivialValueType>
783 struct __uninitialized_default_novalue_1
784 {
785 template<typename _ForwardIterator>
786 static void
787 __uninit_default_novalue(_ForwardIterator __first,
788 _ForwardIterator __last)
789 {
790 _ForwardIterator __cur = __first;
791 __try
792 {
793 for (; __cur != __last; ++__cur)
794 std::_Construct_novalue(std::__addressof(*__cur));
795 }
796 __catch(...)
797 {
798 std::_Destroy(__first, __cur);
799 __throw_exception_again;
800 }
801 }
802 };
803
804 template<>
805 struct __uninitialized_default_novalue_1<true>
806 {
807 template<typename _ForwardIterator>
808 static void
809 __uninit_default_novalue(_ForwardIterator __first,
810 _ForwardIterator __last)
811 {
812 }
813 };
814
815 template<bool _TrivialValueType>
816 struct __uninitialized_default_novalue_n_1
817 {
818 template<typename _ForwardIterator, typename _Size>
819 static _ForwardIterator
820 __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
821 {
822 _ForwardIterator __cur = __first;
823 __try
824 {
825 for (; __n > 0; --__n, (void) ++__cur)
826 std::_Construct_novalue(std::__addressof(*__cur));
827 return __cur;
828 }
829 __catch(...)
830 {
831 std::_Destroy(__first, __cur);
832 __throw_exception_again;
833 }
834 }
835 };
836
837 template<>
838 struct __uninitialized_default_novalue_n_1<true>
839 {
840 template<typename _ForwardIterator, typename _Size>
841 static _ForwardIterator
842 __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
843 { return std::next(__first, __n); }
844 };
845
846 // __uninitialized_default_novalue
847 // Fills [first, last) with default-initialized value_types.
848 template<typename _ForwardIterator>
849 inline void
850 __uninitialized_default_novalue(_ForwardIterator __first,
851 _ForwardIterator __last)
852 {
853 typedef typename iterator_traits<_ForwardIterator>::value_type
854 _ValueType;
855
856 std::__uninitialized_default_novalue_1<
857 is_trivially_default_constructible<_ValueType>::value>::
858 __uninit_default_novalue(__first, __last);
859 }
860
861 // __uninitialized_default_novalue_n
862 // Fills [first, first + n) with default-initialized value_types.
863 template<typename _ForwardIterator, typename _Size>
864 inline _ForwardIterator
865 __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
866 {
867 typedef typename iterator_traits<_ForwardIterator>::value_type
868 _ValueType;
869
870 return __uninitialized_default_novalue_n_1<
871 is_trivially_default_constructible<_ValueType>::value>::
872 __uninit_default_novalue_n(__first, __n);
873 }
874
875 template<typename _InputIterator, typename _Size,
876 typename _ForwardIterator>
877 _ForwardIterator
878 __uninitialized_copy_n(_InputIterator __first, _Size __n,
879 _ForwardIterator __result, input_iterator_tag)
880 {
881 _ForwardIterator __cur = __result;
882 __try
883 {
884 for (; __n > 0; --__n, (void) ++__first, ++__cur)
885 std::_Construct(std::__addressof(*__cur), *__first);
886 return __cur;
887 }
888 __catch(...)
889 {
890 std::_Destroy(__result, __cur);
891 __throw_exception_again;
892 }
893 }
894
895 template<typename _RandomAccessIterator, typename _Size,
896 typename _ForwardIterator>
897 inline _ForwardIterator
898 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
899 _ForwardIterator __result,
900 random_access_iterator_tag)
901 { return std::uninitialized_copy(__first, __first + __n, __result); }
902
903 template<typename _InputIterator, typename _Size,
904 typename _ForwardIterator>
905 pair<_InputIterator, _ForwardIterator>
906 __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
907 _ForwardIterator __result, input_iterator_tag)
908 {
909 _ForwardIterator __cur = __result;
910 __try
911 {
912 for (; __n > 0; --__n, (void) ++__first, ++__cur)
913 std::_Construct(std::__addressof(*__cur), *__first);
914 return {__first, __cur};
915 }
916 __catch(...)
917 {
918 std::_Destroy(__result, __cur);
919 __throw_exception_again;
920 }
921 }
922
923 template<typename _RandomAccessIterator, typename _Size,
924 typename _ForwardIterator>
925 inline pair<_RandomAccessIterator, _ForwardIterator>
926 __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
927 _ForwardIterator __result,
928 random_access_iterator_tag)
929 {
930 auto __second_res = uninitialized_copy(__first, __first + __n, __result);
931 auto __first_res = std::next(__first, __n);
932 return {__first_res, __second_res};
933 }
934
935 /// @endcond
936
937 /**
938 * @brief Copies the range [first,first+n) into result.
939 * @param __first An input iterator.
940 * @param __n The number of elements to copy.
941 * @param __result An output iterator.
942 * @return __result + __n
943 * @since C++11
944 *
945 * Like copy_n(), but does not require an initialized output range.
946 */
947 template<typename _InputIterator, typename _Size, typename _ForwardIterator>
948 inline _ForwardIterator
949 uninitialized_copy_n(_InputIterator __first, _Size __n,
950 _ForwardIterator __result)
951 { return std::__uninitialized_copy_n(__first, __n, __result,
952 std::__iterator_category(__first)); }
953
954 /// @cond undocumented
955 template<typename _InputIterator, typename _Size, typename _ForwardIterator>
956 inline pair<_InputIterator, _ForwardIterator>
957 __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
958 _ForwardIterator __result)
959 {
960 return
961 std::__uninitialized_copy_n_pair(__first, __n, __result,
962 std::__iterator_category(__first));
963 }
964 /// @endcond
965#endif
966
967#if __cplusplus >= 201703L
968# define __cpp_lib_raw_memory_algorithms 201606L
969
970 /**
971 * @brief Default-initializes objects in the range [first,last).
972 * @param __first A forward iterator.
973 * @param __last A forward iterator.
974 * @since C++17
975 */
976 template <typename _ForwardIterator>
977 inline void
978 uninitialized_default_construct(_ForwardIterator __first,
979 _ForwardIterator __last)
980 {
981 __uninitialized_default_novalue(__first, __last);
982 }
983
984 /**
985 * @brief Default-initializes objects in the range [first,first+count).
986 * @param __first A forward iterator.
987 * @param __count The number of objects to construct.
988 * @return __first + __count
989 * @since C++17
990 */
991 template <typename _ForwardIterator, typename _Size>
992 inline _ForwardIterator
993 uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
994 {
995 return __uninitialized_default_novalue_n(__first, __count);
996 }
997
998 /**
999 * @brief Value-initializes objects in the range [first,last).
1000 * @param __first A forward iterator.
1001 * @param __last A forward iterator.
1002 * @since C++17
1003 */
1004 template <typename _ForwardIterator>
1005 inline void
1006 uninitialized_value_construct(_ForwardIterator __first,
1007 _ForwardIterator __last)
1008 {
1009 return __uninitialized_default(__first, __last);
1010 }
1011
1012 /**
1013 * @brief Value-initializes objects in the range [first,first+count).
1014 * @param __first A forward iterator.
1015 * @param __count The number of objects to construct.
1016 * @return __result + __count
1017 * @since C++17
1018 */
1019 template <typename _ForwardIterator, typename _Size>
1020 inline _ForwardIterator
1021 uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
1022 {
1023 return __uninitialized_default_n(__first, __count);
1024 }
1025
1026 /**
1027 * @brief Move-construct from the range [first,last) into result.
1028 * @param __first An input iterator.
1029 * @param __last An input iterator.
1030 * @param __result An output iterator.
1031 * @return __result + (__first - __last)
1032 * @since C++17
1033 */
1034 template <typename _InputIterator, typename _ForwardIterator>
1035 inline _ForwardIterator
1036 uninitialized_move(_InputIterator __first, _InputIterator __last,
1037 _ForwardIterator __result)
1038 {
1040 (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
1041 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
1042 }
1043
1044 /**
1045 * @brief Move-construct from the range [first,first+count) into result.
1046 * @param __first An input iterator.
1047 * @param __count The number of objects to initialize.
1048 * @param __result An output iterator.
1049 * @return __result + __count
1050 * @since C++17
1051 */
1052 template <typename _InputIterator, typename _Size, typename _ForwardIterator>
1053 inline pair<_InputIterator, _ForwardIterator>
1054 uninitialized_move_n(_InputIterator __first, _Size __count,
1055 _ForwardIterator __result)
1056 {
1057 auto __res = std::__uninitialized_copy_n_pair
1058 (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
1059 __count, __result);
1060 return {__res.first.base(), __res.second};
1061 }
1062#endif // C++17
1063
1064#if __cplusplus >= 201103L
1065 /// @cond undocumented
1066
1067 template<typename _Tp, typename _Up, typename _Allocator>
1068 _GLIBCXX20_CONSTEXPR
1069 inline void
1070 __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig,
1071 _Allocator& __alloc)
1072 noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc,
1073 __dest, std::move(*__orig)))
1075 __alloc, std::__addressof(*__orig))))
1076 {
1077 typedef std::allocator_traits<_Allocator> __traits;
1078 __traits::construct(__alloc, __dest, std::move(*__orig));
1079 __traits::destroy(__alloc, std::__addressof(*__orig));
1080 }
1081
1082 // This class may be specialized for specific types.
1083 // Also known as is_trivially_relocatable.
1084 template<typename _Tp, typename = void>
1085 struct __is_bitwise_relocatable
1086 : is_trivial<_Tp> { };
1087
1088 template <typename _InputIterator, typename _ForwardIterator,
1089 typename _Allocator>
1090 _GLIBCXX20_CONSTEXPR
1091 inline _ForwardIterator
1092 __relocate_a_1(_InputIterator __first, _InputIterator __last,
1093 _ForwardIterator __result, _Allocator& __alloc)
1094 noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result),
1095 std::addressof(*__first),
1096 __alloc)))
1097 {
1098 typedef typename iterator_traits<_InputIterator>::value_type
1099 _ValueType;
1100 typedef typename iterator_traits<_ForwardIterator>::value_type
1101 _ValueType2;
1103 "relocation is only possible for values of the same type");
1104 _ForwardIterator __cur = __result;
1105 for (; __first != __last; ++__first, (void)++__cur)
1106 std::__relocate_object_a(std::__addressof(*__cur),
1107 std::__addressof(*__first), __alloc);
1108 return __cur;
1109 }
1110
1111#if _GLIBCXX_HOSTED
1112 template <typename _Tp, typename _Up>
1113 _GLIBCXX20_CONSTEXPR
1114 inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*>
1115 __relocate_a_1(_Tp* __first, _Tp* __last,
1116 _Tp* __result,
1117 [[__maybe_unused__]] allocator<_Up>& __alloc) noexcept
1118 {
1119 ptrdiff_t __count = __last - __first;
1120 if (__count > 0)
1121 {
1122#ifdef __cpp_lib_is_constant_evaluated
1124 {
1125 // Can't use memmove. Wrap the pointer so that __relocate_a_1
1126 // resolves to the non-trivial overload above.
1127 __gnu_cxx::__normal_iterator<_Tp*, void> __out(__result);
1128 __out = std::__relocate_a_1(__first, __last, __out, __alloc);
1129 return __out.base();
1130 }
1131#endif
1132 __builtin_memmove(__result, __first, __count * sizeof(_Tp));
1133 }
1134 return __result + __count;
1135 }
1136#endif
1137
1138 template <typename _InputIterator, typename _ForwardIterator,
1139 typename _Allocator>
1140 _GLIBCXX20_CONSTEXPR
1141 inline _ForwardIterator
1142 __relocate_a(_InputIterator __first, _InputIterator __last,
1143 _ForwardIterator __result, _Allocator& __alloc)
1144 noexcept(noexcept(__relocate_a_1(std::__niter_base(__first),
1145 std::__niter_base(__last),
1146 std::__niter_base(__result), __alloc)))
1147 {
1148 return std::__relocate_a_1(std::__niter_base(__first),
1149 std::__niter_base(__last),
1150 std::__niter_base(__result), __alloc);
1151 }
1152
1153 /// @endcond
1154#endif // C++11
1155
1156 /// @} group memory
1157
1158_GLIBCXX_END_NAMESPACE_VERSION
1159} // namespace
1160
1161#endif /* _STL_UNINITIALIZED_H */
_ForwardIterator uninitialized_copy_n(_InputIterator __first, _Size __n, _ForwardIterator __result)
Copies the range [first,first+n) into result.
void uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp &__x)
Copies the value x into the range [first,last).
_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
Value-initializes objects in the range [first,first+count).
_ForwardIterator uninitialized_move(_InputIterator __first, _InputIterator __last, _ForwardIterator __result)
Move-construct from the range [first,last) into result.
_ForwardIterator uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp &__x)
Copies the value x into the range [first,first+n).
_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
Default-initializes objects in the range [first,first+count).
void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last)
Default-initializes objects in the range [first,last).
_ForwardIterator uninitialized_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result)
Copies the range [first,last) into result.
void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last)
Value-initializes objects in the range [first,last).
pair< _InputIterator, _ForwardIterator > uninitialized_move_n(_InputIterator __first, _Size __count, _ForwardIterator __result)
Move-construct from the range [first,first+count) into result.
constexpr bool is_constant_evaluated() noexcept
Returns true only when called during constant evaluation.
Definition type_traits:3644
constexpr _Tp * addressof(_Tp &__r) noexcept
Returns the actual address of the object or function referenced by r, even in the presence of an over...
Definition move.h:138
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:97
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition move.h:51
constexpr iterator_traits< _Iter >::iterator_category __iterator_category(const _Iter &)
ISO C++ entities toplevel namespace is std.
constexpr void _Construct(_Tp *__p, _Args &&... __args)
constexpr void _Destroy(_ForwardIterator __first, _ForwardIterator __last)
Uniform interface to all allocator types.
static constexpr auto construct(_Alloc &__a, _Tp *__p, _Args &&... __args) noexcept(noexcept(_S_construct(__a, __p, std::forward< _Args >(__args)...))) -> decltype(_S_construct(__a, __p, std::forward< _Args >(__args)...))
Construct an object of type _Tp
Traits class for iterators.
Uniform interface to C++98 and C++11 allocators.