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