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