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