libstdc++
stl_uninitialized.h
Go to the documentation of this file.
00001 // Raw memory manipulators -*- C++ -*-
00002 
00003 // Copyright (C) 2001-2018 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 assignment
00126       typedef typename iterator_traits<_InputIterator>::reference _RefType1;
00127       typedef typename iterator_traits<_ForwardIterator>::reference _RefType2;
00128       const bool __assignable = is_assignable<_RefType2, _RefType1>::value;
00129 #endif
00130 
00131       return std::__uninitialized_copy<__is_trivial(_ValueType1)
00132                                        && __is_trivial(_ValueType2)
00133                                        && __assignable>::
00134         __uninit_copy(__first, __last, __result);
00135     }
00136 
00137 
00138   template<bool _TrivialValueType>
00139     struct __uninitialized_fill
00140     {
00141       template<typename _ForwardIterator, typename _Tp>
00142         static void
00143         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
00144                       const _Tp& __x)
00145         {
00146           _ForwardIterator __cur = __first;
00147           __try
00148             {
00149               for (; __cur != __last; ++__cur)
00150                 std::_Construct(std::__addressof(*__cur), __x);
00151             }
00152           __catch(...)
00153             {
00154               std::_Destroy(__first, __cur);
00155               __throw_exception_again;
00156             }
00157         }
00158     };
00159 
00160   template<>
00161     struct __uninitialized_fill<true>
00162     {
00163       template<typename _ForwardIterator, typename _Tp>
00164         static void
00165         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
00166                       const _Tp& __x)
00167         { std::fill(__first, __last, __x); }
00168     };
00169 
00170   /**
00171    *  @brief Copies the value x into the range [first,last).
00172    *  @param  __first  An input iterator.
00173    *  @param  __last   An input iterator.
00174    *  @param  __x      The source value.
00175    *  @return   Nothing.
00176    *
00177    *  Like fill(), but does not require an initialized output range.
00178   */
00179   template<typename _ForwardIterator, typename _Tp>
00180     inline void
00181     uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
00182                        const _Tp& __x)
00183     {
00184       typedef typename iterator_traits<_ForwardIterator>::value_type
00185         _ValueType;
00186 #if __cplusplus < 201103L
00187       const bool __assignable = true;
00188 #else
00189       // trivial types can have deleted assignment
00190       const bool __assignable = is_copy_assignable<_ValueType>::value;
00191 #endif
00192 
00193       std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>::
00194         __uninit_fill(__first, __last, __x);
00195     }
00196 
00197 
00198   template<bool _TrivialValueType>
00199     struct __uninitialized_fill_n
00200     {
00201       template<typename _ForwardIterator, typename _Size, typename _Tp>
00202         static _ForwardIterator
00203         __uninit_fill_n(_ForwardIterator __first, _Size __n,
00204                         const _Tp& __x)
00205         {
00206           _ForwardIterator __cur = __first;
00207           __try
00208             {
00209               for (; __n > 0; --__n, (void) ++__cur)
00210                 std::_Construct(std::__addressof(*__cur), __x);
00211               return __cur;
00212             }
00213           __catch(...)
00214             {
00215               std::_Destroy(__first, __cur);
00216               __throw_exception_again;
00217             }
00218         }
00219     };
00220 
00221   template<>
00222     struct __uninitialized_fill_n<true>
00223     {
00224       template<typename _ForwardIterator, typename _Size, typename _Tp>
00225         static _ForwardIterator
00226         __uninit_fill_n(_ForwardIterator __first, _Size __n,
00227                         const _Tp& __x)
00228         { return std::fill_n(__first, __n, __x); }
00229     };
00230 
00231    // _GLIBCXX_RESOLVE_LIB_DEFECTS
00232    // DR 1339. uninitialized_fill_n should return the end of its range
00233   /**
00234    *  @brief Copies the value x into the range [first,first+n).
00235    *  @param  __first  An input iterator.
00236    *  @param  __n      The number of copies to make.
00237    *  @param  __x      The source value.
00238    *  @return   Nothing.
00239    *
00240    *  Like fill_n(), but does not require an initialized output range.
00241   */
00242   template<typename _ForwardIterator, typename _Size, typename _Tp>
00243     inline _ForwardIterator
00244     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
00245     {
00246       typedef typename iterator_traits<_ForwardIterator>::value_type
00247         _ValueType;
00248 #if __cplusplus < 201103L
00249       const bool __assignable = true;
00250 #else
00251       // trivial types can have deleted assignment
00252       const bool __assignable = is_copy_assignable<_ValueType>::value;
00253 #endif
00254       return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
00255         __uninit_fill_n(__first, __n, __x);
00256     }
00257 
00258   // Extensions: versions of uninitialized_copy, uninitialized_fill,
00259   //  and uninitialized_fill_n that take an allocator parameter.
00260   //  We dispatch back to the standard versions when we're given the
00261   //  default allocator.  For nondefault allocators we do not use 
00262   //  any of the POD optimizations.
00263 
00264   template<typename _InputIterator, typename _ForwardIterator,
00265            typename _Allocator>
00266     _ForwardIterator
00267     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
00268                            _ForwardIterator __result, _Allocator& __alloc)
00269     {
00270       _ForwardIterator __cur = __result;
00271       __try
00272         {
00273           typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00274           for (; __first != __last; ++__first, (void)++__cur)
00275             __traits::construct(__alloc, std::__addressof(*__cur), *__first);
00276           return __cur;
00277         }
00278       __catch(...)
00279         {
00280           std::_Destroy(__result, __cur, __alloc);
00281           __throw_exception_again;
00282         }
00283     }
00284 
00285   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
00286     inline _ForwardIterator
00287     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
00288                            _ForwardIterator __result, allocator<_Tp>&)
00289     { return std::uninitialized_copy(__first, __last, __result); }
00290 
00291   template<typename _InputIterator, typename _ForwardIterator,
00292            typename _Allocator>
00293     inline _ForwardIterator
00294     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
00295                            _ForwardIterator __result, _Allocator& __alloc)
00296     {
00297       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
00298                                          _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
00299                                          __result, __alloc);
00300     }
00301 
00302   template<typename _InputIterator, typename _ForwardIterator,
00303            typename _Allocator>
00304     inline _ForwardIterator
00305     __uninitialized_move_if_noexcept_a(_InputIterator __first,
00306                                        _InputIterator __last,
00307                                        _ForwardIterator __result,
00308                                        _Allocator& __alloc)
00309     {
00310       return std::__uninitialized_copy_a
00311         (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
00312          _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
00313     }
00314 
00315   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
00316     void
00317     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
00318                            const _Tp& __x, _Allocator& __alloc)
00319     {
00320       _ForwardIterator __cur = __first;
00321       __try
00322         {
00323           typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00324           for (; __cur != __last; ++__cur)
00325             __traits::construct(__alloc, std::__addressof(*__cur), __x);
00326         }
00327       __catch(...)
00328         {
00329           std::_Destroy(__first, __cur, __alloc);
00330           __throw_exception_again;
00331         }
00332     }
00333 
00334   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
00335     inline void
00336     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
00337                            const _Tp& __x, allocator<_Tp2>&)
00338     { std::uninitialized_fill(__first, __last, __x); }
00339 
00340   template<typename _ForwardIterator, typename _Size, typename _Tp,
00341            typename _Allocator>
00342     _ForwardIterator
00343     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
00344                              const _Tp& __x, _Allocator& __alloc)
00345     {
00346       _ForwardIterator __cur = __first;
00347       __try
00348         {
00349           typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00350           for (; __n > 0; --__n, (void) ++__cur)
00351             __traits::construct(__alloc, std::__addressof(*__cur), __x);
00352           return __cur;
00353         }
00354       __catch(...)
00355         {
00356           std::_Destroy(__first, __cur, __alloc);
00357           __throw_exception_again;
00358         }
00359     }
00360 
00361   template<typename _ForwardIterator, typename _Size, typename _Tp,
00362            typename _Tp2>
00363     inline _ForwardIterator
00364     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
00365                              const _Tp& __x, allocator<_Tp2>&)
00366     { return std::uninitialized_fill_n(__first, __n, __x); }
00367 
00368 
00369   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
00370   // __uninitialized_fill_move, __uninitialized_move_fill.
00371   // All of these algorithms take a user-supplied allocator, which is used
00372   // for construction and destruction.
00373 
00374   // __uninitialized_copy_move
00375   // Copies [first1, last1) into [result, result + (last1 - first1)), and
00376   //  move [first2, last2) into
00377   //  [result, result + (last1 - first1) + (last2 - first2)).
00378   template<typename _InputIterator1, typename _InputIterator2,
00379            typename _ForwardIterator, typename _Allocator>
00380     inline _ForwardIterator
00381     __uninitialized_copy_move(_InputIterator1 __first1,
00382                               _InputIterator1 __last1,
00383                               _InputIterator2 __first2,
00384                               _InputIterator2 __last2,
00385                               _ForwardIterator __result,
00386                               _Allocator& __alloc)
00387     {
00388       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
00389                                                            __result,
00390                                                            __alloc);
00391       __try
00392         {
00393           return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
00394         }
00395       __catch(...)
00396         {
00397           std::_Destroy(__result, __mid, __alloc);
00398           __throw_exception_again;
00399         }
00400     }
00401 
00402   // __uninitialized_move_copy
00403   // Moves [first1, last1) into [result, result + (last1 - first1)), and
00404   //  copies [first2, last2) into
00405   //  [result, result + (last1 - first1) + (last2 - first2)).
00406   template<typename _InputIterator1, typename _InputIterator2,
00407            typename _ForwardIterator, typename _Allocator>
00408     inline _ForwardIterator
00409     __uninitialized_move_copy(_InputIterator1 __first1,
00410                               _InputIterator1 __last1,
00411                               _InputIterator2 __first2,
00412                               _InputIterator2 __last2,
00413                               _ForwardIterator __result,
00414                               _Allocator& __alloc)
00415     {
00416       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
00417                                                            __result,
00418                                                            __alloc);
00419       __try
00420         {
00421           return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
00422         }
00423       __catch(...)
00424         {
00425           std::_Destroy(__result, __mid, __alloc);
00426           __throw_exception_again;
00427         }
00428     }
00429   
00430   // __uninitialized_fill_move
00431   // Fills [result, mid) with x, and moves [first, last) into
00432   //  [mid, mid + (last - first)).
00433   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
00434            typename _Allocator>
00435     inline _ForwardIterator
00436     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
00437                               const _Tp& __x, _InputIterator __first,
00438                               _InputIterator __last, _Allocator& __alloc)
00439     {
00440       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
00441       __try
00442         {
00443           return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
00444         }
00445       __catch(...)
00446         {
00447           std::_Destroy(__result, __mid, __alloc);
00448           __throw_exception_again;
00449         }
00450     }
00451 
00452   // __uninitialized_move_fill
00453   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
00454   //  fills [first2 + (last1 - first1), last2) with x.
00455   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
00456            typename _Allocator>
00457     inline void
00458     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
00459                               _ForwardIterator __first2,
00460                               _ForwardIterator __last2, const _Tp& __x,
00461                               _Allocator& __alloc)
00462     {
00463       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
00464                                                             __first2,
00465                                                             __alloc);
00466       __try
00467         {
00468           std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
00469         }
00470       __catch(...)
00471         {
00472           std::_Destroy(__first2, __mid2, __alloc);
00473           __throw_exception_again;
00474         }
00475     }
00476 
00477 #if __cplusplus >= 201103L
00478   // Extensions: __uninitialized_default, __uninitialized_default_n,
00479   // __uninitialized_default_a, __uninitialized_default_n_a.
00480 
00481   template<bool _TrivialValueType>
00482     struct __uninitialized_default_1
00483     {
00484       template<typename _ForwardIterator>
00485         static void
00486         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
00487         {
00488           _ForwardIterator __cur = __first;
00489           __try
00490             {
00491               for (; __cur != __last; ++__cur)
00492                 std::_Construct(std::__addressof(*__cur));
00493             }
00494           __catch(...)
00495             {
00496               std::_Destroy(__first, __cur);
00497               __throw_exception_again;
00498             }
00499         }
00500     };
00501 
00502   template<>
00503     struct __uninitialized_default_1<true>
00504     {
00505       template<typename _ForwardIterator>
00506         static void
00507         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
00508         {
00509           typedef typename iterator_traits<_ForwardIterator>::value_type
00510             _ValueType;
00511 
00512           std::fill(__first, __last, _ValueType());
00513         }
00514     };
00515 
00516   template<bool _TrivialValueType>
00517     struct __uninitialized_default_n_1
00518     {
00519       template<typename _ForwardIterator, typename _Size>
00520         static _ForwardIterator
00521         __uninit_default_n(_ForwardIterator __first, _Size __n)
00522         {
00523           _ForwardIterator __cur = __first;
00524           __try
00525             {
00526               for (; __n > 0; --__n, (void) ++__cur)
00527                 std::_Construct(std::__addressof(*__cur));
00528               return __cur;
00529             }
00530           __catch(...)
00531             {
00532               std::_Destroy(__first, __cur);
00533               __throw_exception_again;
00534             }
00535         }
00536     };
00537 
00538   template<>
00539     struct __uninitialized_default_n_1<true>
00540     {
00541       template<typename _ForwardIterator, typename _Size>
00542         static _ForwardIterator
00543         __uninit_default_n(_ForwardIterator __first, _Size __n)
00544         {
00545           typedef typename iterator_traits<_ForwardIterator>::value_type
00546             _ValueType;
00547 
00548           return std::fill_n(__first, __n, _ValueType());
00549         }
00550     };
00551 
00552   // __uninitialized_default
00553   // Fills [first, last) with std::distance(first, last) default
00554   // constructed value_types(s).
00555   template<typename _ForwardIterator>
00556     inline void
00557     __uninitialized_default(_ForwardIterator __first,
00558                             _ForwardIterator __last)
00559     {
00560       typedef typename iterator_traits<_ForwardIterator>::value_type
00561         _ValueType;
00562       // trivial types can have deleted assignment
00563       const bool __assignable = is_copy_assignable<_ValueType>::value;
00564 
00565       std::__uninitialized_default_1<__is_trivial(_ValueType)
00566                                      && __assignable>::
00567         __uninit_default(__first, __last);
00568     }
00569 
00570   // __uninitialized_default_n
00571   // Fills [first, first + n) with n default constructed value_type(s).
00572   template<typename _ForwardIterator, typename _Size>
00573     inline _ForwardIterator
00574     __uninitialized_default_n(_ForwardIterator __first, _Size __n)
00575     {
00576       typedef typename iterator_traits<_ForwardIterator>::value_type
00577         _ValueType;
00578       // trivial types can have deleted assignment
00579       const bool __assignable = is_copy_assignable<_ValueType>::value;
00580 
00581       return __uninitialized_default_n_1<__is_trivial(_ValueType)
00582                                        && __assignable>::
00583         __uninit_default_n(__first, __n);
00584     }
00585 
00586 
00587   // __uninitialized_default_a
00588   // Fills [first, last) with std::distance(first, last) default
00589   // constructed value_types(s), constructed with the allocator alloc.
00590   template<typename _ForwardIterator, typename _Allocator>
00591     void
00592     __uninitialized_default_a(_ForwardIterator __first,
00593                               _ForwardIterator __last,
00594                               _Allocator& __alloc)
00595     {
00596       _ForwardIterator __cur = __first;
00597       __try
00598         {
00599           typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00600           for (; __cur != __last; ++__cur)
00601             __traits::construct(__alloc, std::__addressof(*__cur));
00602         }
00603       __catch(...)
00604         {
00605           std::_Destroy(__first, __cur, __alloc);
00606           __throw_exception_again;
00607         }
00608     }
00609 
00610   template<typename _ForwardIterator, typename _Tp>
00611     inline void
00612     __uninitialized_default_a(_ForwardIterator __first,
00613                               _ForwardIterator __last,
00614                               allocator<_Tp>&)
00615     { std::__uninitialized_default(__first, __last); }
00616 
00617 
00618   // __uninitialized_default_n_a
00619   // Fills [first, first + n) with n default constructed value_types(s),
00620   // constructed with the allocator alloc.
00621   template<typename _ForwardIterator, typename _Size, typename _Allocator>
00622     _ForwardIterator
00623     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
00624                                 _Allocator& __alloc)
00625     {
00626       _ForwardIterator __cur = __first;
00627       __try
00628         {
00629           typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00630           for (; __n > 0; --__n, (void) ++__cur)
00631             __traits::construct(__alloc, std::__addressof(*__cur));
00632           return __cur;
00633         }
00634       __catch(...)
00635         {
00636           std::_Destroy(__first, __cur, __alloc);
00637           __throw_exception_again;
00638         }
00639     }
00640 
00641   template<typename _ForwardIterator, typename _Size, typename _Tp>
00642     inline _ForwardIterator
00643     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
00644                                 allocator<_Tp>&)
00645     { return std::__uninitialized_default_n(__first, __n); }
00646 
00647   template<bool _TrivialValueType>
00648     struct __uninitialized_default_novalue_1
00649     {
00650       template<typename _ForwardIterator>
00651         static void
00652         __uninit_default_novalue(_ForwardIterator __first,
00653                                  _ForwardIterator __last)
00654         {
00655           _ForwardIterator __cur = __first;
00656           __try
00657             {
00658               for (; __cur != __last; ++__cur)
00659                 std::_Construct_novalue(std::__addressof(*__cur));
00660             }
00661           __catch(...)
00662             {
00663               std::_Destroy(__first, __cur);
00664               __throw_exception_again;
00665             }
00666         }
00667     };
00668 
00669   template<>
00670     struct __uninitialized_default_novalue_1<true>
00671     {
00672       template<typename _ForwardIterator>
00673         static void
00674         __uninit_default_novalue(_ForwardIterator __first,
00675                                  _ForwardIterator __last)
00676         {
00677         }
00678     };
00679 
00680   template<bool _TrivialValueType>
00681     struct __uninitialized_default_novalue_n_1
00682     {
00683       template<typename _ForwardIterator, typename _Size>
00684         static _ForwardIterator
00685         __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
00686         {
00687           _ForwardIterator __cur = __first;
00688           __try
00689             {
00690               for (; __n > 0; --__n, (void) ++__cur)
00691                 std::_Construct_novalue(std::__addressof(*__cur));
00692               return __cur;
00693             }
00694           __catch(...)
00695             {
00696               std::_Destroy(__first, __cur);
00697               __throw_exception_again;
00698             }
00699         }
00700     };
00701 
00702   template<>
00703     struct __uninitialized_default_novalue_n_1<true>
00704     {
00705       template<typename _ForwardIterator, typename _Size>
00706         static _ForwardIterator
00707         __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
00708         { return std::next(__first, __n); }
00709     };
00710 
00711   // __uninitialized_default_novalue
00712   // Fills [first, last) with std::distance(first, last) default-initialized
00713   // value_types(s).
00714   template<typename _ForwardIterator>
00715     inline void
00716     __uninitialized_default_novalue(_ForwardIterator __first,
00717                                     _ForwardIterator __last)
00718     {
00719       typedef typename iterator_traits<_ForwardIterator>::value_type
00720         _ValueType;
00721 
00722       std::__uninitialized_default_novalue_1<
00723         is_trivially_default_constructible<_ValueType>::value>::
00724         __uninit_default_novalue(__first, __last);
00725     }
00726 
00727   // __uninitialized_default_n
00728   // Fills [first, first + n) with n default-initialized value_type(s).
00729   template<typename _ForwardIterator, typename _Size>
00730     inline _ForwardIterator
00731     __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
00732     {
00733       typedef typename iterator_traits<_ForwardIterator>::value_type
00734         _ValueType;
00735 
00736       return __uninitialized_default_novalue_n_1<
00737         is_trivially_default_constructible<_ValueType>::value>::
00738         __uninit_default_novalue_n(__first, __n);
00739     }
00740 
00741   template<typename _InputIterator, typename _Size,
00742            typename _ForwardIterator>
00743     _ForwardIterator
00744     __uninitialized_copy_n(_InputIterator __first, _Size __n,
00745                            _ForwardIterator __result, input_iterator_tag)
00746     {
00747       _ForwardIterator __cur = __result;
00748       __try
00749         {
00750           for (; __n > 0; --__n, (void) ++__first, ++__cur)
00751             std::_Construct(std::__addressof(*__cur), *__first);
00752           return __cur;
00753         }
00754       __catch(...)
00755         {
00756           std::_Destroy(__result, __cur);
00757           __throw_exception_again;
00758         }
00759     }
00760 
00761   template<typename _RandomAccessIterator, typename _Size,
00762            typename _ForwardIterator>
00763     inline _ForwardIterator
00764     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
00765                            _ForwardIterator __result,
00766                            random_access_iterator_tag)
00767     { return std::uninitialized_copy(__first, __first + __n, __result); }
00768 
00769   template<typename _InputIterator, typename _Size,
00770            typename _ForwardIterator>
00771     pair<_InputIterator, _ForwardIterator>
00772     __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
00773                            _ForwardIterator __result, input_iterator_tag)
00774     {
00775       _ForwardIterator __cur = __result;
00776       __try
00777         {
00778           for (; __n > 0; --__n, (void) ++__first, ++__cur)
00779             std::_Construct(std::__addressof(*__cur), *__first);
00780           return {__first, __cur};
00781         }
00782       __catch(...)
00783         {
00784           std::_Destroy(__result, __cur);
00785           __throw_exception_again;
00786         }
00787     }
00788 
00789   template<typename _RandomAccessIterator, typename _Size,
00790            typename _ForwardIterator>
00791     inline pair<_RandomAccessIterator, _ForwardIterator>
00792     __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
00793                            _ForwardIterator __result,
00794                            random_access_iterator_tag)
00795     {
00796       auto __second_res = uninitialized_copy(__first, __first + __n, __result);
00797       auto __first_res = std::next(__first, __n);
00798       return {__first_res, __second_res};
00799     }
00800 
00801   /**
00802    *  @brief Copies the range [first,first+n) into result.
00803    *  @param  __first  An input iterator.
00804    *  @param  __n      The number of elements to copy.
00805    *  @param  __result An output iterator.
00806    *  @return  __result + __n
00807    *
00808    *  Like copy_n(), but does not require an initialized output range.
00809   */
00810   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
00811     inline _ForwardIterator
00812     uninitialized_copy_n(_InputIterator __first, _Size __n,
00813                          _ForwardIterator __result)
00814     { return std::__uninitialized_copy_n(__first, __n, __result,
00815                                          std::__iterator_category(__first)); }
00816 
00817   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
00818     inline pair<_InputIterator, _ForwardIterator>
00819     __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
00820                               _ForwardIterator __result)
00821     {
00822       return
00823         std::__uninitialized_copy_n_pair(__first, __n, __result,
00824                                          std::__iterator_category(__first));
00825     }
00826 
00827 #endif
00828 
00829 #if __cplusplus > 201402L
00830   template <typename _ForwardIterator>
00831     inline void
00832     uninitialized_default_construct(_ForwardIterator __first,
00833                                     _ForwardIterator __last)
00834     {
00835       __uninitialized_default_novalue(__first, __last);
00836     }
00837 
00838   template <typename _ForwardIterator, typename _Size>
00839     inline _ForwardIterator
00840     uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
00841     {
00842       return __uninitialized_default_novalue_n(__first, __count);
00843     }
00844 
00845   template <typename _ForwardIterator>
00846     inline void
00847     uninitialized_value_construct(_ForwardIterator __first,
00848                                   _ForwardIterator __last)
00849     {
00850       return __uninitialized_default(__first, __last);
00851     }
00852 
00853   template <typename _ForwardIterator, typename _Size>
00854     inline _ForwardIterator
00855     uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
00856     {
00857       return __uninitialized_default_n(__first, __count);
00858     }
00859 
00860   template <typename _InputIterator, typename _ForwardIterator>
00861     inline _ForwardIterator
00862     uninitialized_move(_InputIterator __first, _InputIterator __last,
00863                        _ForwardIterator __result)
00864     {
00865       return std::uninitialized_copy
00866         (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
00867          _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
00868     }
00869 
00870   template <typename _InputIterator, typename _Size, typename _ForwardIterator>
00871     inline pair<_InputIterator, _ForwardIterator>
00872     uninitialized_move_n(_InputIterator __first, _Size __count,
00873                          _ForwardIterator __result)
00874     {
00875       auto __res = std::__uninitialized_copy_n_pair
00876         (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
00877          __count, __result);
00878       return {__res.first.base(), __res.second};
00879     }
00880 #endif
00881 
00882 _GLIBCXX_END_NAMESPACE_VERSION
00883 } // namespace
00884 
00885 #endif /* _STL_UNINITIALIZED_H */