Home | History | Annotate | Download | only in bits
      1 // Raw memory manipulators -*- C++ -*-
      2 
      3 // Copyright (C) 2001-2014 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 namespace std _GLIBCXX_VISIBILITY(default)
     60 {
     61 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     62 
     63   template<bool _TrivialValueTypes>
     64     struct __uninitialized_copy
     65     {
     66       template<typename _InputIterator, typename _ForwardIterator>
     67         static _ForwardIterator
     68         __uninit_copy(_InputIterator __first, _InputIterator __last,
     69 		      _ForwardIterator __result)
     70         {
     71 	  _ForwardIterator __cur = __result;
     72 	  __try
     73 	    {
     74 	      for (; __first != __last; ++__first, ++__cur)
     75 		std::_Construct(std::__addressof(*__cur), *__first);
     76 	      return __cur;
     77 	    }
     78 	  __catch(...)
     79 	    {
     80 	      std::_Destroy(__result, __cur);
     81 	      __throw_exception_again;
     82 	    }
     83 	}
     84     };
     85 
     86   template<>
     87     struct __uninitialized_copy<true>
     88     {
     89       template<typename _InputIterator, typename _ForwardIterator>
     90         static _ForwardIterator
     91         __uninit_copy(_InputIterator __first, _InputIterator __last,
     92 		      _ForwardIterator __result)
     93         { return std::copy(__first, __last, __result); }
     94     };
     95 
     96   /**
     97    *  @brief Copies the range [first,last) into result.
     98    *  @param  __first  An input iterator.
     99    *  @param  __last   An input iterator.
    100    *  @param  __result An output iterator.
    101    *  @return   __result + (__first - __last)
    102    *
    103    *  Like copy(), but does not require an initialized output range.
    104   */
    105   template<typename _InputIterator, typename _ForwardIterator>
    106     inline _ForwardIterator
    107     uninitialized_copy(_InputIterator __first, _InputIterator __last,
    108 		       _ForwardIterator __result)
    109     {
    110       typedef typename iterator_traits<_InputIterator>::value_type
    111 	_ValueType1;
    112       typedef typename iterator_traits<_ForwardIterator>::value_type
    113 	_ValueType2;
    114 #if __cplusplus < 201103L
    115       const bool __assignable = true;
    116 #else
    117       // trivial types can have deleted assignment
    118       typedef typename iterator_traits<_InputIterator>::reference _RefType;
    119       const bool __assignable = is_assignable<_ValueType1, _RefType>::value;
    120 #endif
    121 
    122       return std::__uninitialized_copy<__is_trivial(_ValueType1)
    123 				       && __is_trivial(_ValueType2)
    124 				       && __assignable>::
    125 	__uninit_copy(__first, __last, __result);
    126     }
    127 
    128 
    129   template<bool _TrivialValueType>
    130     struct __uninitialized_fill
    131     {
    132       template<typename _ForwardIterator, typename _Tp>
    133         static void
    134         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
    135 		      const _Tp& __x)
    136         {
    137 	  _ForwardIterator __cur = __first;
    138 	  __try
    139 	    {
    140 	      for (; __cur != __last; ++__cur)
    141 		std::_Construct(std::__addressof(*__cur), __x);
    142 	    }
    143 	  __catch(...)
    144 	    {
    145 	      std::_Destroy(__first, __cur);
    146 	      __throw_exception_again;
    147 	    }
    148 	}
    149     };
    150 
    151   template<>
    152     struct __uninitialized_fill<true>
    153     {
    154       template<typename _ForwardIterator, typename _Tp>
    155         static void
    156         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
    157 		      const _Tp& __x)
    158         { std::fill(__first, __last, __x); }
    159     };
    160 
    161   /**
    162    *  @brief Copies the value x into the range [first,last).
    163    *  @param  __first  An input iterator.
    164    *  @param  __last   An input iterator.
    165    *  @param  __x      The source value.
    166    *  @return   Nothing.
    167    *
    168    *  Like fill(), but does not require an initialized output range.
    169   */
    170   template<typename _ForwardIterator, typename _Tp>
    171     inline void
    172     uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
    173 		       const _Tp& __x)
    174     {
    175       typedef typename iterator_traits<_ForwardIterator>::value_type
    176 	_ValueType;
    177 #if __cplusplus < 201103L
    178       const bool __assignable = true;
    179 #else
    180       // trivial types can have deleted assignment
    181       const bool __assignable = is_copy_assignable<_ValueType>::value;
    182 #endif
    183 
    184       std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>::
    185 	__uninit_fill(__first, __last, __x);
    186     }
    187 
    188 
    189   template<bool _TrivialValueType>
    190     struct __uninitialized_fill_n
    191     {
    192       template<typename _ForwardIterator, typename _Size, typename _Tp>
    193         static void
    194         __uninit_fill_n(_ForwardIterator __first, _Size __n,
    195 			const _Tp& __x)
    196         {
    197 	  _ForwardIterator __cur = __first;
    198 	  __try
    199 	    {
    200 	      for (; __n > 0; --__n, ++__cur)
    201 		std::_Construct(std::__addressof(*__cur), __x);
    202 	    }
    203 	  __catch(...)
    204 	    {
    205 	      std::_Destroy(__first, __cur);
    206 	      __throw_exception_again;
    207 	    }
    208 	}
    209     };
    210 
    211   template<>
    212     struct __uninitialized_fill_n<true>
    213     {
    214       template<typename _ForwardIterator, typename _Size, typename _Tp>
    215         static void
    216         __uninit_fill_n(_ForwardIterator __first, _Size __n,
    217 			const _Tp& __x)
    218         { std::fill_n(__first, __n, __x); }
    219     };
    220 
    221   /**
    222    *  @brief Copies the value x into the range [first,first+n).
    223    *  @param  __first  An input iterator.
    224    *  @param  __n      The number of copies to make.
    225    *  @param  __x      The source value.
    226    *  @return   Nothing.
    227    *
    228    *  Like fill_n(), but does not require an initialized output range.
    229   */
    230   template<typename _ForwardIterator, typename _Size, typename _Tp>
    231     inline void
    232     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
    233     {
    234       typedef typename iterator_traits<_ForwardIterator>::value_type
    235 	_ValueType;
    236 #if __cplusplus < 201103L
    237       const bool __assignable = true;
    238 #else
    239       // trivial types can have deleted assignment
    240       const bool __assignable = is_copy_assignable<_ValueType>::value;
    241 #endif
    242 
    243       std::__uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
    244 	__uninit_fill_n(__first, __n, __x);
    245     }
    246 
    247   // Extensions: versions of uninitialized_copy, uninitialized_fill,
    248   //  and uninitialized_fill_n that take an allocator parameter.
    249   //  We dispatch back to the standard versions when we're given the
    250   //  default allocator.  For nondefault allocators we do not use
    251   //  any of the POD optimizations.
    252 
    253   template<typename _InputIterator, typename _ForwardIterator,
    254 	   typename _Allocator>
    255     _ForwardIterator
    256     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
    257 			   _ForwardIterator __result, _Allocator& __alloc)
    258     {
    259       _ForwardIterator __cur = __result;
    260       __try
    261 	{
    262 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
    263 	  for (; __first != __last; ++__first, ++__cur)
    264 	    __traits::construct(__alloc, std::__addressof(*__cur), *__first);
    265 	  return __cur;
    266 	}
    267       __catch(...)
    268 	{
    269 	  std::_Destroy(__result, __cur, __alloc);
    270 	  __throw_exception_again;
    271 	}
    272     }
    273 
    274   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
    275     inline _ForwardIterator
    276     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
    277 			   _ForwardIterator __result, allocator<_Tp>&)
    278     { return std::uninitialized_copy(__first, __last, __result); }
    279 
    280   template<typename _InputIterator, typename _ForwardIterator,
    281 	   typename _Allocator>
    282     inline _ForwardIterator
    283     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
    284 			   _ForwardIterator __result, _Allocator& __alloc)
    285     {
    286       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
    287 					 _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
    288 					 __result, __alloc);
    289     }
    290 
    291   template<typename _InputIterator, typename _ForwardIterator,
    292 	   typename _Allocator>
    293     inline _ForwardIterator
    294     __uninitialized_move_if_noexcept_a(_InputIterator __first,
    295 				       _InputIterator __last,
    296 				       _ForwardIterator __result,
    297 				       _Allocator& __alloc)
    298     {
    299       return std::__uninitialized_copy_a
    300 	(_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
    301 	 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
    302     }
    303 
    304   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
    305     void
    306     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
    307 			   const _Tp& __x, _Allocator& __alloc)
    308     {
    309       _ForwardIterator __cur = __first;
    310       __try
    311 	{
    312 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
    313 	  for (; __cur != __last; ++__cur)
    314 	    __traits::construct(__alloc, std::__addressof(*__cur), __x);
    315 	}
    316       __catch(...)
    317 	{
    318 	  std::_Destroy(__first, __cur, __alloc);
    319 	  __throw_exception_again;
    320 	}
    321     }
    322 
    323   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
    324     inline void
    325     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
    326 			   const _Tp& __x, allocator<_Tp2>&)
    327     { std::uninitialized_fill(__first, __last, __x); }
    328 
    329   template<typename _ForwardIterator, typename _Size, typename _Tp,
    330 	   typename _Allocator>
    331     void
    332     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
    333 			     const _Tp& __x, _Allocator& __alloc)
    334     {
    335       _ForwardIterator __cur = __first;
    336       __try
    337 	{
    338 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
    339 	  for (; __n > 0; --__n, ++__cur)
    340 	    __traits::construct(__alloc, std::__addressof(*__cur), __x);
    341 	}
    342       __catch(...)
    343 	{
    344 	  std::_Destroy(__first, __cur, __alloc);
    345 	  __throw_exception_again;
    346 	}
    347     }
    348 
    349   template<typename _ForwardIterator, typename _Size, typename _Tp,
    350 	   typename _Tp2>
    351     inline void
    352     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
    353 			     const _Tp& __x, allocator<_Tp2>&)
    354     { std::uninitialized_fill_n(__first, __n, __x); }
    355 
    356 
    357   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
    358   // __uninitialized_fill_move, __uninitialized_move_fill.
    359   // All of these algorithms take a user-supplied allocator, which is used
    360   // for construction and destruction.
    361 
    362   // __uninitialized_copy_move
    363   // Copies [first1, last1) into [result, result + (last1 - first1)), and
    364   //  move [first2, last2) into
    365   //  [result, result + (last1 - first1) + (last2 - first2)).
    366   template<typename _InputIterator1, typename _InputIterator2,
    367 	   typename _ForwardIterator, typename _Allocator>
    368     inline _ForwardIterator
    369     __uninitialized_copy_move(_InputIterator1 __first1,
    370 			      _InputIterator1 __last1,
    371 			      _InputIterator2 __first2,
    372 			      _InputIterator2 __last2,
    373 			      _ForwardIterator __result,
    374 			      _Allocator& __alloc)
    375     {
    376       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
    377 							   __result,
    378 							   __alloc);
    379       __try
    380 	{
    381 	  return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
    382 	}
    383       __catch(...)
    384 	{
    385 	  std::_Destroy(__result, __mid, __alloc);
    386 	  __throw_exception_again;
    387 	}
    388     }
    389 
    390   // __uninitialized_move_copy
    391   // Moves [first1, last1) into [result, result + (last1 - first1)), and
    392   //  copies [first2, last2) into
    393   //  [result, result + (last1 - first1) + (last2 - first2)).
    394   template<typename _InputIterator1, typename _InputIterator2,
    395 	   typename _ForwardIterator, typename _Allocator>
    396     inline _ForwardIterator
    397     __uninitialized_move_copy(_InputIterator1 __first1,
    398 			      _InputIterator1 __last1,
    399 			      _InputIterator2 __first2,
    400 			      _InputIterator2 __last2,
    401 			      _ForwardIterator __result,
    402 			      _Allocator& __alloc)
    403     {
    404       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
    405 							   __result,
    406 							   __alloc);
    407       __try
    408 	{
    409 	  return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
    410 	}
    411       __catch(...)
    412 	{
    413 	  std::_Destroy(__result, __mid, __alloc);
    414 	  __throw_exception_again;
    415 	}
    416     }
    417 
    418   // __uninitialized_fill_move
    419   // Fills [result, mid) with x, and moves [first, last) into
    420   //  [mid, mid + (last - first)).
    421   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
    422 	   typename _Allocator>
    423     inline _ForwardIterator
    424     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
    425 			      const _Tp& __x, _InputIterator __first,
    426 			      _InputIterator __last, _Allocator& __alloc)
    427     {
    428       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
    429       __try
    430 	{
    431 	  return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
    432 	}
    433       __catch(...)
    434 	{
    435 	  std::_Destroy(__result, __mid, __alloc);
    436 	  __throw_exception_again;
    437 	}
    438     }
    439 
    440   // __uninitialized_move_fill
    441   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
    442   //  fills [first2 + (last1 - first1), last2) with x.
    443   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
    444 	   typename _Allocator>
    445     inline void
    446     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
    447 			      _ForwardIterator __first2,
    448 			      _ForwardIterator __last2, const _Tp& __x,
    449 			      _Allocator& __alloc)
    450     {
    451       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
    452 							    __first2,
    453 							    __alloc);
    454       __try
    455 	{
    456 	  std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
    457 	}
    458       __catch(...)
    459 	{
    460 	  std::_Destroy(__first2, __mid2, __alloc);
    461 	  __throw_exception_again;
    462 	}
    463     }
    464 
    465 #if __cplusplus >= 201103L
    466   // Extensions: __uninitialized_default, __uninitialized_default_n,
    467   // __uninitialized_default_a, __uninitialized_default_n_a.
    468 
    469   template<bool _TrivialValueType>
    470     struct __uninitialized_default_1
    471     {
    472       template<typename _ForwardIterator>
    473         static void
    474         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
    475         {
    476 	  _ForwardIterator __cur = __first;
    477 	  __try
    478 	    {
    479 	      for (; __cur != __last; ++__cur)
    480 		std::_Construct(std::__addressof(*__cur));
    481 	    }
    482 	  __catch(...)
    483 	    {
    484 	      std::_Destroy(__first, __cur);
    485 	      __throw_exception_again;
    486 	    }
    487 	}
    488     };
    489 
    490   template<>
    491     struct __uninitialized_default_1<true>
    492     {
    493       template<typename _ForwardIterator>
    494         static void
    495         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
    496         {
    497 	  typedef typename iterator_traits<_ForwardIterator>::value_type
    498 	    _ValueType;
    499 
    500 	  std::fill(__first, __last, _ValueType());
    501 	}
    502     };
    503 
    504   template<bool _TrivialValueType>
    505     struct __uninitialized_default_n_1
    506     {
    507       template<typename _ForwardIterator, typename _Size>
    508         static void
    509         __uninit_default_n(_ForwardIterator __first, _Size __n)
    510         {
    511 	  _ForwardIterator __cur = __first;
    512 	  __try
    513 	    {
    514 	      for (; __n > 0; --__n, ++__cur)
    515 		std::_Construct(std::__addressof(*__cur));
    516 	    }
    517 	  __catch(...)
    518 	    {
    519 	      std::_Destroy(__first, __cur);
    520 	      __throw_exception_again;
    521 	    }
    522 	}
    523     };
    524 
    525   template<>
    526     struct __uninitialized_default_n_1<true>
    527     {
    528       template<typename _ForwardIterator, typename _Size>
    529         static void
    530         __uninit_default_n(_ForwardIterator __first, _Size __n)
    531         {
    532 	  typedef typename iterator_traits<_ForwardIterator>::value_type
    533 	    _ValueType;
    534 
    535 	  std::fill_n(__first, __n, _ValueType());
    536 	}
    537     };
    538 
    539   // __uninitialized_default
    540   // Fills [first, last) with std::distance(first, last) default
    541   // constructed value_types(s).
    542   template<typename _ForwardIterator>
    543     inline void
    544     __uninitialized_default(_ForwardIterator __first,
    545 			    _ForwardIterator __last)
    546     {
    547       typedef typename iterator_traits<_ForwardIterator>::value_type
    548 	_ValueType;
    549       // trivial types can have deleted assignment
    550       const bool __assignable = is_copy_assignable<_ValueType>::value;
    551 
    552       std::__uninitialized_default_1<__is_trivial(_ValueType)
    553 				     && __assignable>::
    554 	__uninit_default(__first, __last);
    555     }
    556 
    557   // __uninitialized_default_n
    558   // Fills [first, first + n) with n default constructed value_type(s).
    559   template<typename _ForwardIterator, typename _Size>
    560     inline void
    561     __uninitialized_default_n(_ForwardIterator __first, _Size __n)
    562     {
    563       typedef typename iterator_traits<_ForwardIterator>::value_type
    564 	_ValueType;
    565       // trivial types can have deleted assignment
    566       const bool __assignable = is_copy_assignable<_ValueType>::value;
    567 
    568       std::__uninitialized_default_n_1<__is_trivial(_ValueType)
    569 				       && __assignable>::
    570 	__uninit_default_n(__first, __n);
    571     }
    572 
    573 
    574   // __uninitialized_default_a
    575   // Fills [first, last) with std::distance(first, last) default
    576   // constructed value_types(s), constructed with the allocator alloc.
    577   template<typename _ForwardIterator, typename _Allocator>
    578     void
    579     __uninitialized_default_a(_ForwardIterator __first,
    580 			      _ForwardIterator __last,
    581 			      _Allocator& __alloc)
    582     {
    583       _ForwardIterator __cur = __first;
    584       __try
    585 	{
    586 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
    587 	  for (; __cur != __last; ++__cur)
    588 	    __traits::construct(__alloc, std::__addressof(*__cur));
    589 	}
    590       __catch(...)
    591 	{
    592 	  std::_Destroy(__first, __cur, __alloc);
    593 	  __throw_exception_again;
    594 	}
    595     }
    596 
    597   template<typename _ForwardIterator, typename _Tp>
    598     inline void
    599     __uninitialized_default_a(_ForwardIterator __first,
    600 			      _ForwardIterator __last,
    601 			      allocator<_Tp>&)
    602     { std::__uninitialized_default(__first, __last); }
    603 
    604 
    605   // __uninitialized_default_n_a
    606   // Fills [first, first + n) with n default constructed value_types(s),
    607   // constructed with the allocator alloc.
    608   template<typename _ForwardIterator, typename _Size, typename _Allocator>
    609     void
    610     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
    611 				_Allocator& __alloc)
    612     {
    613       _ForwardIterator __cur = __first;
    614       __try
    615 	{
    616 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
    617 	  for (; __n > 0; --__n, ++__cur)
    618 	    __traits::construct(__alloc, std::__addressof(*__cur));
    619 	}
    620       __catch(...)
    621 	{
    622 	  std::_Destroy(__first, __cur, __alloc);
    623 	  __throw_exception_again;
    624 	}
    625     }
    626 
    627   template<typename _ForwardIterator, typename _Size, typename _Tp>
    628     inline void
    629     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
    630 				allocator<_Tp>&)
    631     { std::__uninitialized_default_n(__first, __n); }
    632 
    633 
    634   template<typename _InputIterator, typename _Size,
    635 	   typename _ForwardIterator>
    636     _ForwardIterator
    637     __uninitialized_copy_n(_InputIterator __first, _Size __n,
    638 			   _ForwardIterator __result, input_iterator_tag)
    639     {
    640       _ForwardIterator __cur = __result;
    641       __try
    642 	{
    643 	  for (; __n > 0; --__n, ++__first, ++__cur)
    644 	    std::_Construct(std::__addressof(*__cur), *__first);
    645 	  return __cur;
    646 	}
    647       __catch(...)
    648 	{
    649 	  std::_Destroy(__result, __cur);
    650 	  __throw_exception_again;
    651 	}
    652     }
    653 
    654   template<typename _RandomAccessIterator, typename _Size,
    655 	   typename _ForwardIterator>
    656     inline _ForwardIterator
    657     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
    658 			   _ForwardIterator __result,
    659 			   random_access_iterator_tag)
    660     { return std::uninitialized_copy(__first, __first + __n, __result); }
    661 
    662   /**
    663    *  @brief Copies the range [first,first+n) into result.
    664    *  @param  __first  An input iterator.
    665    *  @param  __n      The number of elements to copy.
    666    *  @param  __result An output iterator.
    667    *  @return  __result + __n
    668    *
    669    *  Like copy_n(), but does not require an initialized output range.
    670   */
    671   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
    672     inline _ForwardIterator
    673     uninitialized_copy_n(_InputIterator __first, _Size __n,
    674 			 _ForwardIterator __result)
    675     { return std::__uninitialized_copy_n(__first, __n, __result,
    676 					 std::__iterator_category(__first)); }
    677 #endif
    678 
    679 _GLIBCXX_END_NAMESPACE_VERSION
    680 } // namespace
    681 
    682 #endif /* _STL_UNINITIALIZED_H */
    683