libstdc++
stl_uninitialized.h
Go to the documentation of this file.
1// Raw memory manipulators -*- C++ -*-
2
3// Copyright (C) 2001-2025 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# include <bits/ptr_traits.h> // to_address
62# include <bits/stl_pair.h> // pair
63# include <bits/stl_algobase.h> // fill, fill_n
64#endif
65
66#include <bits/cpp_type_traits.h> // __is_pointer
67#include <bits/stl_iterator_base_funcs.h> // distance, advance
68#include <bits/stl_iterator.h> // __niter_base
69#include <ext/alloc_traits.h> // __alloc_traits
70
71namespace std _GLIBCXX_VISIBILITY(default)
72{
73_GLIBCXX_BEGIN_NAMESPACE_VERSION
74
75 /** @addtogroup memory
76 * @{
77 */
78
79 /// @cond undocumented
80
81 template<typename _ForwardIterator, typename _Alloc = void>
82 struct _UninitDestroyGuard
83 {
84 _GLIBCXX20_CONSTEXPR
85 explicit
86 _UninitDestroyGuard(_ForwardIterator& __first, _Alloc& __a)
87 : _M_first(__first), _M_cur(__builtin_addressof(__first)), _M_alloc(__a)
88 { }
89
90 _GLIBCXX20_CONSTEXPR
91 ~_UninitDestroyGuard()
92 {
93 if (__builtin_expect(_M_cur != 0, 0))
94 std::_Destroy(_M_first, *_M_cur, _M_alloc);
95 }
96
97 _GLIBCXX20_CONSTEXPR
98 void release() { _M_cur = 0; }
99
100 private:
101 _ForwardIterator const _M_first;
102 _ForwardIterator* _M_cur;
103 _Alloc& _M_alloc;
104
105 _UninitDestroyGuard(const _UninitDestroyGuard&);
106 };
107
108 template<typename _ForwardIterator>
109 struct _UninitDestroyGuard<_ForwardIterator, void>
110 {
111 _GLIBCXX20_CONSTEXPR
112 explicit
113 _UninitDestroyGuard(_ForwardIterator& __first)
114 : _M_first(__first), _M_cur(__builtin_addressof(__first))
115 { }
116
117 _GLIBCXX20_CONSTEXPR
118 ~_UninitDestroyGuard()
119 {
120 if (__builtin_expect(_M_cur != 0, 0))
121#if __cplusplus == 201703L
122 // std::uninitialized_{value,default}{,_n} can construct array types,
123 // but std::_Destroy cannot handle them until C++20 (PR 120397).
124 _S_destroy(_M_first, *_M_cur);
125#else
126 std::_Destroy(_M_first, *_M_cur);
127#endif
128 }
129
130 _GLIBCXX20_CONSTEXPR
131 void release() { _M_cur = 0; }
132
133 _ForwardIterator const _M_first;
134 _ForwardIterator* _M_cur;
135
136 private:
137 _UninitDestroyGuard(const _UninitDestroyGuard&);
138
139#if __cplusplus == 201703L
140 template<typename _Iter>
141 static void
142 _S_destroy(_Iter __first, _Iter __last)
143 {
144 using _ValT = typename iterator_traits<_Iter>::value_type;
145 if constexpr (is_array<_ValT>::value)
146 for (; __first != __last; ++__first)
147 _S_destroy(*__first, *__first + extent<_ValT>::value);
148 else
149 std::_Destroy(__first, __last);
150 }
151#endif
152 };
153
154 // This is the default implementation of std::uninitialized_copy.
155 // This can be used with C++20 iterators and non-common ranges.
156 template<typename _InputIterator, typename _Sentinel,
157 typename _ForwardIterator>
158 _GLIBCXX20_CONSTEXPR
159 _ForwardIterator
160 __do_uninit_copy(_InputIterator __first, _Sentinel __last,
161 _ForwardIterator __result)
162 {
163 _UninitDestroyGuard<_ForwardIterator> __guard(__result);
164 for (; __first != __last; ++__first, (void)++__result)
165 std::_Construct(std::__addressof(*__result), *__first);
166 __guard.release();
167 return __result;
168 }
169
170#if __cplusplus < 201103L
171
172 // True if we can unwrap _Iter to get a pointer by using std::__niter_base.
173 template<typename _Iter,
174 typename _Base = __decltype(std::__niter_base(*(_Iter*)0))>
175 struct __unwrappable_niter
176 { enum { __value = false }; };
177
178 template<typename _Iter, typename _Tp>
179 struct __unwrappable_niter<_Iter, _Tp*>
180 { enum { __value = true }; };
181
182 // Use template specialization for C++98 when 'if constexpr' can't be used.
183 template<bool _CanMemcpy>
184 struct __uninitialized_copy
185 {
186 template<typename _InputIterator, typename _ForwardIterator>
187 static _ForwardIterator
188 __uninit_copy(_InputIterator __first, _InputIterator __last,
189 _ForwardIterator __result)
190 { return std::__do_uninit_copy(__first, __last, __result); }
191 };
192
193 template<>
194 struct __uninitialized_copy<true>
195 {
196 // Overload for generic iterators.
197 template<typename _InputIterator, typename _ForwardIterator>
198 static _ForwardIterator
199 __uninit_copy(_InputIterator __first, _InputIterator __last,
200 _ForwardIterator __result)
201 {
202 if (__unwrappable_niter<_InputIterator>::__value
203 && __unwrappable_niter<_ForwardIterator>::__value)
204 {
205 __uninit_copy(std::__niter_base(__first),
206 std::__niter_base(__last),
207 std::__niter_base(__result));
208 std::advance(__result, std::distance(__first, __last));
209 return __result;
210 }
211 else
212 return std::__do_uninit_copy(__first, __last, __result);
213 }
214
215 // Overload for pointers.
216 template<typename _Tp, typename _Up>
217 static _Up*
218 __uninit_copy(_Tp* __first, _Tp* __last, _Up* __result)
219 {
220 // Ensure that we don't successfully memcpy in cases that should be
221 // ill-formed because is_constructible<_Up, _Tp&> is false.
222 typedef __typeof__(static_cast<_Up>(*__first)) __check
223 __attribute__((__unused__));
224
225 const ptrdiff_t __n = __last - __first;
226 if (__builtin_expect(__n > 0, true))
227 {
228 __builtin_memcpy(__result, __first, __n * sizeof(_Tp));
229 __result += __n;
230 }
231 return __result;
232 }
233 };
234#endif
235 /// @endcond
236
237#pragma GCC diagnostic push
238#pragma GCC diagnostic ignored "-Wc++17-extensions"
239 /**
240 * @brief Copies the range [first,last) into result.
241 * @param __first An input iterator.
242 * @param __last An input iterator.
243 * @param __result A forward iterator.
244 * @return __result + (__last - __first)
245 *
246 * Like std::copy, but does not require an initialized output range.
247 */
248 template<typename _InputIterator, typename _ForwardIterator>
249 _GLIBCXX26_CONSTEXPR
250 inline _ForwardIterator
251 uninitialized_copy(_InputIterator __first, _InputIterator __last,
252 _ForwardIterator __result)
253 {
254 // We can use memcpy to copy the ranges under these conditions:
255 //
256 // _ForwardIterator and _InputIterator are both contiguous iterators,
257 // so that we can turn them into pointers to pass to memcpy.
258 // Before C++20 we can't detect all contiguous iterators, so we only
259 // handle built-in pointers and __normal_iterator<T*, C> types.
260 //
261 // The value types of both iterators are trivially-copyable types,
262 // so that memcpy is not undefined and can begin the lifetime of
263 // new objects in the output range.
264 //
265 // Finally, memcpy from the source type, S, to the destination type, D,
266 // must give the same value as initialization of D from S would give.
267 // We require is_trivially_constructible<D, S> to be true, but that is
268 // not sufficient. Some cases of trivial initialization are not just a
269 // bitwise copy, even when sizeof(D) == sizeof(S),
270 // e.g. bit_cast<unsigned>(1.0f) != 1u because the corresponding bits
271 // of the value representations do not have the same meaning.
272 // We cannot tell when this condition is true in general,
273 // so we rely on the __memcpyable trait.
274
275#if __cplusplus >= 201103L
276 using _Dest = decltype(std::__niter_base(__result));
277 using _Src = decltype(std::__niter_base(__first));
279
280#if __glibcxx_raw_memory_algorithms >= 202411L // >= C++26
281 if consteval {
282 return std::__do_uninit_copy(__first, __last, __result);
283 }
284#endif
285 if constexpr (!__is_trivially_constructible(_ValT, decltype(*__first)))
286 return std::__do_uninit_copy(__first, __last, __result);
287 else if constexpr (__memcpyable<_Dest, _Src>::__value)
288 {
289 ptrdiff_t __n = __last - __first;
290 if (__n > 0) [[__likely__]]
291 {
292 using _ValT = typename remove_pointer<_Src>::type;
293 __builtin_memcpy(std::__niter_base(__result),
294 std::__niter_base(__first),
295 __n * sizeof(_ValT));
296 __result += __n;
297 }
298 return __result;
299 }
300#if __cpp_lib_concepts
301 else if constexpr (contiguous_iterator<_ForwardIterator>
302 && contiguous_iterator<_InputIterator>)
303 {
304 using _DestPtr = decltype(std::to_address(__result));
305 using _SrcPtr = decltype(std::to_address(__first));
306 if constexpr (__memcpyable<_DestPtr, _SrcPtr>::__value)
307 {
308 if (auto __n = __last - __first; __n > 0) [[likely]]
309 {
310 void* __dest = std::to_address(__result);
311 const void* __src = std::to_address(__first);
312 size_t __nbytes = __n * sizeof(remove_pointer_t<_DestPtr>);
313 __builtin_memcpy(__dest, __src, __nbytes);
314 __result += __n;
315 }
316 return __result;
317 }
318 else
319 return std::__do_uninit_copy(__first, __last, __result);
320 }
321#endif
322 else
323 return std::__do_uninit_copy(__first, __last, __result);
324#else // C++98
326 _ValueType1;
328 _ValueType2;
329
330 const bool __can_memcpy
331 = __memcpyable<_ValueType1*, _ValueType2*>::__value
332 && __is_trivially_constructible(_ValueType2, __decltype(*__first));
333
334 return __uninitialized_copy<__can_memcpy>::
335 __uninit_copy(__first, __last, __result);
336#endif
337 }
338#pragma GCC diagnostic pop
339
340 /// @cond undocumented
341
342 // This is the default implementation of std::uninitialized_fill.
343 template<typename _ForwardIterator, typename _Tp>
344 _GLIBCXX20_CONSTEXPR void
345 __do_uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
346 const _Tp& __x)
347 {
348 _UninitDestroyGuard<_ForwardIterator> __guard(__first);
349 for (; __first != __last; ++__first)
350 std::_Construct(std::__addressof(*__first), __x);
351 __guard.release();
352 }
353
354#if __cplusplus < 201103L
355 // Use template specialization for C++98 when 'if constexpr' can't be used.
356 template<bool _CanMemset>
357 struct __uninitialized_fill
358 {
359 template<typename _ForwardIterator, typename _Tp>
360 static void
361 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
362 const _Tp& __x)
363 { std::__do_uninit_fill(__first, __last, __x); }
364 };
365
366 template<>
367 struct __uninitialized_fill<true>
368 {
369 // Overload for generic iterators.
370 template<typename _ForwardIterator, typename _Tp>
371 static void
372 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
373 const _Tp& __x)
374 {
375 if (__unwrappable_niter<_ForwardIterator>::__value)
376 __uninit_fill(std::__niter_base(__first),
377 std::__niter_base(__last),
378 __x);
379 else
380 std::__do_uninit_fill(__first, __last, __x);
381 }
382
383 // Overload for pointers.
384 template<typename _Up, typename _Tp>
385 static void
386 __uninit_fill(_Up* __first, _Up* __last, const _Tp& __x)
387 {
388 // Ensure that we don't successfully memset in cases that should be
389 // ill-formed because is_constructible<_Up, const _Tp&> is false.
390 typedef __typeof__(static_cast<_Up>(__x)) __check
391 __attribute__((__unused__));
392
393 if (__first != __last)
394 __builtin_memset(__first, (unsigned char)__x, __last - __first);
395 }
396 };
397#endif
398 /// @endcond
399
400 /**
401 * @brief Copies the value x into the range [first,last).
402 * @param __first A forward iterator.
403 * @param __last A forward iterator.
404 * @param __x The source value.
405 * @return Nothing.
406 *
407 * Like std::fill, but does not require an initialized output range.
408 */
409 template<typename _ForwardIterator, typename _Tp>
410 _GLIBCXX26_CONSTEXPR
411 inline void
412 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
413 const _Tp& __x)
414 {
415 // We would like to use memset to optimize this loop when possible.
416 // As for std::uninitialized_copy, the optimization requires
417 // contiguous iterators and trivially copyable value types,
418 // with the additional requirement that sizeof(_Tp) == 1 because
419 // memset only writes single bytes.
420
421 // FIXME: We could additionally enable this for 1-byte enums.
422 // Maybe any 1-byte Val if is_trivially_constructible<Val, const T&>?
423
425 _ValueType;
426
427#if __cplusplus >= 201103L
428#pragma GCC diagnostic push
429#pragma GCC diagnostic ignored "-Wc++17-extensions"
430#if __glibcxx_raw_memory_algorithms >= 202411L // >= C++26
431 if consteval {
432 return std::__do_uninit_fill(__first, __last, __x);
433 }
434#endif
435 if constexpr (__is_byte<_ValueType>::__value)
438 {
439 using _BasePtr = decltype(std::__niter_base(__first));
440 if constexpr (is_pointer<_BasePtr>::value)
441 {
442 void* __dest = std::__niter_base(__first);
443 ptrdiff_t __n = __last - __first;
444 if (__n > 0) [[__likely__]]
445 __builtin_memset(__dest, (unsigned char)__x, __n);
446 return;
447 }
448#if __cpp_lib_concepts
449 else if constexpr (contiguous_iterator<_ForwardIterator>)
450 {
451 auto __dest = std::to_address(__first);
452 auto __n = __last - __first;
453 if (__n > 0) [[__likely__]]
454 __builtin_memset(__dest, (unsigned char)__x, __n);
455 return;
456 }
457#endif
458 }
459 std::__do_uninit_fill(__first, __last, __x);
460#pragma GCC diagnostic pop
461#else // C++98
462 const bool __can_memset = __is_byte<_ValueType>::__value
463 && __is_integer<_Tp>::__value;
464
465 __uninitialized_fill<__can_memset>::__uninit_fill(__first, __last, __x);
466#endif
467 }
468
469 /// @cond undocumented
470
471 // This is the default implementation of std::uninitialized_fill_n.
472 template<typename _ForwardIterator, typename _Size, typename _Tp>
473 _GLIBCXX20_CONSTEXPR
474 _ForwardIterator
475 __do_uninit_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
476 {
477 _UninitDestroyGuard<_ForwardIterator> __guard(__first);
478#if __cplusplus >= 201103L
479#pragma GCC diagnostic push
480#pragma GCC diagnostic ignored "-Wc++17-extensions"
481 if constexpr (is_integral<_Size>::value)
482 // Loop will never terminate if __n is negative.
483 __glibcxx_assert(__n >= 0);
484 else if constexpr (is_floating_point<_Size>::value)
485 // Loop will never terminate if __n is not an integer.
486 __glibcxx_assert(__n >= 0 && static_cast<size_t>(__n) == __n);
487#pragma GCC diagnostic pop
488#endif
489 for (; __n--; ++__first)
490 std::_Construct(std::__addressof(*__first), __x);
491 __guard.release();
492 return __first;
493 }
494
495#if __cplusplus < 201103L
496 // Use template specialization for C++98 when 'if constexpr' can't be used.
497 template<bool _CanMemset>
498 struct __uninitialized_fill_n
499 {
500 template<typename _ForwardIterator, typename _Size, typename _Tp>
501 static _ForwardIterator
502 __uninit_fill_n(_ForwardIterator __first, _Size __n,
503 const _Tp& __x)
504 { return std::__do_uninit_fill_n(__first, __n, __x); }
505 };
506
507 template<>
508 struct __uninitialized_fill_n<true>
509 {
510 // Overload for generic iterators.
511 template<typename _ForwardIterator, typename _Size, typename _Tp>
512 static _ForwardIterator
513 __uninit_fill_n(_ForwardIterator __first, _Size __n,
514 const _Tp& __x)
515 {
516 if (__unwrappable_niter<_ForwardIterator>::__value)
517 {
518 _ForwardIterator __last = __first;
519 std::advance(__last, __n);
520 __uninitialized_fill<true>::__uninit_fill(__first, __last, __x);
521 return __last;
522 }
523 else
524 return std::__do_uninit_fill_n(__first, __n, __x);
525 }
526 };
527#endif
528 /// @endcond
529
530#pragma GCC diagnostic push
531#pragma GCC diagnostic ignored "-Wc++17-extensions"
532 // _GLIBCXX_RESOLVE_LIB_DEFECTS
533 // DR 1339. uninitialized_fill_n should return the end of its range
534 /**
535 * @brief Copies the value x into the range [first,first+n).
536 * @param __first A forward iterator.
537 * @param __n The number of copies to make.
538 * @param __x The source value.
539 * @return __first + __n.
540 *
541 * Like std::fill_n, but does not require an initialized output range.
542 */
543 template<typename _ForwardIterator, typename _Size, typename _Tp>
544 _GLIBCXX26_CONSTEXPR
545 inline _ForwardIterator
546 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
547 {
548 // See uninitialized_fill conditions. We also require _Size to be
549 // an integer. The standard only requires _Size to be decrementable
550 // and contextually convertible to bool, so don't assume first+n works.
551
552 // FIXME: We could additionally enable this for 1-byte enums.
553
555 _ValueType;
556
557#if __cplusplus >= 201103L
558#if __glibcxx_raw_memory_algorithms >= 202411L // >= C++26
559 if consteval {
560 return std::__do_uninit_fill_n(__first, __n, __x);
561 }
562#endif
563 if constexpr (__is_byte<_ValueType>::__value)
564 if constexpr (is_integral<_Tp>::value)
565 if constexpr (is_integral<_Size>::value)
566 {
567 using _BasePtr = decltype(std::__niter_base(__first));
568 if constexpr (is_pointer<_BasePtr>::value)
569 {
570 void* __dest = std::__niter_base(__first);
571 if (__n > 0) [[__likely__]]
572 {
573 __builtin_memset(__dest, (unsigned char)__x, __n);
574 __first += __n;
575 }
576 return __first;
577 }
578#if __cpp_lib_concepts
579 else if constexpr (contiguous_iterator<_ForwardIterator>)
580 {
581 auto __dest = std::to_address(__first);
582 if (__n > 0) [[__likely__]]
583 {
584 __builtin_memset(__dest, (unsigned char)__x, __n);
585 __first += __n;
586 }
587 return __first;
588 }
589#endif
590 }
591 return std::__do_uninit_fill_n(__first, __n, __x);
592#else // C++98
593 const bool __can_memset = __is_byte<_ValueType>::__value
594 && __is_integer<_Tp>::__value
595 && __is_integer<_Size>::__value;
596
597 return __uninitialized_fill_n<__can_memset>::
598 __uninit_fill_n(__first, __n, __x);
599#endif
600 }
601#pragma GCC diagnostic pop
602
603 /// @cond undocumented
604
605 // Extensions: versions of uninitialized_copy, uninitialized_fill,
606 // and uninitialized_fill_n that take an allocator parameter.
607 // We dispatch back to the standard versions when we're given the
608 // default allocator. For nondefault allocators we do not use
609 // any of the POD optimizations.
610
611 template<typename _InputIterator, typename _Sentinel,
612 typename _ForwardIterator, typename _Allocator>
613 _GLIBCXX20_CONSTEXPR
614 _ForwardIterator
615 __uninitialized_copy_a(_InputIterator __first, _Sentinel __last,
616 _ForwardIterator __result, _Allocator& __alloc)
617 {
618 _UninitDestroyGuard<_ForwardIterator, _Allocator>
619 __guard(__result, __alloc);
620
622 for (; __first != __last; ++__first, (void)++__result)
623 __traits::construct(__alloc, std::__addressof(*__result), *__first);
624 __guard.release();
625 return __result;
626 }
627
628#if _GLIBCXX_HOSTED
629 template<typename _InputIterator, typename _Sentinel,
630 typename _ForwardIterator, typename _Tp>
631 _GLIBCXX20_CONSTEXPR
632 inline _ForwardIterator
633 __uninitialized_copy_a(_InputIterator __first, _Sentinel __last,
634 _ForwardIterator __result, allocator<_Tp>&)
635 {
636#ifdef __cpp_lib_is_constant_evaluated
637 if (std::is_constant_evaluated())
638 return std::__do_uninit_copy(std::move(__first), __last, __result);
639#endif
640
641#ifdef __glibcxx_ranges
642 if constexpr (!is_same_v<_InputIterator, _Sentinel>)
643 {
644 // Convert to a common range if possible, to benefit from memcpy
645 // optimizations that std::uninitialized_copy might use.
646 if constexpr (sized_sentinel_for<_Sentinel, _InputIterator>
647 && random_access_iterator<_InputIterator>)
648 return std::uninitialized_copy(__first,
649 __first + (__last - __first),
650 __result);
651 else // Just use default implementation.
652 return std::__do_uninit_copy(std::move(__first), __last, __result);
653 }
654 else
655 return std::uninitialized_copy(std::move(__first), __last, __result);
656#else
657 return std::uninitialized_copy(__first, __last, __result);
658#endif
659 }
660#endif
661
662 template<typename _InputIterator, typename _ForwardIterator,
663 typename _Allocator>
664 _GLIBCXX20_CONSTEXPR
665 inline _ForwardIterator
666 __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
667 _ForwardIterator __result, _Allocator& __alloc)
668 {
669 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
670 _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
671 __result, __alloc);
672 }
673
674 template<typename _InputIterator, typename _ForwardIterator,
675 typename _Allocator>
676 _GLIBCXX20_CONSTEXPR
677 inline _ForwardIterator
678 __uninitialized_move_if_noexcept_a(_InputIterator __first,
679 _InputIterator __last,
680 _ForwardIterator __result,
681 _Allocator& __alloc)
682 {
683 return std::__uninitialized_copy_a
684 (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
685 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
686 }
687
688 template<typename _ForwardIterator, typename _Tp, typename _Allocator>
689 _GLIBCXX20_CONSTEXPR
690 void
691 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
692 const _Tp& __x, _Allocator& __alloc)
693 {
694 _UninitDestroyGuard<_ForwardIterator, _Allocator>
695 __guard(__first, __alloc);
696
697 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
698 for (; __first != __last; ++__first)
699 __traits::construct(__alloc, std::__addressof(*__first), __x);
700
701 __guard.release();
702 }
703
704#if _GLIBCXX_HOSTED
705 template<typename _ForwardIterator, typename _Tp, typename _Tp2>
706 _GLIBCXX20_CONSTEXPR
707 inline void
708 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
709 const _Tp& __x, allocator<_Tp2>&)
710 {
711#ifdef __cpp_lib_is_constant_evaluated
712 if (std::is_constant_evaluated())
713 return std::__do_uninit_fill(__first, __last, __x);
714#endif
715 std::uninitialized_fill(__first, __last, __x);
716 }
717#endif
718
719 template<typename _ForwardIterator, typename _Size, typename _Tp,
720 typename _Allocator>
721 _GLIBCXX20_CONSTEXPR
722 _ForwardIterator
723 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
724 const _Tp& __x, _Allocator& __alloc)
725 {
726 _UninitDestroyGuard<_ForwardIterator, _Allocator>
727 __guard(__first, __alloc);
728 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
729 for (; __n > 0; --__n, (void) ++__first)
730 __traits::construct(__alloc, std::__addressof(*__first), __x);
731 __guard.release();
732 return __first;
733 }
734
735#if _GLIBCXX_HOSTED
736 template<typename _ForwardIterator, typename _Size, typename _Tp,
737 typename _Tp2>
738 _GLIBCXX20_CONSTEXPR
739 inline _ForwardIterator
740 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
741 const _Tp& __x, allocator<_Tp2>&)
742 {
743#ifdef __cpp_lib_is_constant_evaluated
744 if (std::is_constant_evaluated())
745 return std::__do_uninit_fill_n(__first, __n, __x);
746#endif
747 return std::uninitialized_fill_n(__first, __n, __x);
748 }
749#endif
750
751 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
752 // __uninitialized_fill_move, __uninitialized_move_fill.
753 // All of these algorithms take a user-supplied allocator, which is used
754 // for construction and destruction.
755
756 // __uninitialized_copy_move
757 // Copies [first1, last1) into [result, result + (last1 - first1)), and
758 // move [first2, last2) into
759 // [result, result + (last1 - first1) + (last2 - first2)).
760 template<typename _InputIterator1, typename _InputIterator2,
761 typename _ForwardIterator, typename _Allocator>
762 inline _ForwardIterator
763 __uninitialized_copy_move(_InputIterator1 __first1,
764 _InputIterator1 __last1,
765 _InputIterator2 __first2,
766 _InputIterator2 __last2,
767 _ForwardIterator __result,
768 _Allocator& __alloc)
769 {
770 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
771 __result, __alloc);
772 _UninitDestroyGuard<_ForwardIterator, _Allocator> __guard(__result,
773 __alloc);
774 __result = __mid; // Everything up to __mid is now guarded.
775 __result = std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
776 __guard.release();
777 return __result;
778 }
779
780 // __uninitialized_move_copy
781 // Moves [first1, last1) into [result, result + (last1 - first1)), and
782 // copies [first2, last2) into
783 // [result, result + (last1 - first1) + (last2 - first2)).
784 template<typename _InputIterator1, typename _InputIterator2,
785 typename _ForwardIterator, typename _Allocator>
786 inline _ForwardIterator
787 __uninitialized_move_copy(_InputIterator1 __first1,
788 _InputIterator1 __last1,
789 _InputIterator2 __first2,
790 _InputIterator2 __last2,
791 _ForwardIterator __result,
792 _Allocator& __alloc)
793 {
794 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
795 __result, __alloc);
796 _UninitDestroyGuard<_ForwardIterator, _Allocator> __guard(__result,
797 __alloc);
798 __result = __mid; // Everything up to __mid is now guarded.
799 __result = std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
800 __guard.release();
801 return __result;
802 }
803
804 // __uninitialized_fill_move
805 // Fills [result, mid) with x, and moves [first, last) into
806 // [mid, mid + (last - first)).
807 template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
808 typename _Allocator>
809 inline _ForwardIterator
810 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
811 const _Tp& __x, _InputIterator __first,
812 _InputIterator __last, _Allocator& __alloc)
813 {
814 std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
815 _UninitDestroyGuard<_ForwardIterator, _Allocator> __guard(__result,
816 __alloc);
817 __result = __mid; // Everything up to __mid is now guarded.
818 __result = std::__uninitialized_move_a(__first, __last, __mid, __alloc);
819 __guard.release();
820 return __result;
821 }
822
823 // __uninitialized_move_fill
824 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
825 // fills [first2 + (last1 - first1), last2) with x.
826 template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
827 typename _Allocator>
828 inline void
829 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
830 _ForwardIterator __first2,
831 _ForwardIterator __last2, const _Tp& __x,
832 _Allocator& __alloc)
833 {
834 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
835 __first2,
836 __alloc);
837 _UninitDestroyGuard<_ForwardIterator, _Allocator> __guard(__first2,
838 __alloc);
839 __first2 = __mid2; // Everything up to __mid2 is now guarded.
840 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
841 __guard.release();
842 }
843
844 /// @endcond
845
846#if __cplusplus >= 201103L
847 /// @cond undocumented
848
849 // Extensions: __uninitialized_default, __uninitialized_default_n,
850 // __uninitialized_default_a, __uninitialized_default_n_a.
851
852 template<bool _TrivialValueType>
853 struct __uninitialized_default_1
854 {
855 template<typename _ForwardIterator>
856 _GLIBCXX26_CONSTEXPR
857 static void
858 __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
859 {
860 _UninitDestroyGuard<_ForwardIterator> __guard(__first);
861 for (; __first != __last; ++__first)
863 __guard.release();
864 }
865 };
866
867 template<>
868 struct __uninitialized_default_1<true>
869 {
870 template<typename _ForwardIterator>
871 _GLIBCXX26_CONSTEXPR
872 static void
873 __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
874 {
875 if (__first == __last)
876 return;
877
878 typename iterator_traits<_ForwardIterator>::value_type* __val
879 = std::addressof(*__first);
880 std::_Construct(__val);
881 if (++__first != __last)
882 std::fill(__first, __last, *__val);
883 }
884 };
885
886 template<bool _TrivialValueType>
887 struct __uninitialized_default_n_1
888 {
889 template<typename _ForwardIterator, typename _Size>
890 _GLIBCXX20_CONSTEXPR
891 static _ForwardIterator
892 __uninit_default_n(_ForwardIterator __first, _Size __n)
893 {
894 _UninitDestroyGuard<_ForwardIterator> __guard(__first);
895 for (; __n > 0; --__n, (void) ++__first)
897 __guard.release();
898 return __first;
899 }
900 };
901
902 template<>
903 struct __uninitialized_default_n_1<true>
904 {
905 template<typename _ForwardIterator, typename _Size>
906 _GLIBCXX20_CONSTEXPR
907 static _ForwardIterator
908 __uninit_default_n(_ForwardIterator __first, _Size __n)
909 {
910 if (__n > 0)
911 {
912 typename iterator_traits<_ForwardIterator>::value_type* __val
913 = std::addressof(*__first);
914 std::_Construct(__val);
915 ++__first;
916 __first = std::fill_n(__first, __n - 1, *__val);
917 }
918 return __first;
919 }
920 };
921
922 // __uninitialized_default
923 // Fills [first, last) with value-initialized value_types.
924 template<typename _ForwardIterator>
925 _GLIBCXX20_CONSTEXPR
926 inline void
927 __uninitialized_default(_ForwardIterator __first,
928 _ForwardIterator __last)
929 {
930#ifdef __cpp_lib_is_constant_evaluated
931 if (std::is_constant_evaluated())
932 return __uninitialized_default_1<false>::
933 __uninit_default(__first, __last);
934#endif
935
937 _ValueType;
938 // trivial types can have deleted assignment
939 const bool __assignable = is_copy_assignable<_ValueType>::value;
940
941 std::__uninitialized_default_1<__is_trivial(_ValueType)
942 && __assignable>::
943 __uninit_default(__first, __last);
944 }
945
946 // __uninitialized_default_n
947 // Fills [first, first + n) with value-initialized value_types.
948 template<typename _ForwardIterator, typename _Size>
949 _GLIBCXX20_CONSTEXPR
950 inline _ForwardIterator
951 __uninitialized_default_n(_ForwardIterator __first, _Size __n)
952 {
953#ifdef __cpp_lib_is_constant_evaluated
954 if (std::is_constant_evaluated())
955 return __uninitialized_default_n_1<false>::
956 __uninit_default_n(__first, __n);
957#endif
958
960 _ValueType;
961 // See uninitialized_fill_n for the conditions for using std::fill_n.
962 constexpr bool __can_fill
963 = __and_<is_integral<_Size>, is_copy_assignable<_ValueType>>::value;
964
965 return __uninitialized_default_n_1<__is_trivial(_ValueType)
966 && __can_fill>::
967 __uninit_default_n(__first, __n);
968 }
969
970
971 // __uninitialized_default_a
972 // Fills [first, last) with value_types constructed by the allocator
973 // alloc, with no arguments passed to the construct call.
974 template<typename _ForwardIterator, typename _Allocator>
975 void
976 __uninitialized_default_a(_ForwardIterator __first,
977 _ForwardIterator __last,
978 _Allocator& __alloc)
979 {
980 _UninitDestroyGuard<_ForwardIterator, _Allocator> __guard(__first,
981 __alloc);
982 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
983 for (; __first != __last; ++__first)
984 __traits::construct(__alloc, std::addressof(*__first));
985 __guard.release();
986 }
987
988#if _GLIBCXX_HOSTED
989 template<typename _ForwardIterator, typename _Tp>
990 inline void
991 __uninitialized_default_a(_ForwardIterator __first,
992 _ForwardIterator __last,
994 { std::__uninitialized_default(__first, __last); }
995#endif
996
997 // __uninitialized_default_n_a
998 // Fills [first, first + n) with value_types constructed by the allocator
999 // alloc, with no arguments passed to the construct call.
1000 template<typename _ForwardIterator, typename _Size, typename _Allocator>
1001 _GLIBCXX20_CONSTEXPR _ForwardIterator
1002 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
1003 _Allocator& __alloc)
1004 {
1005 _UninitDestroyGuard<_ForwardIterator, _Allocator> __guard(__first,
1006 __alloc);
1007 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
1008 for (; __n > 0; --__n, (void) ++__first)
1009 __traits::construct(__alloc, std::addressof(*__first));
1010 __guard.release();
1011 return __first;
1012 }
1013
1014#if _GLIBCXX_HOSTED
1015 // __uninitialized_default_n_a specialization for std::allocator,
1016 // which ignores the allocator and value-initializes the elements.
1017 template<typename _ForwardIterator, typename _Size, typename _Tp>
1018 _GLIBCXX20_CONSTEXPR
1019 inline _ForwardIterator
1020 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
1022 { return std::__uninitialized_default_n(__first, __n); }
1023#endif
1024
1025 template<bool _TrivialValueType>
1026 struct __uninitialized_default_novalue_1
1027 {
1028 template<typename _ForwardIterator>
1029 _GLIBCXX26_CONSTEXPR
1030 static void
1031 __uninit_default_novalue(_ForwardIterator __first,
1032 _ForwardIterator __last)
1033 {
1034 _UninitDestroyGuard<_ForwardIterator> __guard(__first);
1035 for (; __first != __last; ++__first)
1036 std::_Construct_novalue(std::addressof(*__first));
1037 __guard.release();
1038 }
1039 };
1040
1041 template<>
1042 struct __uninitialized_default_novalue_1<true>
1043 {
1044 template<typename _ForwardIterator>
1045 _GLIBCXX26_CONSTEXPR
1046 static void
1047 __uninit_default_novalue(_ForwardIterator, _ForwardIterator)
1048 {
1049 }
1050 };
1051
1052 template<bool _TrivialValueType>
1053 struct __uninitialized_default_novalue_n_1
1054 {
1055 template<typename _ForwardIterator, typename _Size>
1056 _GLIBCXX26_CONSTEXPR
1057 static _ForwardIterator
1058 __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
1059 {
1060 _UninitDestroyGuard<_ForwardIterator> __guard(__first);
1061 for (; __n > 0; --__n, (void) ++__first)
1062 std::_Construct_novalue(std::addressof(*__first));
1063 __guard.release();
1064 return __first;
1065 }
1066 };
1067
1068 template<>
1069 struct __uninitialized_default_novalue_n_1<true>
1070 {
1071 template<typename _ForwardIterator, typename _Size>
1072 _GLIBCXX26_CONSTEXPR
1073 static _ForwardIterator
1074 __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
1075 { return std::next(__first, __n); }
1076 };
1077
1078 // __uninitialized_default_novalue
1079 // Fills [first, last) with default-initialized value_types.
1080 template<typename _ForwardIterator>
1081 _GLIBCXX26_CONSTEXPR
1082 inline void
1083 __uninitialized_default_novalue(_ForwardIterator __first,
1084 _ForwardIterator __last)
1085 {
1087 _ValueType;
1088
1089 std::__uninitialized_default_novalue_1<
1091 __uninit_default_novalue(__first, __last);
1092 }
1093
1094 // __uninitialized_default_novalue_n
1095 // Fills [first, first + n) with default-initialized value_types.
1096 template<typename _ForwardIterator, typename _Size>
1097 _GLIBCXX26_CONSTEXPR
1098 inline _ForwardIterator
1099 __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
1100 {
1102 _ValueType;
1103
1104 return __uninitialized_default_novalue_n_1<
1106 __uninit_default_novalue_n(__first, __n);
1107 }
1108
1109 template<typename _InputIterator, typename _Size,
1110 typename _ForwardIterator>
1111 _GLIBCXX26_CONSTEXPR
1112 _ForwardIterator
1113 __uninitialized_copy_n(_InputIterator __first, _Size __n,
1114 _ForwardIterator __result, input_iterator_tag)
1115 {
1116 _UninitDestroyGuard<_ForwardIterator> __guard(__result);
1117 for (; __n > 0; --__n, (void) ++__first, ++__result)
1118 std::_Construct(std::addressof(*__result), *__first);
1119 __guard.release();
1120 return __result;
1121 }
1122
1123 template<typename _RandomAccessIterator, typename _Size,
1124 typename _ForwardIterator>
1125 _GLIBCXX26_CONSTEXPR
1126 inline _ForwardIterator
1127 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
1128 _ForwardIterator __result,
1130 { return std::uninitialized_copy(__first, __first + __n, __result); }
1131
1132 template<typename _InputIterator, typename _Size,
1133 typename _ForwardIterator>
1134 _GLIBCXX26_CONSTEXPR
1136 __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
1137 _ForwardIterator __result, input_iterator_tag)
1138 {
1139 _UninitDestroyGuard<_ForwardIterator> __guard(__result);
1140 for (; __n > 0; --__n, (void) ++__first, ++__result)
1141 std::_Construct(std::addressof(*__result), *__first);
1142 __guard.release();
1143 return {__first, __result};
1144 }
1145
1146 template<typename _RandomAccessIterator, typename _Size,
1147 typename _ForwardIterator>
1148 _GLIBCXX26_CONSTEXPR
1150 __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
1151 _ForwardIterator __result,
1153 {
1154 auto __second_res = uninitialized_copy(__first, __first + __n, __result);
1155 auto __first_res = std::next(__first, __n);
1156 return {__first_res, __second_res};
1157 }
1158
1159 /// @endcond
1160
1161 /**
1162 * @brief Copies the range [first,first+n) into result.
1163 * @param __first An input iterator.
1164 * @param __n The number of elements to copy.
1165 * @param __result An output iterator.
1166 * @return __result + __n
1167 * @since C++11
1168 *
1169 * Like copy_n(), but does not require an initialized output range.
1170 */
1171 template<typename _InputIterator, typename _Size, typename _ForwardIterator>
1172 _GLIBCXX26_CONSTEXPR
1173 inline _ForwardIterator
1174 uninitialized_copy_n(_InputIterator __first, _Size __n,
1175 _ForwardIterator __result)
1176 { return std::__uninitialized_copy_n(__first, __n, __result,
1177 std::__iterator_category(__first)); }
1178
1179 /// @cond undocumented
1180 template<typename _InputIterator, typename _Size, typename _ForwardIterator>
1181 _GLIBCXX26_CONSTEXPR
1183 __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
1184 _ForwardIterator __result)
1185 {
1186 return
1187 std::__uninitialized_copy_n_pair(__first, __n, __result,
1188 std::__iterator_category(__first));
1189 }
1190 /// @endcond
1191#endif
1192
1193#ifdef __glibcxx_raw_memory_algorithms // C++ >= 17
1194 /**
1195 * @brief Default-initializes objects in the range [first,last).
1196 * @param __first A forward iterator.
1197 * @param __last A forward iterator.
1198 * @since C++17
1199 */
1200 template <typename _ForwardIterator>
1201 _GLIBCXX26_CONSTEXPR
1202 inline void
1203 uninitialized_default_construct(_ForwardIterator __first,
1204 _ForwardIterator __last)
1205 {
1206 std::__uninitialized_default_novalue(__first, __last);
1207 }
1208
1209 /**
1210 * @brief Default-initializes objects in the range [first,first+count).
1211 * @param __first A forward iterator.
1212 * @param __count The number of objects to construct.
1213 * @return __first + __count
1214 * @since C++17
1215 */
1216 template <typename _ForwardIterator, typename _Size>
1217 _GLIBCXX26_CONSTEXPR
1218 inline _ForwardIterator
1219 uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
1220 {
1221 return std::__uninitialized_default_novalue_n(__first, __count);
1222 }
1223
1224 /**
1225 * @brief Value-initializes objects in the range [first,last).
1226 * @param __first A forward iterator.
1227 * @param __last A forward iterator.
1228 * @since C++17
1229 */
1230 template <typename _ForwardIterator>
1231 _GLIBCXX26_CONSTEXPR
1232 inline void
1233 uninitialized_value_construct(_ForwardIterator __first,
1234 _ForwardIterator __last)
1235 {
1236 return std::__uninitialized_default(__first, __last);
1237 }
1238
1239 /**
1240 * @brief Value-initializes objects in the range [first,first+count).
1241 * @param __first A forward iterator.
1242 * @param __count The number of objects to construct.
1243 * @return __result + __count
1244 * @since C++17
1245 */
1246 template <typename _ForwardIterator, typename _Size>
1247 _GLIBCXX26_CONSTEXPR
1248 inline _ForwardIterator
1249 uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
1250 {
1251 return std::__uninitialized_default_n(__first, __count);
1252 }
1253
1254 /**
1255 * @brief Move-construct from the range [first,last) into result.
1256 * @param __first An input iterator.
1257 * @param __last An input iterator.
1258 * @param __result An output iterator.
1259 * @return __result + (__first - __last)
1260 * @since C++17
1261 */
1262 template <typename _InputIterator, typename _ForwardIterator>
1263 _GLIBCXX26_CONSTEXPR
1264 inline _ForwardIterator
1265 uninitialized_move(_InputIterator __first, _InputIterator __last,
1266 _ForwardIterator __result)
1267 {
1269 (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
1270 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
1271 }
1272
1273 /**
1274 * @brief Move-construct from the range [first,first+count) into result.
1275 * @param __first An input iterator.
1276 * @param __count The number of objects to initialize.
1277 * @param __result An output iterator.
1278 * @return __result + __count
1279 * @since C++17
1280 */
1281 template <typename _InputIterator, typename _Size, typename _ForwardIterator>
1282 _GLIBCXX26_CONSTEXPR
1284 uninitialized_move_n(_InputIterator __first, _Size __count,
1285 _ForwardIterator __result)
1286 {
1287 auto __res = std::__uninitialized_copy_n_pair
1288 (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
1289 __count, __result);
1290 return {__res.first.base(), __res.second};
1291 }
1292#endif // __glibcxx_raw_memory_algorithms
1293
1294#if __cplusplus >= 201103L
1295 /// @cond undocumented
1296
1297 template<typename _Tp, typename _Up, typename _Allocator>
1298 _GLIBCXX20_CONSTEXPR
1299 inline void
1300 __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig,
1301 _Allocator& __alloc)
1302 noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc,
1303 __dest, std::move(*__orig)))
1305 __alloc, std::addressof(*__orig))))
1306 {
1307 typedef std::allocator_traits<_Allocator> __traits;
1308 __traits::construct(__alloc, __dest, std::move(*__orig));
1309 __traits::destroy(__alloc, std::addressof(*__orig));
1310 }
1311
1312 // This class may be specialized for specific types.
1313 // Also known as is_trivially_relocatable.
1314 template<typename _Tp, typename = void>
1315 struct __is_bitwise_relocatable
1316 : __bool_constant<__is_trivial(_Tp)>
1317 { };
1318
1319 template <typename _InputIterator, typename _ForwardIterator,
1320 typename _Allocator>
1321 _GLIBCXX20_CONSTEXPR
1322 inline _ForwardIterator
1323 __relocate_a_1(_InputIterator __first, _InputIterator __last,
1324 _ForwardIterator __result, _Allocator& __alloc)
1325 noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result),
1326 std::addressof(*__first),
1327 __alloc)))
1328 {
1330 _ValueType;
1332 _ValueType2;
1333 static_assert(std::is_same<_ValueType, _ValueType2>::value,
1334 "relocation is only possible for values of the same type");
1335 _ForwardIterator __cur = __result;
1336 for (; __first != __last; ++__first, (void)++__cur)
1337 std::__relocate_object_a(std::addressof(*__cur),
1338 std::addressof(*__first), __alloc);
1339 return __cur;
1340 }
1341
1342#if _GLIBCXX_HOSTED
1343 template <typename _Tp, typename _Up>
1344 _GLIBCXX20_CONSTEXPR
1345 inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*>
1346 __relocate_a_1(_Tp* __first, _Tp* __last,
1347 _Tp* __result,
1348 [[__maybe_unused__]] allocator<_Up>& __alloc) noexcept
1349 {
1350 ptrdiff_t __count = __last - __first;
1351 if (__count > 0)
1352 {
1353#ifdef __cpp_lib_is_constant_evaluated
1354 if (std::is_constant_evaluated())
1355 {
1356 // Can't use memcpy. Wrap the pointer so that __relocate_a_1
1357 // resolves to the non-trivial overload above.
1358 __gnu_cxx::__normal_iterator<_Tp*, void> __out(__result);
1359 __out = std::__relocate_a_1(__first, __last, __out, __alloc);
1360 return __out.base();
1361 }
1362#endif
1363 __builtin_memcpy(__result, __first, __count * sizeof(_Tp));
1364 }
1365 return __result + __count;
1366 }
1367#endif
1368
1369 template <typename _InputIterator, typename _ForwardIterator,
1370 typename _Allocator>
1371 _GLIBCXX20_CONSTEXPR
1372 inline _ForwardIterator
1373 __relocate_a(_InputIterator __first, _InputIterator __last,
1374 _ForwardIterator __result, _Allocator& __alloc)
1375 noexcept(noexcept(__relocate_a_1(std::__niter_base(__first),
1376 std::__niter_base(__last),
1377 std::__niter_base(__result), __alloc)))
1378 {
1379 return std::__relocate_a_1(std::__niter_base(__first),
1380 std::__niter_base(__last),
1381 std::__niter_base(__result), __alloc);
1382 }
1383
1384 /// @endcond
1385#endif // C++11
1386
1387 /// @} group memory
1388
1389_GLIBCXX_END_NAMESPACE_VERSION
1390} // namespace
1391
1392#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 _Tp * to_address(_Tp *__ptr) noexcept
Obtain address referenced by a pointer to an object.
Definition ptr_traits.h:232
typename remove_pointer< _Tp >::type remove_pointer_t
Alias template for remove_pointer.
Definition type_traits:2308
pair(_T1, _T2) -> pair< _T1, _T2 >
Two pairs are equal iff their members are equal.
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:176
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:138
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition move.h:52
constexpr iterator_traits< _Iter >::iterator_category __iterator_category(const _Iter &)
ISO C++ entities toplevel namespace is std.
constexpr iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
constexpr void _Construct(_Tp *__p, _Args &&... __args)
constexpr void advance(_InputIterator &__i, _Distance __n)
A generalization of pointer arithmetic.
constexpr void _Destroy(_ForwardIterator __first, _ForwardIterator __last)
is_integral
Definition type_traits:485
is_pointer
Definition type_traits:572
is_copy_assignable
Definition type_traits:1323
is_trivially_default_constructible
Definition type_traits:1391
Uniform interface to all allocator types.
static constexpr void construct(_Alloc &__a, _Tp *__p, _Args &&... __args) noexcept(_S_nothrow_construct< _Tp, _Args... >())
Construct an object of type _Tp
static constexpr void destroy(_Alloc &__a, _Tp *__p) noexcept(_S_nothrow_destroy< _Tp >())
Destroy an object of type _Tp.
The standard allocator, as per C++03 [20.4.1].
Definition allocator.h:134
Struct holding two objects of arbitrary type.
Definition stl_pair.h:304
Marking input iterators.
Random-access iterators support a superset of bidirectional iterator operations.
Traits class for iterators.
Uniform interface to C++98 and C++11 allocators.