# stl_uninitialized.h

Go to the documentation of this file.

    00001 // Raw memory manipulators -*- C++ -*-
    00002
    00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    00004 // Free Software Foundation, Inc.
    00005 //
    00006 // This file is part of the GNU ISO C++ Library.  This library is free
    00007 // software; you can redistribute it and/or modify it under the
    00008 // terms of the GNU General Public License as published by the
    00009 // Free Software Foundation; either version 3, or (at your option)
    00010 // any later version.
    00011
    00012 // This library is distributed in the hope that it will be useful,
    00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00015 // GNU General Public License for more details.
    00016
    00017 // Under Section 7 of GPL version 3, you are granted additional
    00018 // permissions described in the GCC Runtime Library Exception, version
    00019 // 3.1, as published by the Free Software Foundation.
    00020
    00021 // You should have received a copy of the GNU General Public License and
    00022 // a copy of the GCC Runtime Library Exception along with this program;
    00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    00024 // <http://www.gnu.org/licenses/>.
    00025
    00026 /*
    00027  *
    00028  * Copyright (c) 1994
    00029  * Hewlett-Packard Company
    00030  *
    00031  * Permission to use, copy, modify, distribute and sell this software
    00032  * and its documentation for any purpose is hereby granted without fee,
    00033  * provided that the above copyright notice appear in all copies and
    00034  * that both that copyright notice and this permission notice appear
    00035  * in supporting documentation.  Hewlett-Packard Company makes no
    00036  * representations about the suitability of this software for any
    00037  * purpose.  It is provided "as is" without express or implied warranty.
    00038  *
    00039  *
    00040  * Copyright (c) 1996,1997
    00041  * Silicon Graphics Computer Systems, Inc.
    00042  *
    00043  * Permission to use, copy, modify, distribute and sell this software
    00044  * and its documentation for any purpose is hereby granted without fee,
    00045  * provided that the above copyright notice appear in all copies and
    00046  * that both that copyright notice and this permission notice appear
    00047  * in supporting documentation.  Silicon Graphics makes no
    00048  * representations about the suitability of this software for any
    00049  * purpose.  It is provided "as is" without express or implied warranty.
    00050  */
    00051
    00052 /** @file stl_uninitialized.h
    00053  *  This is an internal header file, included by other library headers.
    00054  *  You should not attempt to use it directly.
    00055  */
    00056
    00057 #ifndef _STL_UNINITIALIZED_H
    00058 #define _STL_UNINITIALIZED_H 1
    00059
    00060 _GLIBCXX_BEGIN_NAMESPACE(std)
    00061
    00062   template<bool>
    00063     struct __uninitialized_copy
    00064     {
    00065       template<typename _InputIterator, typename _ForwardIterator>
    00066         static _ForwardIterator
    00067         uninitialized_copy(_InputIterator __first, _InputIterator __last,
    00068                _ForwardIterator __result)
    00069         {
    00070       _ForwardIterator __cur = __result;
    00071       __try
    00072         {
    00073           for (; __first != __last; ++__first, ++__cur)
    00074         std::_Construct(&*__cur, *__first);
    00075           return __cur;
    00076         }
    00077       __catch(...)
    00078         {
    00079           std::_Destroy(__result, __cur);
    00080           __throw_exception_again;
    00081         }
    00082     }
    00083     };
    00084
    00085   template<>
    00086     struct __uninitialized_copy<true>
    00087     {
    00088       template<typename _InputIterator, typename _ForwardIterator>
    00089         static _ForwardIterator
    00090         uninitialized_copy(_InputIterator __first, _InputIterator __last,
    00091                _ForwardIterator __result)
    00092         { return std::copy(__first, __last, __result); }
    00093     };
    00094
    00095   /**
    00096    *  @brief Copies the range [first,last) into result.
    00097    *  @param  first  An input iterator.
    00098    *  @param  last   An input iterator.
    00099    *  @param  result An output iterator.
    00100    *  @return   result + (first - last)
    00101    *
    00102    *  Like copy(), but does not require an initialized output range.
    00103   */
    00104   template<typename _InputIterator, typename _ForwardIterator>
    00105     inline _ForwardIterator
    00106     uninitialized_copy(_InputIterator __first, _InputIterator __last,
    00107                _ForwardIterator __result)
    00108     {
    00109       typedef typename iterator_traits<_InputIterator>::value_type
    00110     _ValueType1;
    00111       typedef typename iterator_traits<_ForwardIterator>::value_type
    00112     _ValueType2;
    00113
    00114       return std::__uninitialized_copy<(__is_pod(_ValueType1)
    00115                     && __is_pod(_ValueType2))>::
    00116     uninitialized_copy(__first, __last, __result);
    00117     }
    00118
    00119
    00120   template<bool>
    00121     struct __uninitialized_fill
    00122     {
    00123       template<typename _ForwardIterator, typename _Tp>
    00124         static void
    00125         uninitialized_fill(_ForwardIterator __first,
    00126                _ForwardIterator __last, const _Tp& __x)
    00127         {
    00128       _ForwardIterator __cur = __first;
    00129       __try
    00130         {
    00131           for (; __cur != __last; ++__cur)
    00132         std::_Construct(&*__cur, __x);
    00133         }
    00134       __catch(...)
    00135         {
    00136           std::_Destroy(__first, __cur);
    00137           __throw_exception_again;
    00138         }
    00139     }
    00140     };
    00141
    00142   template<>
    00143     struct __uninitialized_fill<true>
    00144     {
    00145       template<typename _ForwardIterator, typename _Tp>
    00146         static void
    00147         uninitialized_fill(_ForwardIterator __first,
    00148                _ForwardIterator __last, const _Tp& __x)
    00149         { std::fill(__first, __last, __x); }
    00150     };
    00151
    00152   /**
    00153    *  @brief Copies the value x into the range [first,last).
    00154    *  @param  first  An input iterator.
    00155    *  @param  last   An input iterator.
    00156    *  @param  x      The source value.
    00157    *  @return   Nothing.
    00158    *
    00159    *  Like fill(), but does not require an initialized output range.
    00160   */
    00161   template<typename _ForwardIterator, typename _Tp>
    00162     inline void
    00163     uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
    00164                const _Tp& __x)
    00165     {
    00166       typedef typename iterator_traits<_ForwardIterator>::value_type
    00167     _ValueType;
    00168
    00169       std::__uninitialized_fill<__is_pod(_ValueType)>::
    00170 	uninitialized_fill(__first, __last, __x);
    00171     }
    00172
    00173
    00174   template<bool>
    00175     struct __uninitialized_construct_range_dispatch
    00176     {
    00177       template<typename _ForwardIterator, typename _Tp>
    00178         static void
    00179         __ucr(_ForwardIterator __first, _ForwardIterator __last,
    00180           _Tp& __value)
    00181         {
    00182       if(__first == __last)
    00183         return;
    00184
    00185       _ForwardIterator __cur = __first;
    00186       __try
    00187         {
    00188           std::_Construct(&*__first, _GLIBCXX_MOVE(__value));
    00189           _ForwardIterator __prev = __cur;
    00190           ++__cur;
    00191           for(; __cur != __last; ++__cur, ++__prev)
    00192         std::_Construct(&*__cur, _GLIBCXX_MOVE(*__prev));
    00193           __value = _GLIBCXX_MOVE(*__prev);
    00194         }
    00195       __catch(...)
    00196         {
    00197           std::_Destroy(__first, __cur);
    00198           __throw_exception_again;
    00199         }
    00200     }
    00201     };
    00202
    00203   template<>
    00204     struct __uninitialized_construct_range_dispatch<true>
    00205     {
    00206       template<typename _ForwardIterator, typename _Tp>
    00207         static void
    00208         __ucr(_ForwardIterator, _ForwardIterator, _Tp&) { }
    00209     };
    00210
    00211   // Constructs objects in the range [first, last).
    00212   // Note that while these new objects will take valid values,
    00213   // their exact value is not defined. In particular they may
    00214   // be 'moved from'.
    00215   //
    00216   // While __value may altered during this algorithm, it will have
    00217   // the same value when the algorithm finishes, unless one of the
    00218   // constructions throws.
    00219   //
    00220   // Requirements: _ForwardIterator::value_type(_Tp&&) is valid.
    00221   template<typename _ForwardIterator, typename _Tp>
    00222     inline void
    00223     __uninitialized_construct_range(_ForwardIterator __first,
    00224                     _ForwardIterator __last,
    00225                     _Tp& __value)
    00226     {
    00227       typedef typename std::iterator_traits<_ForwardIterator>::value_type
    00228     _ValueType;
    00229
    00230       std::__uninitialized_construct_range_dispatch<
    00231         __has_trivial_constructor(_ValueType)>::
    00232       __ucr(__first, __last, __value);
    00233     }
    00234
    00235
    00236   template<bool>
    00237     struct __uninitialized_fill_n
    00238     {
    00239       template<typename _ForwardIterator, typename _Size, typename _Tp>
    00240         static void
    00241         uninitialized_fill_n(_ForwardIterator __first, _Size __n,
    00242                  const _Tp& __x)
    00243         {
    00244       _ForwardIterator __cur = __first;
    00245       __try
    00246         {
    00247           for (; __n > 0; --__n, ++__cur)
    00248         std::_Construct(&*__cur, __x);
    00249         }
    00250       __catch(...)
    00251         {
    00252           std::_Destroy(__first, __cur);
    00253           __throw_exception_again;
    00254         }
    00255     }
    00256     };
    00257
    00258   template<>
    00259     struct __uninitialized_fill_n<true>
    00260     {
    00261       template<typename _ForwardIterator, typename _Size, typename _Tp>
    00262         static void
    00263         uninitialized_fill_n(_ForwardIterator __first, _Size __n,
    00264                  const _Tp& __x)
    00265         { std::fill_n(__first, __n, __x); }
    00266     };
    00267
    00268   /**
    00269    *  @brief Copies the value x into the range [first,first+n).
    00270    *  @param  first  An input iterator.
    00271    *  @param  n      The number of copies to make.
    00272    *  @param  x      The source value.
    00273    *  @return   Nothing.
    00274    *
    00275    *  Like fill_n(), but does not require an initialized output range.
    00276   */
    00277   template<typename _ForwardIterator, typename _Size, typename _Tp>
    00278     inline void
    00279     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
    00280     {
    00281       typedef typename iterator_traits<_ForwardIterator>::value_type
    00282     _ValueType;
    00283
    00284       std::__uninitialized_fill_n<__is_pod(_ValueType)>::
    00285 	uninitialized_fill_n(__first, __n, __x);
    00286     }
    00287
    00288   // Extensions: versions of uninitialized_copy, uninitialized_fill,
    00289   //  and uninitialized_fill_n that take an allocator parameter.
    00290   //  We dispatch back to the standard versions when we're given the
    00291   //  default allocator.  For nondefault allocators we do not use
    00292   //  any of the POD optimizations.
    00293
    00294   template<typename _InputIterator, typename _ForwardIterator,
    00295        typename _Allocator>
    00296     _ForwardIterator
    00297     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
    00298                _ForwardIterator __result, _Allocator& __alloc)
    00299     {
    00300       _ForwardIterator __cur = __result;
    00301       __try
    00302     {
    00303       for (; __first != __last; ++__first, ++__cur)
    00304         __alloc.construct(&*__cur, *__first);
    00305       return __cur;
    00306     }
    00307       __catch(...)
    00308     {
    00309       std::_Destroy(__result, __cur, __alloc);
    00310       __throw_exception_again;
    00311     }
    00312     }
    00313
    00314   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
    00315     inline _ForwardIterator
    00316     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
    00317                _ForwardIterator __result, allocator<_Tp>&)
    00318     { return std::uninitialized_copy(__first, __last, __result); }
    00319
    00320   template<typename _InputIterator, typename _ForwardIterator,
    00321        typename _Allocator>
    00322     inline _ForwardIterator
    00323     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
    00324                _ForwardIterator __result, _Allocator& __alloc)
    00325     {
    00326       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
    00327                      _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
    00328                      __result, __alloc);
    00329     }
    00330
    00331   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
    00332     void
    00333     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
    00334                const _Tp& __x, _Allocator& __alloc)
    00335     {
    00336       _ForwardIterator __cur = __first;
    00337       __try
    00338     {
    00339       for (; __cur != __last; ++__cur)
    00340         __alloc.construct(&*__cur, __x);
    00341     }
    00342       __catch(...)
    00343     {
    00344       std::_Destroy(__first, __cur, __alloc);
    00345       __throw_exception_again;
    00346     }
    00347     }
    00348
    00349   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
    00350     inline void
    00351     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
    00352                const _Tp& __x, allocator<_Tp2>&)
    00353     { std::uninitialized_fill(__first, __last, __x); }
    00354
    00355   template<typename _ForwardIterator, typename _Size, typename _Tp,
    00356        typename _Allocator>
    00357     void
    00358     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
    00359                  const _Tp& __x, _Allocator& __alloc)
    00360     {
    00361       _ForwardIterator __cur = __first;
    00362       __try
    00363     {
    00364       for (; __n > 0; --__n, ++__cur)
    00365         __alloc.construct(&*__cur, __x);
    00366     }
    00367       __catch(...)
    00368     {
    00369       std::_Destroy(__first, __cur, __alloc);
    00370       __throw_exception_again;
    00371     }
    00372     }
    00373
    00374   template<typename _ForwardIterator, typename _Size, typename _Tp,
    00375        typename _Tp2>
    00376     inline void
    00377     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
    00378                  const _Tp& __x, allocator<_Tp2>&)
    00379     { std::uninitialized_fill_n(__first, __n, __x); }
    00380
    00381
    00382   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
    00383   // __uninitialized_fill_move, __uninitialized_move_fill.
    00384   // All of these algorithms take a user-supplied allocator, which is used
    00385   // for construction and destruction.
    00386
    00387   // __uninitialized_copy_move
    00388   // Copies [first1, last1) into [result, result + (last1 - first1)), and
    00389   //  move [first2, last2) into
    00390   //  [result, result + (last1 - first1) + (last2 - first2)).
    00391   template<typename _InputIterator1, typename _InputIterator2,
    00392        typename _ForwardIterator, typename _Allocator>
    00393     inline _ForwardIterator
    00394     __uninitialized_copy_move(_InputIterator1 __first1,
    00395                   _InputIterator1 __last1,
    00396                   _InputIterator2 __first2,
    00397                   _InputIterator2 __last2,
    00398                   _ForwardIterator __result,
    00399                   _Allocator& __alloc)
    00400     {
    00401       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
    00402                                __result,
    00403                                __alloc);
    00404       __try
    00405     {
    00406       return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
    00407     }
    00408       __catch(...)
    00409     {
    00410       std::_Destroy(__result, __mid, __alloc);
    00411       __throw_exception_again;
    00412     }
    00413     }
    00414
    00415   // __uninitialized_move_copy
    00416   // Moves [first1, last1) into [result, result + (last1 - first1)), and
    00417   //  copies [first2, last2) into
    00418   //  [result, result + (last1 - first1) + (last2 - first2)).
    00419   template<typename _InputIterator1, typename _InputIterator2,
    00420        typename _ForwardIterator, typename _Allocator>
    00421     inline _ForwardIterator
    00422     __uninitialized_move_copy(_InputIterator1 __first1,
    00423                   _InputIterator1 __last1,
    00424                   _InputIterator2 __first2,
    00425                   _InputIterator2 __last2,
    00426                   _ForwardIterator __result,
    00427                   _Allocator& __alloc)
    00428     {
    00429       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
    00430                                __result,
    00431                                __alloc);
    00432       __try
    00433     {
    00434       return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
    00435     }
    00436       __catch(...)
    00437     {
    00438       std::_Destroy(__result, __mid, __alloc);
    00439       __throw_exception_again;
    00440     }
    00441     }
    00442
    00443   // __uninitialized_fill_move
    00444   // Fills [result, mid) with x, and moves [first, last) into
    00445   //  [mid, mid + (last - first)).
    00446   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
    00447        typename _Allocator>
    00448     inline _ForwardIterator
    00449     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
    00450                   const _Tp& __x, _InputIterator __first,
    00451                   _InputIterator __last, _Allocator& __alloc)
    00452     {
    00453       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
    00454       __try
    00455     {
    00456       return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
    00457     }
    00458       __catch(...)
    00459     {
    00460       std::_Destroy(__result, __mid, __alloc);
    00461       __throw_exception_again;
    00462     }
    00463     }
    00464
    00465   // __uninitialized_move_fill
    00466   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
    00467   //  fills [first2 + (last1 - first1), last2) with x.
    00468   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
    00469        typename _Allocator>
    00470     inline void
    00471     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
    00472                   _ForwardIterator __first2,
    00473                   _ForwardIterator __last2, const _Tp& __x,
    00474                   _Allocator& __alloc)
    00475     {
    00476       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
    00477                                 __first2,
    00478                                 __alloc);
    00479       __try
    00480     {
    00481       std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
    00482     }
    00483       __catch(...)
    00484     {
    00485       std::_Destroy(__first2, __mid2, __alloc);
    00486       __throw_exception_again;
    00487     }
    00488     }
    00489
    00490 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    00491   template<typename _InputIterator, typename _Size,
    00492        typename _ForwardIterator>
    00493     _ForwardIterator
    00494     __uninitialized_copy_n(_InputIterator __first, _Size __n,
    00495                _ForwardIterator __result, input_iterator_tag)
    00496     {
    00497       _ForwardIterator __cur = __result;
    00498       __try
    00499     {
    00500       for (; __n > 0; --__n, ++__first, ++__cur)
    00501         ::new(static_cast<void*>(&*__cur)) typename
    00502         iterator_traits<_ForwardIterator>::value_type(*__first);
    00503       return __cur;
    00504     }
    00505       __catch(...)
    00506     {
    00507       std::_Destroy(__result, __cur);
    00508       __throw_exception_again;
    00509     }
    00510     }
    00511
    00512   template<typename _RandomAccessIterator, typename _Size,
    00513        typename _ForwardIterator>
    00514     inline _ForwardIterator
    00515     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
    00516                _ForwardIterator __result,
    00517                random_access_iterator_tag)
    00518     { return std::uninitialized_copy(__first, __first + __n, __result); }
    00519
    00520   /**
    00521    *  @brief Copies the range [first,first+n) into result.
    00522    *  @param  first  An input iterator.
    00523    *  @param  n      The number of elements to copy.
    00524    *  @param  result An output iterator.
    00525    *  @return  result + n
    00526    *
    00527    *  Like copy_n(), but does not require an initialized output range.
    00528   */
    00529   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
    00530     inline _ForwardIterator
    00531     uninitialized_copy_n(_InputIterator __first, _Size __n,
    00532              _ForwardIterator __result)
    00533     { return std::__uninitialized_copy_n(__first, __n, __result,
    00534                      std::__iterator_category(__first)); }
    00535 #endif
    00536
    00537 _GLIBCXX_END_NAMESPACE
    00538
    00539 #endif /* _STL_UNINITIALIZED_H */