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