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