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