libstdc++
stl_uninitialized.h
Go to the documentation of this file.
00001 // Raw memory manipulators -*- C++ -*-
00002 
00003 // Copyright (C) 2001-2019 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /*
00026  *
00027  * Copyright (c) 1994
00028  * Hewlett-Packard Company
00029  *
00030  * Permission to use, copy, modify, distribute and sell this software
00031  * and its documentation for any purpose is hereby granted without fee,
00032  * provided that the above copyright notice appear in all copies and
00033  * that both that copyright notice and this permission notice appear
00034  * in supporting documentation.  Hewlett-Packard Company makes no
00035  * representations about the suitability of this software for any
00036  * purpose.  It is provided "as is" without express or implied warranty.
00037  *
00038  *
00039  * Copyright (c) 1996,1997
00040  * Silicon Graphics Computer Systems, Inc.
00041  *
00042  * Permission to use, copy, modify, distribute and sell this software
00043  * and its documentation for any purpose is hereby granted without fee,
00044  * provided that the above copyright notice appear in all copies and
00045  * that both that copyright notice and this permission notice appear
00046  * in supporting documentation.  Silicon Graphics makes no
00047  * representations about the suitability of this software for any
00048  * purpose.  It is provided "as is" without express or implied warranty.
00049  */
00050 
00051 /** @file bits/stl_uninitialized.h
00052  *  This is an internal header file, included by other library headers.
00053  *  Do not attempt to use it directly. @headername{memory}
00054  */
00055 
00056 #ifndef _STL_UNINITIALIZED_H
00057 #define _STL_UNINITIALIZED_H 1
00058 
00059 #if __cplusplus > 201402L
00060 #include <utility>
00061 #endif
00062 
00063 #if __cplusplus >= 201103L
00064 #include <type_traits>
00065 #endif
00066 
00067 namespace std _GLIBCXX_VISIBILITY(default)
00068 {
00069 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00070 
00071   template<bool _TrivialValueTypes>
00072     struct __uninitialized_copy
00073     {
00074       template<typename _InputIterator, typename _ForwardIterator>
00075         static _ForwardIterator
00076         __uninit_copy(_InputIterator __first, _InputIterator __last,
00077                       _ForwardIterator __result)
00078         {
00079           _ForwardIterator __cur = __result;
00080           __try
00081             {
00082               for (; __first != __last; ++__first, (void)++__cur)
00083                 std::_Construct(std::__addressof(*__cur), *__first);
00084               return __cur;
00085             }
00086           __catch(...)
00087             {
00088               std::_Destroy(__result, __cur);
00089               __throw_exception_again;
00090             }
00091         }
00092     };
00093 
00094   template<>
00095     struct __uninitialized_copy<true>
00096     {
00097       template<typename _InputIterator, typename _ForwardIterator>
00098         static _ForwardIterator
00099         __uninit_copy(_InputIterator __first, _InputIterator __last,
00100                       _ForwardIterator __result)
00101         { return std::copy(__first, __last, __result); }
00102     };
00103 
00104   /**
00105    *  @brief Copies the range [first,last) into result.
00106    *  @param  __first  An input iterator.
00107    *  @param  __last   An input iterator.
00108    *  @param  __result An output iterator.
00109    *  @return   __result + (__first - __last)
00110    *
00111    *  Like copy(), but does not require an initialized output range.
00112   */
00113   template<typename _InputIterator, typename _ForwardIterator>
00114     inline _ForwardIterator
00115     uninitialized_copy(_InputIterator __first, _InputIterator __last,
00116                        _ForwardIterator __result)
00117     {
00118       typedef typename iterator_traits<_InputIterator>::value_type
00119         _ValueType1;
00120       typedef typename iterator_traits<_ForwardIterator>::value_type
00121         _ValueType2;
00122 #if __cplusplus < 201103L
00123       const bool __assignable = true;
00124 #else
00125       // Trivial types can have deleted copy constructor, but the std::copy
00126       // optimization that uses memmove would happily "copy" them anyway.
00127       static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
00128           "result type must be constructible from value type of input range");
00129 
00130       typedef typename iterator_traits<_InputIterator>::reference _RefType1;
00131       typedef typename iterator_traits<_ForwardIterator>::reference _RefType2;
00132       // Trivial types can have deleted assignment, so using std::copy
00133       // would be ill-formed. Require assignability before using std::copy:
00134       const bool __assignable = is_assignable<_RefType2, _RefType1>::value;
00135 #endif
00136 
00137       return std::__uninitialized_copy<__is_trivial(_ValueType1)
00138                                        && __is_trivial(_ValueType2)
00139                                        && __assignable>::
00140         __uninit_copy(__first, __last, __result);
00141     }
00142 
00143 
00144   template<bool _TrivialValueType>
00145     struct __uninitialized_fill
00146     {
00147       template<typename _ForwardIterator, typename _Tp>
00148         static void
00149         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
00150                       const _Tp& __x)
00151         {
00152           _ForwardIterator __cur = __first;
00153           __try
00154             {
00155               for (; __cur != __last; ++__cur)
00156                 std::_Construct(std::__addressof(*__cur), __x);
00157             }
00158           __catch(...)
00159             {
00160               std::_Destroy(__first, __cur);
00161               __throw_exception_again;
00162             }
00163         }
00164     };
00165 
00166   template<>
00167     struct __uninitialized_fill<true>
00168     {
00169       template<typename _ForwardIterator, typename _Tp>
00170         static void
00171         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
00172                       const _Tp& __x)
00173         { std::fill(__first, __last, __x); }
00174     };
00175 
00176   /**
00177    *  @brief Copies the value x into the range [first,last).
00178    *  @param  __first  An input iterator.
00179    *  @param  __last   An input iterator.
00180    *  @param  __x      The source value.
00181    *  @return   Nothing.
00182    *
00183    *  Like fill(), but does not require an initialized output range.
00184   */
00185   template<typename _ForwardIterator, typename _Tp>
00186     inline void
00187     uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
00188                        const _Tp& __x)
00189     {
00190       typedef typename iterator_traits<_ForwardIterator>::value_type
00191         _ValueType;
00192 #if __cplusplus < 201103L
00193       const bool __assignable = true;
00194 #else
00195       // Trivial types can have deleted copy constructor, but the std::fill
00196       // optimization that uses memmove would happily "copy" them anyway.
00197       static_assert(is_constructible<_ValueType, const _Tp&>::value,
00198           "result type must be constructible from input type");
00199 
00200       // Trivial types can have deleted assignment, so using std::fill
00201       // would be ill-formed. Require assignability before using std::fill:
00202       const bool __assignable = is_copy_assignable<_ValueType>::value;
00203 #endif
00204 
00205       std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>::
00206         __uninit_fill(__first, __last, __x);
00207     }
00208 
00209 
00210   template<bool _TrivialValueType>
00211     struct __uninitialized_fill_n
00212     {
00213       template<typename _ForwardIterator, typename _Size, typename _Tp>
00214         static _ForwardIterator
00215         __uninit_fill_n(_ForwardIterator __first, _Size __n,
00216                         const _Tp& __x)
00217         {
00218           _ForwardIterator __cur = __first;
00219           __try
00220             {
00221               for (; __n > 0; --__n, (void) ++__cur)
00222                 std::_Construct(std::__addressof(*__cur), __x);
00223               return __cur;
00224             }
00225           __catch(...)
00226             {
00227               std::_Destroy(__first, __cur);
00228               __throw_exception_again;
00229             }
00230         }
00231     };
00232 
00233   template<>
00234     struct __uninitialized_fill_n<true>
00235     {
00236       template<typename _ForwardIterator, typename _Size, typename _Tp>
00237         static _ForwardIterator
00238         __uninit_fill_n(_ForwardIterator __first, _Size __n,
00239                         const _Tp& __x)
00240         { return std::fill_n(__first, __n, __x); }
00241     };
00242 
00243    // _GLIBCXX_RESOLVE_LIB_DEFECTS
00244    // DR 1339. uninitialized_fill_n should return the end of its range
00245   /**
00246    *  @brief Copies the value x into the range [first,first+n).
00247    *  @param  __first  An input iterator.
00248    *  @param  __n      The number of copies to make.
00249    *  @param  __x      The source value.
00250    *  @return   Nothing.
00251    *
00252    *  Like fill_n(), but does not require an initialized output range.
00253   */
00254   template<typename _ForwardIterator, typename _Size, typename _Tp>
00255     inline _ForwardIterator
00256     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
00257     {
00258       typedef typename iterator_traits<_ForwardIterator>::value_type
00259         _ValueType;
00260 #if __cplusplus < 201103L
00261       const bool __assignable = true;
00262 #else
00263       // Trivial types can have deleted copy constructor, but the std::fill
00264       // optimization that uses memmove would happily "copy" them anyway.
00265       static_assert(is_constructible<_ValueType, const _Tp&>::value,
00266           "result type must be constructible from input type");
00267 
00268       // Trivial types can have deleted assignment, so using std::fill
00269       // would be ill-formed. Require assignability before using std::fill:
00270       const bool __assignable = is_copy_assignable<_ValueType>::value;
00271 #endif
00272       return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
00273         __uninit_fill_n(__first, __n, __x);
00274     }
00275 
00276   // Extensions: versions of uninitialized_copy, uninitialized_fill,
00277   //  and uninitialized_fill_n that take an allocator parameter.
00278   //  We dispatch back to the standard versions when we're given the
00279   //  default allocator.  For nondefault allocators we do not use 
00280   //  any of the POD optimizations.
00281 
00282   template<typename _InputIterator, typename _ForwardIterator,
00283            typename _Allocator>
00284     _ForwardIterator
00285     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
00286                            _ForwardIterator __result, _Allocator& __alloc)
00287     {
00288       _ForwardIterator __cur = __result;
00289       __try
00290         {
00291           typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00292           for (; __first != __last; ++__first, (void)++__cur)
00293             __traits::construct(__alloc, std::__addressof(*__cur), *__first);
00294           return __cur;
00295         }
00296       __catch(...)
00297         {
00298           std::_Destroy(__result, __cur, __alloc);
00299           __throw_exception_again;
00300         }
00301     }
00302 
00303   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
00304     inline _ForwardIterator
00305     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
00306                            _ForwardIterator __result, allocator<_Tp>&)
00307     { return std::uninitialized_copy(__first, __last, __result); }
00308 
00309   template<typename _InputIterator, typename _ForwardIterator,
00310            typename _Allocator>
00311     inline _ForwardIterator
00312     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
00313                            _ForwardIterator __result, _Allocator& __alloc)
00314     {
00315       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
00316                                          _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
00317                                          __result, __alloc);
00318     }
00319 
00320   template<typename _InputIterator, typename _ForwardIterator,
00321            typename _Allocator>
00322     inline _ForwardIterator
00323     __uninitialized_move_if_noexcept_a(_InputIterator __first,
00324                                        _InputIterator __last,
00325                                        _ForwardIterator __result,
00326                                        _Allocator& __alloc)
00327     {
00328       return std::__uninitialized_copy_a
00329         (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
00330          _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
00331     }
00332 
00333   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
00334     void
00335     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
00336                            const _Tp& __x, _Allocator& __alloc)
00337     {
00338       _ForwardIterator __cur = __first;
00339       __try
00340         {
00341           typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00342           for (; __cur != __last; ++__cur)
00343             __traits::construct(__alloc, std::__addressof(*__cur), __x);
00344         }
00345       __catch(...)
00346         {
00347           std::_Destroy(__first, __cur, __alloc);
00348           __throw_exception_again;
00349         }
00350     }
00351 
00352   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
00353     inline void
00354     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
00355                            const _Tp& __x, allocator<_Tp2>&)
00356     { std::uninitialized_fill(__first, __last, __x); }
00357 
00358   template<typename _ForwardIterator, typename _Size, typename _Tp,
00359            typename _Allocator>
00360     _ForwardIterator
00361     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
00362                              const _Tp& __x, _Allocator& __alloc)
00363     {
00364       _ForwardIterator __cur = __first;
00365       __try
00366         {
00367           typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00368           for (; __n > 0; --__n, (void) ++__cur)
00369             __traits::construct(__alloc, std::__addressof(*__cur), __x);
00370           return __cur;
00371         }
00372       __catch(...)
00373         {
00374           std::_Destroy(__first, __cur, __alloc);
00375           __throw_exception_again;
00376         }
00377     }
00378 
00379   template<typename _ForwardIterator, typename _Size, typename _Tp,
00380            typename _Tp2>
00381     inline _ForwardIterator
00382     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
00383                              const _Tp& __x, allocator<_Tp2>&)
00384     { return std::uninitialized_fill_n(__first, __n, __x); }
00385 
00386 
00387   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
00388   // __uninitialized_fill_move, __uninitialized_move_fill.
00389   // All of these algorithms take a user-supplied allocator, which is used
00390   // for construction and destruction.
00391 
00392   // __uninitialized_copy_move
00393   // Copies [first1, last1) into [result, result + (last1 - first1)), and
00394   //  move [first2, last2) into
00395   //  [result, result + (last1 - first1) + (last2 - first2)).
00396   template<typename _InputIterator1, typename _InputIterator2,
00397            typename _ForwardIterator, typename _Allocator>
00398     inline _ForwardIterator
00399     __uninitialized_copy_move(_InputIterator1 __first1,
00400                               _InputIterator1 __last1,
00401                               _InputIterator2 __first2,
00402                               _InputIterator2 __last2,
00403                               _ForwardIterator __result,
00404                               _Allocator& __alloc)
00405     {
00406       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
00407                                                            __result,
00408                                                            __alloc);
00409       __try
00410         {
00411           return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
00412         }
00413       __catch(...)
00414         {
00415           std::_Destroy(__result, __mid, __alloc);
00416           __throw_exception_again;
00417         }
00418     }
00419 
00420   // __uninitialized_move_copy
00421   // Moves [first1, last1) into [result, result + (last1 - first1)), and
00422   //  copies [first2, last2) into
00423   //  [result, result + (last1 - first1) + (last2 - first2)).
00424   template<typename _InputIterator1, typename _InputIterator2,
00425            typename _ForwardIterator, typename _Allocator>
00426     inline _ForwardIterator
00427     __uninitialized_move_copy(_InputIterator1 __first1,
00428                               _InputIterator1 __last1,
00429                               _InputIterator2 __first2,
00430                               _InputIterator2 __last2,
00431                               _ForwardIterator __result,
00432                               _Allocator& __alloc)
00433     {
00434       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
00435                                                            __result,
00436                                                            __alloc);
00437       __try
00438         {
00439           return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
00440         }
00441       __catch(...)
00442         {
00443           std::_Destroy(__result, __mid, __alloc);
00444           __throw_exception_again;
00445         }
00446     }
00447   
00448   // __uninitialized_fill_move
00449   // Fills [result, mid) with x, and moves [first, last) into
00450   //  [mid, mid + (last - first)).
00451   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
00452            typename _Allocator>
00453     inline _ForwardIterator
00454     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
00455                               const _Tp& __x, _InputIterator __first,
00456                               _InputIterator __last, _Allocator& __alloc)
00457     {
00458       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
00459       __try
00460         {
00461           return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
00462         }
00463       __catch(...)
00464         {
00465           std::_Destroy(__result, __mid, __alloc);
00466           __throw_exception_again;
00467         }
00468     }
00469 
00470   // __uninitialized_move_fill
00471   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
00472   //  fills [first2 + (last1 - first1), last2) with x.
00473   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
00474            typename _Allocator>
00475     inline void
00476     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
00477                               _ForwardIterator __first2,
00478                               _ForwardIterator __last2, const _Tp& __x,
00479                               _Allocator& __alloc)
00480     {
00481       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
00482                                                             __first2,
00483                                                             __alloc);
00484       __try
00485         {
00486           std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
00487         }
00488       __catch(...)
00489         {
00490           std::_Destroy(__first2, __mid2, __alloc);
00491           __throw_exception_again;
00492         }
00493     }
00494 
00495 #if __cplusplus >= 201103L
00496   // Extensions: __uninitialized_default, __uninitialized_default_n,
00497   // __uninitialized_default_a, __uninitialized_default_n_a.
00498 
00499   template<bool _TrivialValueType>
00500     struct __uninitialized_default_1
00501     {
00502       template<typename _ForwardIterator>
00503         static void
00504         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
00505         {
00506           _ForwardIterator __cur = __first;
00507           __try
00508             {
00509               for (; __cur != __last; ++__cur)
00510                 std::_Construct(std::__addressof(*__cur));
00511             }
00512           __catch(...)
00513             {
00514               std::_Destroy(__first, __cur);
00515               __throw_exception_again;
00516             }
00517         }
00518     };
00519 
00520   template<>
00521     struct __uninitialized_default_1<true>
00522     {
00523       template<typename _ForwardIterator>
00524         static void
00525         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
00526         {
00527           typedef typename iterator_traits<_ForwardIterator>::value_type
00528             _ValueType;
00529 
00530           std::fill(__first, __last, _ValueType());
00531         }
00532     };
00533 
00534   template<bool _TrivialValueType>
00535     struct __uninitialized_default_n_1
00536     {
00537       template<typename _ForwardIterator, typename _Size>
00538         static _ForwardIterator
00539         __uninit_default_n(_ForwardIterator __first, _Size __n)
00540         {
00541           _ForwardIterator __cur = __first;
00542           __try
00543             {
00544               for (; __n > 0; --__n, (void) ++__cur)
00545                 std::_Construct(std::__addressof(*__cur));
00546               return __cur;
00547             }
00548           __catch(...)
00549             {
00550               std::_Destroy(__first, __cur);
00551               __throw_exception_again;
00552             }
00553         }
00554     };
00555 
00556   template<>
00557     struct __uninitialized_default_n_1<true>
00558     {
00559       template<typename _ForwardIterator, typename _Size>
00560         static _ForwardIterator
00561         __uninit_default_n(_ForwardIterator __first, _Size __n)
00562         {
00563           typedef typename iterator_traits<_ForwardIterator>::value_type
00564             _ValueType;
00565 
00566           return std::fill_n(__first, __n, _ValueType());
00567         }
00568     };
00569 
00570   // __uninitialized_default
00571   // Fills [first, last) with std::distance(first, last) default
00572   // constructed value_types(s).
00573   template<typename _ForwardIterator>
00574     inline void
00575     __uninitialized_default(_ForwardIterator __first,
00576                             _ForwardIterator __last)
00577     {
00578       typedef typename iterator_traits<_ForwardIterator>::value_type
00579         _ValueType;
00580       // trivial types can have deleted assignment
00581       const bool __assignable = is_copy_assignable<_ValueType>::value;
00582 
00583       std::__uninitialized_default_1<__is_trivial(_ValueType)
00584                                      && __assignable>::
00585         __uninit_default(__first, __last);
00586     }
00587 
00588   // __uninitialized_default_n
00589   // Fills [first, first + n) with n default constructed value_type(s).
00590   template<typename _ForwardIterator, typename _Size>
00591     inline _ForwardIterator
00592     __uninitialized_default_n(_ForwardIterator __first, _Size __n)
00593     {
00594       typedef typename iterator_traits<_ForwardIterator>::value_type
00595         _ValueType;
00596       // trivial types can have deleted assignment
00597       const bool __assignable = is_copy_assignable<_ValueType>::value;
00598 
00599       return __uninitialized_default_n_1<__is_trivial(_ValueType)
00600                                        && __assignable>::
00601         __uninit_default_n(__first, __n);
00602     }
00603 
00604 
00605   // __uninitialized_default_a
00606   // Fills [first, last) with std::distance(first, last) default
00607   // constructed value_types(s), constructed with the allocator alloc.
00608   template<typename _ForwardIterator, typename _Allocator>
00609     void
00610     __uninitialized_default_a(_ForwardIterator __first,
00611                               _ForwardIterator __last,
00612                               _Allocator& __alloc)
00613     {
00614       _ForwardIterator __cur = __first;
00615       __try
00616         {
00617           typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00618           for (; __cur != __last; ++__cur)
00619             __traits::construct(__alloc, std::__addressof(*__cur));
00620         }
00621       __catch(...)
00622         {
00623           std::_Destroy(__first, __cur, __alloc);
00624           __throw_exception_again;
00625         }
00626     }
00627 
00628   template<typename _ForwardIterator, typename _Tp>
00629     inline void
00630     __uninitialized_default_a(_ForwardIterator __first,
00631                               _ForwardIterator __last,
00632                               allocator<_Tp>&)
00633     { std::__uninitialized_default(__first, __last); }
00634 
00635 
00636   // __uninitialized_default_n_a
00637   // Fills [first, first + n) with n default constructed value_types(s),
00638   // constructed with the allocator alloc.
00639   template<typename _ForwardIterator, typename _Size, typename _Allocator>
00640     _ForwardIterator
00641     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
00642                                 _Allocator& __alloc)
00643     {
00644       _ForwardIterator __cur = __first;
00645       __try
00646         {
00647           typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00648           for (; __n > 0; --__n, (void) ++__cur)
00649             __traits::construct(__alloc, std::__addressof(*__cur));
00650           return __cur;
00651         }
00652       __catch(...)
00653         {
00654           std::_Destroy(__first, __cur, __alloc);
00655           __throw_exception_again;
00656         }
00657     }
00658 
00659   template<typename _ForwardIterator, typename _Size, typename _Tp>
00660     inline _ForwardIterator
00661     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
00662                                 allocator<_Tp>&)
00663     { return std::__uninitialized_default_n(__first, __n); }
00664 
00665   template<bool _TrivialValueType>
00666     struct __uninitialized_default_novalue_1
00667     {
00668       template<typename _ForwardIterator>
00669         static void
00670         __uninit_default_novalue(_ForwardIterator __first,
00671                                  _ForwardIterator __last)
00672         {
00673           _ForwardIterator __cur = __first;
00674           __try
00675             {
00676               for (; __cur != __last; ++__cur)
00677                 std::_Construct_novalue(std::__addressof(*__cur));
00678             }
00679           __catch(...)
00680             {
00681               std::_Destroy(__first, __cur);
00682               __throw_exception_again;
00683             }
00684         }
00685     };
00686 
00687   template<>
00688     struct __uninitialized_default_novalue_1<true>
00689     {
00690       template<typename _ForwardIterator>
00691         static void
00692         __uninit_default_novalue(_ForwardIterator __first,
00693                                  _ForwardIterator __last)
00694         {
00695         }
00696     };
00697 
00698   template<bool _TrivialValueType>
00699     struct __uninitialized_default_novalue_n_1
00700     {
00701       template<typename _ForwardIterator, typename _Size>
00702         static _ForwardIterator
00703         __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
00704         {
00705           _ForwardIterator __cur = __first;
00706           __try
00707             {
00708               for (; __n > 0; --__n, (void) ++__cur)
00709                 std::_Construct_novalue(std::__addressof(*__cur));
00710               return __cur;
00711             }
00712           __catch(...)
00713             {
00714               std::_Destroy(__first, __cur);
00715               __throw_exception_again;
00716             }
00717         }
00718     };
00719 
00720   template<>
00721     struct __uninitialized_default_novalue_n_1<true>
00722     {
00723       template<typename _ForwardIterator, typename _Size>
00724         static _ForwardIterator
00725         __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
00726         { return std::next(__first, __n); }
00727     };
00728 
00729   // __uninitialized_default_novalue
00730   // Fills [first, last) with std::distance(first, last) default-initialized
00731   // value_types(s).
00732   template<typename _ForwardIterator>
00733     inline void
00734     __uninitialized_default_novalue(_ForwardIterator __first,
00735                                     _ForwardIterator __last)
00736     {
00737       typedef typename iterator_traits<_ForwardIterator>::value_type
00738         _ValueType;
00739 
00740       std::__uninitialized_default_novalue_1<
00741         is_trivially_default_constructible<_ValueType>::value>::
00742         __uninit_default_novalue(__first, __last);
00743     }
00744 
00745   // __uninitialized_default_n
00746   // Fills [first, first + n) with n default-initialized value_type(s).
00747   template<typename _ForwardIterator, typename _Size>
00748     inline _ForwardIterator
00749     __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
00750     {
00751       typedef typename iterator_traits<_ForwardIterator>::value_type
00752         _ValueType;
00753 
00754       return __uninitialized_default_novalue_n_1<
00755         is_trivially_default_constructible<_ValueType>::value>::
00756         __uninit_default_novalue_n(__first, __n);
00757     }
00758 
00759   template<typename _InputIterator, typename _Size,
00760            typename _ForwardIterator>
00761     _ForwardIterator
00762     __uninitialized_copy_n(_InputIterator __first, _Size __n,
00763                            _ForwardIterator __result, input_iterator_tag)
00764     {
00765       _ForwardIterator __cur = __result;
00766       __try
00767         {
00768           for (; __n > 0; --__n, (void) ++__first, ++__cur)
00769             std::_Construct(std::__addressof(*__cur), *__first);
00770           return __cur;
00771         }
00772       __catch(...)
00773         {
00774           std::_Destroy(__result, __cur);
00775           __throw_exception_again;
00776         }
00777     }
00778 
00779   template<typename _RandomAccessIterator, typename _Size,
00780            typename _ForwardIterator>
00781     inline _ForwardIterator
00782     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
00783                            _ForwardIterator __result,
00784                            random_access_iterator_tag)
00785     { return std::uninitialized_copy(__first, __first + __n, __result); }
00786 
00787   template<typename _InputIterator, typename _Size,
00788            typename _ForwardIterator>
00789     pair<_InputIterator, _ForwardIterator>
00790     __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
00791                            _ForwardIterator __result, input_iterator_tag)
00792     {
00793       _ForwardIterator __cur = __result;
00794       __try
00795         {
00796           for (; __n > 0; --__n, (void) ++__first, ++__cur)
00797             std::_Construct(std::__addressof(*__cur), *__first);
00798           return {__first, __cur};
00799         }
00800       __catch(...)
00801         {
00802           std::_Destroy(__result, __cur);
00803           __throw_exception_again;
00804         }
00805     }
00806 
00807   template<typename _RandomAccessIterator, typename _Size,
00808            typename _ForwardIterator>
00809     inline pair<_RandomAccessIterator, _ForwardIterator>
00810     __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
00811                            _ForwardIterator __result,
00812                            random_access_iterator_tag)
00813     {
00814       auto __second_res = uninitialized_copy(__first, __first + __n, __result);
00815       auto __first_res = std::next(__first, __n);
00816       return {__first_res, __second_res};
00817     }
00818 
00819   /**
00820    *  @brief Copies the range [first,first+n) into result.
00821    *  @param  __first  An input iterator.
00822    *  @param  __n      The number of elements to copy.
00823    *  @param  __result An output iterator.
00824    *  @return  __result + __n
00825    *
00826    *  Like copy_n(), but does not require an initialized output range.
00827   */
00828   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
00829     inline _ForwardIterator
00830     uninitialized_copy_n(_InputIterator __first, _Size __n,
00831                          _ForwardIterator __result)
00832     { return std::__uninitialized_copy_n(__first, __n, __result,
00833                                          std::__iterator_category(__first)); }
00834 
00835   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
00836     inline pair<_InputIterator, _ForwardIterator>
00837     __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
00838                               _ForwardIterator __result)
00839     {
00840       return
00841         std::__uninitialized_copy_n_pair(__first, __n, __result,
00842                                          std::__iterator_category(__first));
00843     }
00844 
00845 #endif
00846 
00847 #if __cplusplus >= 201703L
00848 # define __cpp_lib_raw_memory_algorithms 201606L
00849 
00850   template <typename _ForwardIterator>
00851     inline void
00852     uninitialized_default_construct(_ForwardIterator __first,
00853                                     _ForwardIterator __last)
00854     {
00855       __uninitialized_default_novalue(__first, __last);
00856     }
00857 
00858   template <typename _ForwardIterator, typename _Size>
00859     inline _ForwardIterator
00860     uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
00861     {
00862       return __uninitialized_default_novalue_n(__first, __count);
00863     }
00864 
00865   template <typename _ForwardIterator>
00866     inline void
00867     uninitialized_value_construct(_ForwardIterator __first,
00868                                   _ForwardIterator __last)
00869     {
00870       return __uninitialized_default(__first, __last);
00871     }
00872 
00873   template <typename _ForwardIterator, typename _Size>
00874     inline _ForwardIterator
00875     uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
00876     {
00877       return __uninitialized_default_n(__first, __count);
00878     }
00879 
00880   template <typename _InputIterator, typename _ForwardIterator>
00881     inline _ForwardIterator
00882     uninitialized_move(_InputIterator __first, _InputIterator __last,
00883                        _ForwardIterator __result)
00884     {
00885       return std::uninitialized_copy
00886         (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
00887          _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
00888     }
00889 
00890   template <typename _InputIterator, typename _Size, typename _ForwardIterator>
00891     inline pair<_InputIterator, _ForwardIterator>
00892     uninitialized_move_n(_InputIterator __first, _Size __count,
00893                          _ForwardIterator __result)
00894     {
00895       auto __res = std::__uninitialized_copy_n_pair
00896         (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
00897          __count, __result);
00898       return {__res.first.base(), __res.second};
00899     }
00900 #endif // C++17
00901 
00902 #if __cplusplus >= 201103L
00903   template<typename _Tp, typename _Up, typename _Allocator>
00904     inline void
00905     __relocate_object_a(_Tp* __dest, _Up* __orig, _Allocator& __alloc)
00906     noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc,
00907                          __dest, std::move(*__orig)))
00908              && noexcept(std::allocator_traits<_Allocator>::destroy(
00909                             __alloc, std::__addressof(*__orig))))
00910     {
00911       typedef std::allocator_traits<_Allocator> __traits;
00912       __traits::construct(__alloc, __dest, std::move(*__orig));
00913       __traits::destroy(__alloc, std::__addressof(*__orig));
00914     }
00915 
00916   // This class may be specialized for specific types.
00917   // Also known as is_trivially_relocatable.
00918   template<typename _Tp, typename = void>
00919     struct __is_bitwise_relocatable
00920     : is_trivial<_Tp> { };
00921 
00922   template <typename _Tp, typename _Up>
00923     inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*>
00924     __relocate_a_1(_Tp* __first, _Tp* __last,
00925                    _Tp* __result, allocator<_Up>&) noexcept
00926     {
00927       ptrdiff_t __count = __last - __first;
00928       if (__count > 0)
00929         __builtin_memmove(__result, __first, __count * sizeof(_Tp));
00930       return __result + __count;
00931     }
00932 
00933   template <typename _InputIterator, typename _ForwardIterator,
00934             typename _Allocator>
00935     inline _ForwardIterator
00936     __relocate_a_1(_InputIterator __first, _InputIterator __last,
00937                    _ForwardIterator __result, _Allocator& __alloc)
00938     noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result),
00939                                                std::addressof(*__first),
00940                                                __alloc)))
00941     {
00942       typedef typename iterator_traits<_InputIterator>::value_type
00943         _ValueType;
00944       typedef typename iterator_traits<_ForwardIterator>::value_type
00945         _ValueType2;
00946       static_assert(std::is_same<_ValueType, _ValueType2>::value,
00947           "relocation is only possible for values of the same type");
00948       _ForwardIterator __cur = __result;
00949       for (; __first != __last; ++__first, (void)++__cur)
00950         std::__relocate_object_a(std::__addressof(*__cur),
00951                                  std::__addressof(*__first), __alloc);
00952       return __cur;
00953     }
00954 
00955   template <typename _InputIterator, typename _ForwardIterator,
00956             typename _Allocator>
00957     inline _ForwardIterator
00958     __relocate_a(_InputIterator __first, _InputIterator __last,
00959                  _ForwardIterator __result, _Allocator& __alloc)
00960     noexcept(noexcept(__relocate_a_1(std::__niter_base(__first),
00961                                      std::__niter_base(__last),
00962                                      std::__niter_base(__result), __alloc)))
00963     {
00964       return __relocate_a_1(std::__niter_base(__first),
00965                             std::__niter_base(__last),
00966                             std::__niter_base(__result), __alloc);
00967     }
00968 #endif
00969 
00970 _GLIBCXX_END_NAMESPACE_VERSION
00971 } // namespace
00972 
00973 #endif /* _STL_UNINITIALIZED_H */