Home | History | Annotate | Download | only in bits
      1 // Raw memory manipulators -*- C++ -*-
      2 
      3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
      4 // Free Software Foundation, Inc.
      5 //
      6 // This file is part of the GNU ISO C++ Library.  This library is free
      7 // software; you can redistribute it and/or modify it under the
      8 // terms of the GNU General Public License as published by the
      9 // Free Software Foundation; either version 3, or (at your option)
     10 // any later version.
     11 
     12 // This library is distributed in the hope that it will be useful,
     13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 // GNU General Public License for more details.
     16 
     17 // Under Section 7 of GPL version 3, you are granted additional
     18 // permissions described in the GCC Runtime Library Exception, version
     19 // 3.1, as published by the Free Software Foundation.
     20 
     21 // You should have received a copy of the GNU General Public License and
     22 // a copy of the GCC Runtime Library Exception along with this program;
     23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24 // <http://www.gnu.org/licenses/>.
     25 
     26 /*
     27  *
     28  * Copyright (c) 1994
     29  * Hewlett-Packard Company
     30  *
     31  * Permission to use, copy, modify, distribute and sell this software
     32  * and its documentation for any purpose is hereby granted without fee,
     33  * provided that the above copyright notice appear in all copies and
     34  * that both that copyright notice and this permission notice appear
     35  * in supporting documentation.  Hewlett-Packard Company makes no
     36  * representations about the suitability of this software for any
     37  * purpose.  It is provided "as is" without express or implied warranty.
     38  *
     39  *
     40  * Copyright (c) 1996,1997
     41  * Silicon Graphics Computer Systems, Inc.
     42  *
     43  * Permission to use, copy, modify, distribute and sell this software
     44  * and its documentation for any purpose is hereby granted without fee,
     45  * provided that the above copyright notice appear in all copies and
     46  * that both that copyright notice and this permission notice appear
     47  * in supporting documentation.  Silicon Graphics makes no
     48  * representations about the suitability of this software for any
     49  * purpose.  It is provided "as is" without express or implied warranty.
     50  */
     51 
     52 /** @file stl_uninitialized.h
     53  *  This is an internal header file, included by other library headers.
     54  *  You should not attempt to use it directly.
     55  */
     56 
     57 #ifndef _STL_UNINITIALIZED_H
     58 #define _STL_UNINITIALIZED_H 1
     59 
     60 _GLIBCXX_BEGIN_NAMESPACE(std)
     61 
     62   template<bool>
     63     struct __uninitialized_copy
     64     {
     65       template<typename _InputIterator, typename _ForwardIterator>
     66         static _ForwardIterator
     67         uninitialized_copy(_InputIterator __first, _InputIterator __last,
     68 			   _ForwardIterator __result)
     69         {
     70 	  _ForwardIterator __cur = __result;
     71 	  __try
     72 	    {
     73 	      for (; __first != __last; ++__first, ++__cur)
     74 		::new(static_cast<void*>(&*__cur)) typename
     75 		    iterator_traits<_ForwardIterator>::value_type(*__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         uninitialized_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_pod(_ValueType1)
    116 					&& __is_pod(_ValueType2))>::
    117 	uninitialized_copy(__first, __last, __result);
    118     }
    119 
    120 
    121   template<bool>
    122     struct __uninitialized_fill
    123     {
    124       template<typename _ForwardIterator, typename _Tp>
    125         static void
    126         uninitialized_fill(_ForwardIterator __first,
    127 			   _ForwardIterator __last, const _Tp& __x)
    128         {
    129 	  _ForwardIterator __cur = __first;
    130 	  __try
    131 	    {
    132 	      for (; __cur != __last; ++__cur)
    133 		std::_Construct(&*__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         uninitialized_fill(_ForwardIterator __first,
    149 			   _ForwardIterator __last, 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_pod(_ValueType)>::
    171 	uninitialized_fill(__first, __last, __x);
    172     }
    173 
    174 
    175   template<bool>
    176     struct __uninitialized_fill_n
    177     {
    178       template<typename _ForwardIterator, typename _Size, typename _Tp>
    179         static void
    180         uninitialized_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(&*__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         uninitialized_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_pod(_ValueType)>::
    224 	uninitialized_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 	  for (; __first != __last; ++__first, ++__cur)
    243 	    __alloc.construct(&*__cur, *__first);
    244 	  return __cur;
    245 	}
    246       __catch(...)
    247 	{
    248 	  std::_Destroy(__result, __cur, __alloc);
    249 	  __throw_exception_again;
    250 	}
    251     }
    252 
    253   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
    254     inline _ForwardIterator
    255     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
    256 			   _ForwardIterator __result, allocator<_Tp>&)
    257     { return std::uninitialized_copy(__first, __last, __result); }
    258 
    259   template<typename _InputIterator, typename _ForwardIterator,
    260 	   typename _Allocator>
    261     inline _ForwardIterator
    262     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
    263 			   _ForwardIterator __result, _Allocator& __alloc)
    264     {
    265       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
    266 					 _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
    267 					 __result, __alloc);
    268     }
    269 
    270   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
    271     void
    272     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
    273 			   const _Tp& __x, _Allocator& __alloc)
    274     {
    275       _ForwardIterator __cur = __first;
    276       __try
    277 	{
    278 	  for (; __cur != __last; ++__cur)
    279 	    __alloc.construct(&*__cur, __x);
    280 	}
    281       __catch(...)
    282 	{
    283 	  std::_Destroy(__first, __cur, __alloc);
    284 	  __throw_exception_again;
    285 	}
    286     }
    287 
    288   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
    289     inline void
    290     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
    291 			   const _Tp& __x, allocator<_Tp2>&)
    292     { std::uninitialized_fill(__first, __last, __x); }
    293 
    294   template<typename _ForwardIterator, typename _Size, typename _Tp,
    295 	   typename _Allocator>
    296     void
    297     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
    298 			     const _Tp& __x, _Allocator& __alloc)
    299     {
    300       _ForwardIterator __cur = __first;
    301       __try
    302 	{
    303 	  for (; __n > 0; --__n, ++__cur)
    304 	    __alloc.construct(&*__cur, __x);
    305 	}
    306       __catch(...)
    307 	{
    308 	  std::_Destroy(__first, __cur, __alloc);
    309 	  __throw_exception_again;
    310 	}
    311     }
    312 
    313   template<typename _ForwardIterator, typename _Size, typename _Tp,
    314 	   typename _Tp2>
    315     inline void
    316     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
    317 			     const _Tp& __x, allocator<_Tp2>&)
    318     { std::uninitialized_fill_n(__first, __n, __x); }
    319 
    320 
    321   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
    322   // __uninitialized_fill_move, __uninitialized_move_fill.
    323   // All of these algorithms take a user-supplied allocator, which is used
    324   // for construction and destruction.
    325 
    326   // __uninitialized_copy_move
    327   // Copies [first1, last1) into [result, result + (last1 - first1)), and
    328   //  move [first2, last2) into
    329   //  [result, result + (last1 - first1) + (last2 - first2)).
    330   template<typename _InputIterator1, typename _InputIterator2,
    331 	   typename _ForwardIterator, typename _Allocator>
    332     inline _ForwardIterator
    333     __uninitialized_copy_move(_InputIterator1 __first1,
    334 			      _InputIterator1 __last1,
    335 			      _InputIterator2 __first2,
    336 			      _InputIterator2 __last2,
    337 			      _ForwardIterator __result,
    338 			      _Allocator& __alloc)
    339     {
    340       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
    341 							   __result,
    342 							   __alloc);
    343       __try
    344 	{
    345 	  return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
    346 	}
    347       __catch(...)
    348 	{
    349 	  std::_Destroy(__result, __mid, __alloc);
    350 	  __throw_exception_again;
    351 	}
    352     }
    353 
    354   // __uninitialized_move_copy
    355   // Moves [first1, last1) into [result, result + (last1 - first1)), and
    356   //  copies [first2, last2) into
    357   //  [result, result + (last1 - first1) + (last2 - first2)).
    358   template<typename _InputIterator1, typename _InputIterator2,
    359 	   typename _ForwardIterator, typename _Allocator>
    360     inline _ForwardIterator
    361     __uninitialized_move_copy(_InputIterator1 __first1,
    362 			      _InputIterator1 __last1,
    363 			      _InputIterator2 __first2,
    364 			      _InputIterator2 __last2,
    365 			      _ForwardIterator __result,
    366 			      _Allocator& __alloc)
    367     {
    368       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
    369 							   __result,
    370 							   __alloc);
    371       __try
    372 	{
    373 	  return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
    374 	}
    375       __catch(...)
    376 	{
    377 	  std::_Destroy(__result, __mid, __alloc);
    378 	  __throw_exception_again;
    379 	}
    380     }
    381 
    382   // __uninitialized_fill_move
    383   // Fills [result, mid) with x, and moves [first, last) into
    384   //  [mid, mid + (last - first)).
    385   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
    386 	   typename _Allocator>
    387     inline _ForwardIterator
    388     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
    389 			      const _Tp& __x, _InputIterator __first,
    390 			      _InputIterator __last, _Allocator& __alloc)
    391     {
    392       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
    393       __try
    394 	{
    395 	  return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
    396 	}
    397       __catch(...)
    398 	{
    399 	  std::_Destroy(__result, __mid, __alloc);
    400 	  __throw_exception_again;
    401 	}
    402     }
    403 
    404   // __uninitialized_move_fill
    405   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
    406   //  fills [first2 + (last1 - first1), last2) with x.
    407   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
    408 	   typename _Allocator>
    409     inline void
    410     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
    411 			      _ForwardIterator __first2,
    412 			      _ForwardIterator __last2, const _Tp& __x,
    413 			      _Allocator& __alloc)
    414     {
    415       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
    416 							    __first2,
    417 							    __alloc);
    418       __try
    419 	{
    420 	  std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
    421 	}
    422       __catch(...)
    423 	{
    424 	  std::_Destroy(__first2, __mid2, __alloc);
    425 	  __throw_exception_again;
    426 	}
    427     }
    428 
    429 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    430   template<typename _InputIterator, typename _Size,
    431 	   typename _ForwardIterator>
    432     _ForwardIterator
    433     __uninitialized_copy_n(_InputIterator __first, _Size __n,
    434 			   _ForwardIterator __result, input_iterator_tag)
    435     {
    436       _ForwardIterator __cur = __result;
    437       __try
    438 	{
    439 	  for (; __n > 0; --__n, ++__first, ++__cur)
    440 	    ::new(static_cast<void*>(&*__cur)) typename
    441 		iterator_traits<_ForwardIterator>::value_type(*__first);
    442 	  return __cur;
    443 	}
    444       __catch(...)
    445 	{
    446 	  std::_Destroy(__result, __cur);
    447 	  __throw_exception_again;
    448 	}
    449     }
    450 
    451   template<typename _RandomAccessIterator, typename _Size,
    452 	   typename _ForwardIterator>
    453     inline _ForwardIterator
    454     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
    455 			   _ForwardIterator __result,
    456 			   random_access_iterator_tag)
    457     { return std::uninitialized_copy(__first, __first + __n, __result); }
    458 
    459   /**
    460    *  @brief Copies the range [first,first+n) into result.
    461    *  @param  first  An input iterator.
    462    *  @param  n      The number of elements to copy.
    463    *  @param  result An output iterator.
    464    *  @return  result + n
    465    *
    466    *  Like copy_n(), but does not require an initialized output range.
    467   */
    468   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
    469     inline _ForwardIterator
    470     uninitialized_copy_n(_InputIterator __first, _Size __n,
    471 			 _ForwardIterator __result)
    472     { return std::__uninitialized_copy_n(__first, __n, __result,
    473 					 std::__iterator_category(__first)); }
    474 #endif
    475 
    476 _GLIBCXX_END_NAMESPACE
    477 
    478 #endif /* _STL_UNINITIALIZED_H */
    479