xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/stl_uninitialized.h (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 // Raw memory manipulators -*- C++ -*-
2 
3 // Copyright (C) 2001-2020 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 > 201402L
60 #include <bits/stl_pair.h>
61 #endif
62 
63 #if __cplusplus >= 201103L
64 #include <type_traits>
65 #endif
66 
67 #include <ext/alloc_traits.h>
68 
69 namespace std _GLIBCXX_VISIBILITY(default)
70 {
71 _GLIBCXX_BEGIN_NAMESPACE_VERSION
72 
73   /** @addtogroup memory
74    *  @{
75    */
76 
77   /// @cond undocumented
78 
79   template<bool _TrivialValueTypes>
80     struct __uninitialized_copy
81     {
82       template<typename _InputIterator, typename _ForwardIterator>
83         static _ForwardIterator
84         __uninit_copy(_InputIterator __first, _InputIterator __last,
85 		      _ForwardIterator __result)
86         {
87 	  _ForwardIterator __cur = __result;
88 	  __try
89 	    {
90 	      for (; __first != __last; ++__first, (void)++__cur)
91 		std::_Construct(std::__addressof(*__cur), *__first);
92 	      return __cur;
93 	    }
94 	  __catch(...)
95 	    {
96 	      std::_Destroy(__result, __cur);
97 	      __throw_exception_again;
98 	    }
99 	}
100     };
101 
102   template<>
103     struct __uninitialized_copy<true>
104     {
105       template<typename _InputIterator, typename _ForwardIterator>
106         static _ForwardIterator
107         __uninit_copy(_InputIterator __first, _InputIterator __last,
108 		      _ForwardIterator __result)
109         { return std::copy(__first, __last, __result); }
110     };
111 
112   /// @endcond
113 
114   /**
115    *  @brief Copies the range [first,last) into result.
116    *  @param  __first  An input iterator.
117    *  @param  __last   An input iterator.
118    *  @param  __result An output iterator.
119    *  @return   __result + (__first - __last)
120    *
121    *  Like copy(), but does not require an initialized output range.
122   */
123   template<typename _InputIterator, typename _ForwardIterator>
124     inline _ForwardIterator
125     uninitialized_copy(_InputIterator __first, _InputIterator __last,
126 		       _ForwardIterator __result)
127     {
128       typedef typename iterator_traits<_InputIterator>::value_type
129 	_ValueType1;
130       typedef typename iterator_traits<_ForwardIterator>::value_type
131 	_ValueType2;
132 #if __cplusplus < 201103L
133       const bool __assignable = true;
134 #else
135       // Trivial types can have deleted copy constructor, but the std::copy
136       // optimization that uses memmove would happily "copy" them anyway.
137       static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
138 	  "result type must be constructible from value type of input range");
139 
140       typedef typename iterator_traits<_InputIterator>::reference _RefType1;
141       typedef typename iterator_traits<_ForwardIterator>::reference _RefType2;
142       // Trivial types can have deleted assignment, so using std::copy
143       // would be ill-formed. Require assignability before using std::copy:
144       const bool __assignable = is_assignable<_RefType2, _RefType1>::value;
145 #endif
146 
147       return std::__uninitialized_copy<__is_trivial(_ValueType1)
148 				       && __is_trivial(_ValueType2)
149 				       && __assignable>::
150 	__uninit_copy(__first, __last, __result);
151     }
152 
153   /// @cond undocumented
154 
155   template<bool _TrivialValueType>
156     struct __uninitialized_fill
157     {
158       template<typename _ForwardIterator, typename _Tp>
159         static void
160         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
161 		      const _Tp& __x)
162         {
163 	  _ForwardIterator __cur = __first;
164 	  __try
165 	    {
166 	      for (; __cur != __last; ++__cur)
167 		std::_Construct(std::__addressof(*__cur), __x);
168 	    }
169 	  __catch(...)
170 	    {
171 	      std::_Destroy(__first, __cur);
172 	      __throw_exception_again;
173 	    }
174 	}
175     };
176 
177   template<>
178     struct __uninitialized_fill<true>
179     {
180       template<typename _ForwardIterator, typename _Tp>
181         static void
182         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
183 		      const _Tp& __x)
184         { std::fill(__first, __last, __x); }
185     };
186 
187   /// @endcond
188 
189   /**
190    *  @brief Copies the value x into the range [first,last).
191    *  @param  __first  An input iterator.
192    *  @param  __last   An input iterator.
193    *  @param  __x      The source value.
194    *  @return   Nothing.
195    *
196    *  Like fill(), but does not require an initialized output range.
197   */
198   template<typename _ForwardIterator, typename _Tp>
199     inline void
200     uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
201 		       const _Tp& __x)
202     {
203       typedef typename iterator_traits<_ForwardIterator>::value_type
204 	_ValueType;
205 #if __cplusplus < 201103L
206       const bool __assignable = true;
207 #else
208       // Trivial types can have deleted copy constructor, but the std::fill
209       // optimization that uses memmove would happily "copy" them anyway.
210       static_assert(is_constructible<_ValueType, const _Tp&>::value,
211 	  "result type must be constructible from input type");
212 
213       // Trivial types can have deleted assignment, so using std::fill
214       // would be ill-formed. Require assignability before using std::fill:
215       const bool __assignable = is_copy_assignable<_ValueType>::value;
216 #endif
217 
218       std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>::
219 	__uninit_fill(__first, __last, __x);
220     }
221 
222   /// @cond undocumented
223 
224   template<bool _TrivialValueType>
225     struct __uninitialized_fill_n
226     {
227       template<typename _ForwardIterator, typename _Size, typename _Tp>
228         static _ForwardIterator
229         __uninit_fill_n(_ForwardIterator __first, _Size __n,
230 			const _Tp& __x)
231         {
232 	  _ForwardIterator __cur = __first;
233 	  __try
234 	    {
235 	      for (; __n > 0; --__n, (void) ++__cur)
236 		std::_Construct(std::__addressof(*__cur), __x);
237 	      return __cur;
238 	    }
239 	  __catch(...)
240 	    {
241 	      std::_Destroy(__first, __cur);
242 	      __throw_exception_again;
243 	    }
244 	}
245     };
246 
247   template<>
248     struct __uninitialized_fill_n<true>
249     {
250       template<typename _ForwardIterator, typename _Size, typename _Tp>
251         static _ForwardIterator
252         __uninit_fill_n(_ForwardIterator __first, _Size __n,
253 			const _Tp& __x)
254         { return std::fill_n(__first, __n, __x); }
255     };
256 
257   /// @endcond
258 
259    // _GLIBCXX_RESOLVE_LIB_DEFECTS
260    // DR 1339. uninitialized_fill_n should return the end of its range
261   /**
262    *  @brief Copies the value x into the range [first,first+n).
263    *  @param  __first  An input iterator.
264    *  @param  __n      The number of copies to make.
265    *  @param  __x      The source value.
266    *  @return   Nothing.
267    *
268    *  Like fill_n(), but does not require an initialized output range.
269   */
270   template<typename _ForwardIterator, typename _Size, typename _Tp>
271     inline _ForwardIterator
272     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
273     {
274       typedef typename iterator_traits<_ForwardIterator>::value_type
275 	_ValueType;
276 #if __cplusplus < 201103L
277       const bool __assignable = true;
278 #else
279       // Trivial types can have deleted copy constructor, but the std::fill
280       // optimization that uses memmove would happily "copy" them anyway.
281       static_assert(is_constructible<_ValueType, const _Tp&>::value,
282 	  "result type must be constructible from input type");
283 
284       // Trivial types can have deleted assignment, so using std::fill
285       // would be ill-formed. Require assignability before using std::fill:
286       const bool __assignable = is_copy_assignable<_ValueType>::value;
287 #endif
288       return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
289 	__uninit_fill_n(__first, __n, __x);
290     }
291 
292   /// @cond undocumented
293 
294   // Extensions: versions of uninitialized_copy, uninitialized_fill,
295   //  and uninitialized_fill_n that take an allocator parameter.
296   //  We dispatch back to the standard versions when we're given the
297   //  default allocator.  For nondefault allocators we do not use
298   //  any of the POD optimizations.
299 
300   template<typename _InputIterator, typename _ForwardIterator,
301 	   typename _Allocator>
302     _ForwardIterator
303     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
304 			   _ForwardIterator __result, _Allocator& __alloc)
305     {
306       _ForwardIterator __cur = __result;
307       __try
308 	{
309 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
310 	  for (; __first != __last; ++__first, (void)++__cur)
311 	    __traits::construct(__alloc, std::__addressof(*__cur), *__first);
312 	  return __cur;
313 	}
314       __catch(...)
315 	{
316 	  std::_Destroy(__result, __cur, __alloc);
317 	  __throw_exception_again;
318 	}
319     }
320 
321   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
322     inline _ForwardIterator
323     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
324 			   _ForwardIterator __result, allocator<_Tp>&)
325     { return std::uninitialized_copy(__first, __last, __result); }
326 
327   template<typename _InputIterator, typename _ForwardIterator,
328 	   typename _Allocator>
329     inline _ForwardIterator
330     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
331 			   _ForwardIterator __result, _Allocator& __alloc)
332     {
333       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
334 					 _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
335 					 __result, __alloc);
336     }
337 
338   template<typename _InputIterator, typename _ForwardIterator,
339 	   typename _Allocator>
340     inline _ForwardIterator
341     __uninitialized_move_if_noexcept_a(_InputIterator __first,
342 				       _InputIterator __last,
343 				       _ForwardIterator __result,
344 				       _Allocator& __alloc)
345     {
346       return std::__uninitialized_copy_a
347 	(_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
348 	 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
349     }
350 
351   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
352     void
353     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
354 			   const _Tp& __x, _Allocator& __alloc)
355     {
356       _ForwardIterator __cur = __first;
357       __try
358 	{
359 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
360 	  for (; __cur != __last; ++__cur)
361 	    __traits::construct(__alloc, std::__addressof(*__cur), __x);
362 	}
363       __catch(...)
364 	{
365 	  std::_Destroy(__first, __cur, __alloc);
366 	  __throw_exception_again;
367 	}
368     }
369 
370   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
371     inline void
372     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
373 			   const _Tp& __x, allocator<_Tp2>&)
374     { std::uninitialized_fill(__first, __last, __x); }
375 
376   template<typename _ForwardIterator, typename _Size, typename _Tp,
377 	   typename _Allocator>
378     _ForwardIterator
379     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
380 			     const _Tp& __x, _Allocator& __alloc)
381     {
382       _ForwardIterator __cur = __first;
383       __try
384 	{
385 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
386 	  for (; __n > 0; --__n, (void) ++__cur)
387 	    __traits::construct(__alloc, std::__addressof(*__cur), __x);
388 	  return __cur;
389 	}
390       __catch(...)
391 	{
392 	  std::_Destroy(__first, __cur, __alloc);
393 	  __throw_exception_again;
394 	}
395     }
396 
397   template<typename _ForwardIterator, typename _Size, typename _Tp,
398 	   typename _Tp2>
399     inline _ForwardIterator
400     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
401 			     const _Tp& __x, allocator<_Tp2>&)
402     { return std::uninitialized_fill_n(__first, __n, __x); }
403 
404 
405   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
406   // __uninitialized_fill_move, __uninitialized_move_fill.
407   // All of these algorithms take a user-supplied allocator, which is used
408   // for construction and destruction.
409 
410   // __uninitialized_copy_move
411   // Copies [first1, last1) into [result, result + (last1 - first1)), and
412   //  move [first2, last2) into
413   //  [result, result + (last1 - first1) + (last2 - first2)).
414   template<typename _InputIterator1, typename _InputIterator2,
415 	   typename _ForwardIterator, typename _Allocator>
416     inline _ForwardIterator
417     __uninitialized_copy_move(_InputIterator1 __first1,
418 			      _InputIterator1 __last1,
419 			      _InputIterator2 __first2,
420 			      _InputIterator2 __last2,
421 			      _ForwardIterator __result,
422 			      _Allocator& __alloc)
423     {
424       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
425 							   __result,
426 							   __alloc);
427       __try
428 	{
429 	  return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
430 	}
431       __catch(...)
432 	{
433 	  std::_Destroy(__result, __mid, __alloc);
434 	  __throw_exception_again;
435 	}
436     }
437 
438   // __uninitialized_move_copy
439   // Moves [first1, last1) into [result, result + (last1 - first1)), and
440   //  copies [first2, last2) into
441   //  [result, result + (last1 - first1) + (last2 - first2)).
442   template<typename _InputIterator1, typename _InputIterator2,
443 	   typename _ForwardIterator, typename _Allocator>
444     inline _ForwardIterator
445     __uninitialized_move_copy(_InputIterator1 __first1,
446 			      _InputIterator1 __last1,
447 			      _InputIterator2 __first2,
448 			      _InputIterator2 __last2,
449 			      _ForwardIterator __result,
450 			      _Allocator& __alloc)
451     {
452       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
453 							   __result,
454 							   __alloc);
455       __try
456 	{
457 	  return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
458 	}
459       __catch(...)
460 	{
461 	  std::_Destroy(__result, __mid, __alloc);
462 	  __throw_exception_again;
463 	}
464     }
465 
466   // __uninitialized_fill_move
467   // Fills [result, mid) with x, and moves [first, last) into
468   //  [mid, mid + (last - first)).
469   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
470 	   typename _Allocator>
471     inline _ForwardIterator
472     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
473 			      const _Tp& __x, _InputIterator __first,
474 			      _InputIterator __last, _Allocator& __alloc)
475     {
476       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
477       __try
478 	{
479 	  return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
480 	}
481       __catch(...)
482 	{
483 	  std::_Destroy(__result, __mid, __alloc);
484 	  __throw_exception_again;
485 	}
486     }
487 
488   // __uninitialized_move_fill
489   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
490   //  fills [first2 + (last1 - first1), last2) with x.
491   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
492 	   typename _Allocator>
493     inline void
494     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
495 			      _ForwardIterator __first2,
496 			      _ForwardIterator __last2, const _Tp& __x,
497 			      _Allocator& __alloc)
498     {
499       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
500 							    __first2,
501 							    __alloc);
502       __try
503 	{
504 	  std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
505 	}
506       __catch(...)
507 	{
508 	  std::_Destroy(__first2, __mid2, __alloc);
509 	  __throw_exception_again;
510 	}
511     }
512 
513   /// @endcond
514 
515 #if __cplusplus >= 201103L
516   /// @cond undocumented
517 
518   // Extensions: __uninitialized_default, __uninitialized_default_n,
519   // __uninitialized_default_a, __uninitialized_default_n_a.
520 
521   template<bool _TrivialValueType>
522     struct __uninitialized_default_1
523     {
524       template<typename _ForwardIterator>
525         static void
526         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
527         {
528 	  _ForwardIterator __cur = __first;
529 	  __try
530 	    {
531 	      for (; __cur != __last; ++__cur)
532 		std::_Construct(std::__addressof(*__cur));
533 	    }
534 	  __catch(...)
535 	    {
536 	      std::_Destroy(__first, __cur);
537 	      __throw_exception_again;
538 	    }
539 	}
540     };
541 
542   template<>
543     struct __uninitialized_default_1<true>
544     {
545       template<typename _ForwardIterator>
546         static void
547         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
548         {
549 	  typedef typename iterator_traits<_ForwardIterator>::value_type
550 	    _ValueType;
551 
552 	  std::fill(__first, __last, _ValueType());
553 	}
554     };
555 
556   template<bool _TrivialValueType>
557     struct __uninitialized_default_n_1
558     {
559       template<typename _ForwardIterator, typename _Size>
560         static _ForwardIterator
561         __uninit_default_n(_ForwardIterator __first, _Size __n)
562         {
563 	  _ForwardIterator __cur = __first;
564 	  __try
565 	    {
566 	      for (; __n > 0; --__n, (void) ++__cur)
567 		std::_Construct(std::__addressof(*__cur));
568 	      return __cur;
569 	    }
570 	  __catch(...)
571 	    {
572 	      std::_Destroy(__first, __cur);
573 	      __throw_exception_again;
574 	    }
575 	}
576     };
577 
578   template<>
579     struct __uninitialized_default_n_1<true>
580     {
581       template<typename _ForwardIterator, typename _Size>
582         static _ForwardIterator
583         __uninit_default_n(_ForwardIterator __first, _Size __n)
584         {
585 	  typedef typename iterator_traits<_ForwardIterator>::value_type
586 	    _ValueType;
587 
588 	  return std::fill_n(__first, __n, _ValueType());
589 	}
590     };
591 
592   // __uninitialized_default
593   // Fills [first, last) with std::distance(first, last) default
594   // constructed value_types(s).
595   template<typename _ForwardIterator>
596     inline void
597     __uninitialized_default(_ForwardIterator __first,
598 			    _ForwardIterator __last)
599     {
600       typedef typename iterator_traits<_ForwardIterator>::value_type
601 	_ValueType;
602       // trivial types can have deleted assignment
603       const bool __assignable = is_copy_assignable<_ValueType>::value;
604 
605       std::__uninitialized_default_1<__is_trivial(_ValueType)
606 				     && __assignable>::
607 	__uninit_default(__first, __last);
608     }
609 
610   // __uninitialized_default_n
611   // Fills [first, first + n) with n default constructed value_type(s).
612   template<typename _ForwardIterator, typename _Size>
613     inline _ForwardIterator
614     __uninitialized_default_n(_ForwardIterator __first, _Size __n)
615     {
616       typedef typename iterator_traits<_ForwardIterator>::value_type
617 	_ValueType;
618       // trivial types can have deleted assignment
619       const bool __assignable = is_copy_assignable<_ValueType>::value;
620 
621       return __uninitialized_default_n_1<__is_trivial(_ValueType)
622 				       && __assignable>::
623 	__uninit_default_n(__first, __n);
624     }
625 
626 
627   // __uninitialized_default_a
628   // Fills [first, last) with std::distance(first, last) default
629   // constructed value_types(s), constructed with the allocator alloc.
630   template<typename _ForwardIterator, typename _Allocator>
631     void
632     __uninitialized_default_a(_ForwardIterator __first,
633 			      _ForwardIterator __last,
634 			      _Allocator& __alloc)
635     {
636       _ForwardIterator __cur = __first;
637       __try
638 	{
639 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
640 	  for (; __cur != __last; ++__cur)
641 	    __traits::construct(__alloc, std::__addressof(*__cur));
642 	}
643       __catch(...)
644 	{
645 	  std::_Destroy(__first, __cur, __alloc);
646 	  __throw_exception_again;
647 	}
648     }
649 
650   template<typename _ForwardIterator, typename _Tp>
651     inline void
652     __uninitialized_default_a(_ForwardIterator __first,
653 			      _ForwardIterator __last,
654 			      allocator<_Tp>&)
655     { std::__uninitialized_default(__first, __last); }
656 
657 
658   // __uninitialized_default_n_a
659   // Fills [first, first + n) with n default constructed value_types(s),
660   // constructed with the allocator alloc.
661   template<typename _ForwardIterator, typename _Size, typename _Allocator>
662     _ForwardIterator
663     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
664 				_Allocator& __alloc)
665     {
666       _ForwardIterator __cur = __first;
667       __try
668 	{
669 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
670 	  for (; __n > 0; --__n, (void) ++__cur)
671 	    __traits::construct(__alloc, std::__addressof(*__cur));
672 	  return __cur;
673 	}
674       __catch(...)
675 	{
676 	  std::_Destroy(__first, __cur, __alloc);
677 	  __throw_exception_again;
678 	}
679     }
680 
681   template<typename _ForwardIterator, typename _Size, typename _Tp>
682     inline _ForwardIterator
683     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
684 				allocator<_Tp>&)
685     { return std::__uninitialized_default_n(__first, __n); }
686 
687   template<bool _TrivialValueType>
688     struct __uninitialized_default_novalue_1
689     {
690       template<typename _ForwardIterator>
691 	static void
692 	__uninit_default_novalue(_ForwardIterator __first,
693 				 _ForwardIterator __last)
694 	{
695 	  _ForwardIterator __cur = __first;
696 	  __try
697 	    {
698 	      for (; __cur != __last; ++__cur)
699 		std::_Construct_novalue(std::__addressof(*__cur));
700 	    }
701 	  __catch(...)
702 	    {
703 	      std::_Destroy(__first, __cur);
704 	      __throw_exception_again;
705 	    }
706 	}
707     };
708 
709   template<>
710     struct __uninitialized_default_novalue_1<true>
711     {
712       template<typename _ForwardIterator>
713         static void
714         __uninit_default_novalue(_ForwardIterator __first,
715 				 _ForwardIterator __last)
716 	{
717 	}
718     };
719 
720   template<bool _TrivialValueType>
721     struct __uninitialized_default_novalue_n_1
722     {
723       template<typename _ForwardIterator, typename _Size>
724 	static _ForwardIterator
725 	__uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
726 	{
727 	  _ForwardIterator __cur = __first;
728 	  __try
729 	    {
730 	      for (; __n > 0; --__n, (void) ++__cur)
731 		std::_Construct_novalue(std::__addressof(*__cur));
732 	      return __cur;
733 	    }
734 	  __catch(...)
735 	    {
736 	      std::_Destroy(__first, __cur);
737 	      __throw_exception_again;
738 	    }
739 	}
740     };
741 
742   template<>
743     struct __uninitialized_default_novalue_n_1<true>
744     {
745       template<typename _ForwardIterator, typename _Size>
746 	static _ForwardIterator
747 	__uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
748 	{ return std::next(__first, __n); }
749     };
750 
751   // __uninitialized_default_novalue
752   // Fills [first, last) with std::distance(first, last) default-initialized
753   // value_types(s).
754   template<typename _ForwardIterator>
755     inline void
756     __uninitialized_default_novalue(_ForwardIterator __first,
757 				    _ForwardIterator __last)
758     {
759       typedef typename iterator_traits<_ForwardIterator>::value_type
760 	_ValueType;
761 
762       std::__uninitialized_default_novalue_1<
763 	is_trivially_default_constructible<_ValueType>::value>::
764 	__uninit_default_novalue(__first, __last);
765     }
766 
767   // __uninitialized_default_n
768   // Fills [first, first + n) with n default-initialized value_type(s).
769   template<typename _ForwardIterator, typename _Size>
770     inline _ForwardIterator
771     __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
772     {
773       typedef typename iterator_traits<_ForwardIterator>::value_type
774 	_ValueType;
775 
776       return __uninitialized_default_novalue_n_1<
777 	is_trivially_default_constructible<_ValueType>::value>::
778 	__uninit_default_novalue_n(__first, __n);
779     }
780 
781   template<typename _InputIterator, typename _Size,
782 	   typename _ForwardIterator>
783     _ForwardIterator
784     __uninitialized_copy_n(_InputIterator __first, _Size __n,
785 			   _ForwardIterator __result, input_iterator_tag)
786     {
787       _ForwardIterator __cur = __result;
788       __try
789 	{
790 	  for (; __n > 0; --__n, (void) ++__first, ++__cur)
791 	    std::_Construct(std::__addressof(*__cur), *__first);
792 	  return __cur;
793 	}
794       __catch(...)
795 	{
796 	  std::_Destroy(__result, __cur);
797 	  __throw_exception_again;
798 	}
799     }
800 
801   template<typename _RandomAccessIterator, typename _Size,
802 	   typename _ForwardIterator>
803     inline _ForwardIterator
804     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
805 			   _ForwardIterator __result,
806 			   random_access_iterator_tag)
807     { return std::uninitialized_copy(__first, __first + __n, __result); }
808 
809   template<typename _InputIterator, typename _Size,
810 	   typename _ForwardIterator>
811     pair<_InputIterator, _ForwardIterator>
812     __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
813 			   _ForwardIterator __result, input_iterator_tag)
814     {
815       _ForwardIterator __cur = __result;
816       __try
817 	{
818 	  for (; __n > 0; --__n, (void) ++__first, ++__cur)
819 	    std::_Construct(std::__addressof(*__cur), *__first);
820 	  return {__first, __cur};
821 	}
822       __catch(...)
823 	{
824 	  std::_Destroy(__result, __cur);
825 	  __throw_exception_again;
826 	}
827     }
828 
829   template<typename _RandomAccessIterator, typename _Size,
830 	   typename _ForwardIterator>
831     inline pair<_RandomAccessIterator, _ForwardIterator>
832     __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
833 			   _ForwardIterator __result,
834 			   random_access_iterator_tag)
835     {
836       auto __second_res = uninitialized_copy(__first, __first + __n, __result);
837       auto __first_res = std::next(__first, __n);
838       return {__first_res, __second_res};
839     }
840 
841   /// @endcond
842 
843   /**
844    *  @brief Copies the range [first,first+n) into result.
845    *  @param  __first  An input iterator.
846    *  @param  __n      The number of elements to copy.
847    *  @param  __result An output iterator.
848    *  @return  __result + __n
849    *
850    *  Like copy_n(), but does not require an initialized output range.
851   */
852   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
853     inline _ForwardIterator
854     uninitialized_copy_n(_InputIterator __first, _Size __n,
855 			 _ForwardIterator __result)
856     { return std::__uninitialized_copy_n(__first, __n, __result,
857 					 std::__iterator_category(__first)); }
858 
859   /// @cond undocumented
860   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
861     inline pair<_InputIterator, _ForwardIterator>
862     __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
863 			      _ForwardIterator __result)
864     {
865       return
866 	std::__uninitialized_copy_n_pair(__first, __n, __result,
867 					 std::__iterator_category(__first));
868     }
869   /// @endcond
870 #endif
871 
872 #if __cplusplus >= 201703L
873 # define __cpp_lib_raw_memory_algorithms 201606L
874 
875   /**
876    *  @brief Default-initializes objects in the range [first,last).
877    *  @param  __first  A forward iterator.
878    *  @param  __last   A forward iterator.
879   */
880   template <typename _ForwardIterator>
881     inline void
882     uninitialized_default_construct(_ForwardIterator __first,
883 				    _ForwardIterator __last)
884     {
885       __uninitialized_default_novalue(__first, __last);
886     }
887 
888   /**
889    *  @brief Default-initializes objects in the range [first,first+count).
890    *  @param  __first  A forward iterator.
891    *  @param  __count  The number of objects to construct.
892    *  @return   __first + __count
893   */
894   template <typename _ForwardIterator, typename _Size>
895     inline _ForwardIterator
896     uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
897     {
898       return __uninitialized_default_novalue_n(__first, __count);
899     }
900 
901   /**
902    *  @brief Value-initializes objects in the range [first,last).
903    *  @param  __first  A forward iterator.
904    *  @param  __last   A forward iterator.
905   */
906   template <typename _ForwardIterator>
907     inline void
908     uninitialized_value_construct(_ForwardIterator __first,
909 				  _ForwardIterator __last)
910     {
911       return __uninitialized_default(__first, __last);
912     }
913 
914   /**
915    *  @brief Value-initializes objects in the range [first,first+count).
916    *  @param  __first  A forward iterator.
917    *  @param  __count  The number of objects to construct.
918    *  @return   __result + __count
919   */
920   template <typename _ForwardIterator, typename _Size>
921     inline _ForwardIterator
922     uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
923     {
924       return __uninitialized_default_n(__first, __count);
925     }
926 
927   /**
928    *  @brief Move-construct from the range [first,last) into result.
929    *  @param  __first  An input iterator.
930    *  @param  __last   An input iterator.
931    *  @param  __result An output iterator.
932    *  @return   __result + (__first - __last)
933   */
934   template <typename _InputIterator, typename _ForwardIterator>
935     inline _ForwardIterator
936     uninitialized_move(_InputIterator __first, _InputIterator __last,
937 		       _ForwardIterator __result)
938     {
939       return std::uninitialized_copy
940 	(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
941 	 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
942     }
943 
944   /**
945    *  @brief Move-construct from the range [first,first+count) into result.
946    *  @param  __first  An input iterator.
947    *  @param  __count  The number of objects to initialize.
948    *  @param  __result An output iterator.
949    *  @return  __result + __count
950   */
951   template <typename _InputIterator, typename _Size, typename _ForwardIterator>
952     inline pair<_InputIterator, _ForwardIterator>
953     uninitialized_move_n(_InputIterator __first, _Size __count,
954 			 _ForwardIterator __result)
955     {
956       auto __res = std::__uninitialized_copy_n_pair
957 	(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
958 	 __count, __result);
959       return {__res.first.base(), __res.second};
960     }
961 #endif // C++17
962 
963 #if __cplusplus >= 201103L
964   /// @cond undocumented
965 
966   template<typename _Tp, typename _Up, typename _Allocator>
967     inline void
968     __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig,
969 			_Allocator& __alloc)
970     noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc,
971 			 __dest, std::move(*__orig)))
972 	     && noexcept(std::allocator_traits<_Allocator>::destroy(
973 			    __alloc, std::__addressof(*__orig))))
974     {
975       typedef std::allocator_traits<_Allocator> __traits;
976       __traits::construct(__alloc, __dest, std::move(*__orig));
977       __traits::destroy(__alloc, std::__addressof(*__orig));
978     }
979 
980   // This class may be specialized for specific types.
981   // Also known as is_trivially_relocatable.
982   template<typename _Tp, typename = void>
983     struct __is_bitwise_relocatable
984     : is_trivial<_Tp> { };
985 
986   template <typename _Tp, typename _Up>
987     inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*>
988     __relocate_a_1(_Tp* __first, _Tp* __last,
989 		   _Tp* __result, allocator<_Up>&) noexcept
990     {
991       ptrdiff_t __count = __last - __first;
992       if (__count > 0)
993 	__builtin_memmove(__result, __first, __count * sizeof(_Tp));
994       return __result + __count;
995     }
996 
997   template <typename _InputIterator, typename _ForwardIterator,
998 	    typename _Allocator>
999     inline _ForwardIterator
1000     __relocate_a_1(_InputIterator __first, _InputIterator __last,
1001 		   _ForwardIterator __result, _Allocator& __alloc)
1002     noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result),
1003 					       std::addressof(*__first),
1004 					       __alloc)))
1005     {
1006       typedef typename iterator_traits<_InputIterator>::value_type
1007 	_ValueType;
1008       typedef typename iterator_traits<_ForwardIterator>::value_type
1009 	_ValueType2;
1010       static_assert(std::is_same<_ValueType, _ValueType2>::value,
1011 	  "relocation is only possible for values of the same type");
1012       _ForwardIterator __cur = __result;
1013       for (; __first != __last; ++__first, (void)++__cur)
1014 	std::__relocate_object_a(std::__addressof(*__cur),
1015 				 std::__addressof(*__first), __alloc);
1016       return __cur;
1017     }
1018 
1019   template <typename _InputIterator, typename _ForwardIterator,
1020 	    typename _Allocator>
1021     inline _ForwardIterator
1022     __relocate_a(_InputIterator __first, _InputIterator __last,
1023 		 _ForwardIterator __result, _Allocator& __alloc)
1024     noexcept(noexcept(__relocate_a_1(std::__niter_base(__first),
1025 				     std::__niter_base(__last),
1026 				     std::__niter_base(__result), __alloc)))
1027     {
1028       return __relocate_a_1(std::__niter_base(__first),
1029 			    std::__niter_base(__last),
1030 			    std::__niter_base(__result), __alloc);
1031     }
1032 
1033   /// @endcond
1034 #endif
1035 
1036   // @} group memory
1037 
1038 _GLIBCXX_END_NAMESPACE_VERSION
1039 } // namespace
1040 
1041 #endif /* _STL_UNINITIALIZED_H */
1042