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