# 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         ::new(static_cast<void*>(&*__cur)) typename
    00075             iterator_traits<_ForwardIterator>::value_type(*__first);
    00076           return __cur;
    00077         }
    00078       __catch(...)
    00079         {
    00080           std::_Destroy(__result, __cur);
    00081           __throw_exception_again;
    00082         }
    00083     }
    00084     };
    00085
    00086   template<>
    00087     struct __uninitialized_copy<true>
    00088     {
    00089       template<typename _InputIterator, typename _ForwardIterator>
    00090         static _ForwardIterator
    00091         uninitialized_copy(_InputIterator __first, _InputIterator __last,
    00092                _ForwardIterator __result)
    00093         { return std::copy(__first, __last, __result); }
    00094     };
    00095
    00096   /**
    00097    *  @brief Copies the range [first,last) into result.
    00098    *  @param  first  An input iterator.
    00099    *  @param  last   An input iterator.
    00100    *  @param  result An output iterator.
    00101    *  @return   result + (first - last)
    00102    *
    00103    *  Like copy(), but does not require an initialized output range.
    00104   */
    00105   template<typename _InputIterator, typename _ForwardIterator>
    00106     inline _ForwardIterator
    00107     uninitialized_copy(_InputIterator __first, _InputIterator __last,
    00108                _ForwardIterator __result)
    00109     {
    00110       typedef typename iterator_traits<_InputIterator>::value_type
    00111     _ValueType1;
    00112       typedef typename iterator_traits<_ForwardIterator>::value_type
    00113     _ValueType2;
    00114
    00115       return std::__uninitialized_copy<(__is_pod(_ValueType1)
    00116                     && __is_pod(_ValueType2))>::
    00117     uninitialized_copy(__first, __last, __result);
    00118     }
    00119
    00120
    00121   template<bool>
    00122     struct __uninitialized_fill
    00123     {
    00124       template<typename _ForwardIterator, typename _Tp>
    00125         static void
    00126         uninitialized_fill(_ForwardIterator __first,
    00127                _ForwardIterator __last, const _Tp& __x)
    00128         {
    00129       _ForwardIterator __cur = __first;
    00130       __try
    00131         {
    00132           for (; __cur != __last; ++__cur)
    00133         std::_Construct(&*__cur, __x);
    00134         }
    00135       __catch(...)
    00136         {
    00137           std::_Destroy(__first, __cur);
    00138           __throw_exception_again;
    00139         }
    00140     }
    00141     };
    00142
    00143   template<>
    00144     struct __uninitialized_fill<true>
    00145     {
    00146       template<typename _ForwardIterator, typename _Tp>
    00147         static void
    00148         uninitialized_fill(_ForwardIterator __first,
    00149                _ForwardIterator __last, const _Tp& __x)
    00150         { std::fill(__first, __last, __x); }
    00151     };
    00152
    00153   /**
    00154    *  @brief Copies the value x into the range [first,last).
    00155    *  @param  first  An input iterator.
    00156    *  @param  last   An input iterator.
    00157    *  @param  x      The source value.
    00158    *  @return   Nothing.
    00159    *
    00160    *  Like fill(), but does not require an initialized output range.
    00161   */
    00162   template<typename _ForwardIterator, typename _Tp>
    00163     inline void
    00164     uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
    00165                const _Tp& __x)
    00166     {
    00167       typedef typename iterator_traits<_ForwardIterator>::value_type
    00168     _ValueType;
    00169
    00170       std::__uninitialized_fill<__is_pod(_ValueType)>::
    00171 	uninitialized_fill(__first, __last, __x);
    00172     }
    00173
    00174
    00175   template<bool>
    00176     struct __uninitialized_fill_n
    00177     {
    00178       template<typename _ForwardIterator, typename _Size, typename _Tp>
    00179         static void
    00180         uninitialized_fill_n(_ForwardIterator __first, _Size __n,
    00181                  const _Tp& __x)
    00182         {
    00183       _ForwardIterator __cur = __first;
    00184       __try
    00185         {
    00186           for (; __n > 0; --__n, ++__cur)
    00187         std::_Construct(&*__cur, __x);
    00188         }
    00189       __catch(...)
    00190         {
    00191           std::_Destroy(__first, __cur);
    00192           __throw_exception_again;
    00193         }
    00194     }
    00195     };
    00196
    00197   template<>
    00198     struct __uninitialized_fill_n<true>
    00199     {
    00200       template<typename _ForwardIterator, typename _Size, typename _Tp>
    00201         static void
    00202         uninitialized_fill_n(_ForwardIterator __first, _Size __n,
    00203                  const _Tp& __x)
    00204         { std::fill_n(__first, __n, __x); }
    00205     };
    00206
    00207   /**
    00208    *  @brief Copies the value x into the range [first,first+n).
    00209    *  @param  first  An input iterator.
    00210    *  @param  n      The number of copies to make.
    00211    *  @param  x      The source value.
    00212    *  @return   Nothing.
    00213    *
    00214    *  Like fill_n(), but does not require an initialized output range.
    00215   */
    00216   template<typename _ForwardIterator, typename _Size, typename _Tp>
    00217     inline void
    00218     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
    00219     {
    00220       typedef typename iterator_traits<_ForwardIterator>::value_type
    00221     _ValueType;
    00222
    00223       std::__uninitialized_fill_n<__is_pod(_ValueType)>::
    00224 	uninitialized_fill_n(__first, __n, __x);
    00225     }
    00226
    00227   // Extensions: versions of uninitialized_copy, uninitialized_fill,
    00228   //  and uninitialized_fill_n that take an allocator parameter.
    00229   //  We dispatch back to the standard versions when we're given the
    00230   //  default allocator.  For nondefault allocators we do not use
    00231   //  any of the POD optimizations.
    00232
    00233   template<typename _InputIterator, typename _ForwardIterator,
    00234        typename _Allocator>
    00235     _ForwardIterator
    00236     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
    00237                _ForwardIterator __result, _Allocator& __alloc)
    00238     {
    00239       _ForwardIterator __cur = __result;
    00240       __try
    00241     {
    00242       for (; __first != __last; ++__first, ++__cur)
    00243         __alloc.construct(&*__cur, *__first);
    00244       return __cur;
    00245     }
    00246       __catch(...)
    00247     {
    00248       std::_Destroy(__result, __cur, __alloc);
    00249       __throw_exception_again;
    00250     }
    00251     }
    00252
    00253   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
    00254     inline _ForwardIterator
    00255     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
    00256                _ForwardIterator __result, allocator<_Tp>&)
    00257     { return std::uninitialized_copy(__first, __last, __result); }
    00258
    00259   template<typename _InputIterator, typename _ForwardIterator,
    00260        typename _Allocator>
    00261     inline _ForwardIterator
    00262     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
    00263                _ForwardIterator __result, _Allocator& __alloc)
    00264     {
    00265       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
    00266                      _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
    00267                      __result, __alloc);
    00268     }
    00269
    00270   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
    00271     void
    00272     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
    00273                const _Tp& __x, _Allocator& __alloc)
    00274     {
    00275       _ForwardIterator __cur = __first;
    00276       __try
    00277     {
    00278       for (; __cur != __last; ++__cur)
    00279         __alloc.construct(&*__cur, __x);
    00280     }
    00281       __catch(...)
    00282     {
    00283       std::_Destroy(__first, __cur, __alloc);
    00284       __throw_exception_again;
    00285     }
    00286     }
    00287
    00288   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
    00289     inline void
    00290     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
    00291                const _Tp& __x, allocator<_Tp2>&)
    00292     { std::uninitialized_fill(__first, __last, __x); }
    00293
    00294   template<typename _ForwardIterator, typename _Size, typename _Tp,
    00295        typename _Allocator>
    00296     void
    00297     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
    00298                  const _Tp& __x, _Allocator& __alloc)
    00299     {
    00300       _ForwardIterator __cur = __first;
    00301       __try
    00302     {
    00303       for (; __n > 0; --__n, ++__cur)
    00304         __alloc.construct(&*__cur, __x);
    00305     }
    00306       __catch(...)
    00307     {
    00308       std::_Destroy(__first, __cur, __alloc);
    00309       __throw_exception_again;
    00310     }
    00311     }
    00312
    00313   template<typename _ForwardIterator, typename _Size, typename _Tp,
    00314        typename _Tp2>
    00315     inline void
    00316     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
    00317                  const _Tp& __x, allocator<_Tp2>&)
    00318     { std::uninitialized_fill_n(__first, __n, __x); }
    00319
    00320
    00321   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
    00322   // __uninitialized_fill_move, __uninitialized_move_fill.
    00323   // All of these algorithms take a user-supplied allocator, which is used
    00324   // for construction and destruction.
    00325
    00326   // __uninitialized_copy_move
    00327   // Copies [first1, last1) into [result, result + (last1 - first1)), and
    00328   //  move [first2, last2) into
    00329   //  [result, result + (last1 - first1) + (last2 - first2)).
    00330   template<typename _InputIterator1, typename _InputIterator2,
    00331        typename _ForwardIterator, typename _Allocator>
    00332     inline _ForwardIterator
    00333     __uninitialized_copy_move(_InputIterator1 __first1,
    00334                   _InputIterator1 __last1,
    00335                   _InputIterator2 __first2,
    00336                   _InputIterator2 __last2,
    00337                   _ForwardIterator __result,
    00338                   _Allocator& __alloc)
    00339     {
    00340       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
    00341                                __result,
    00342                                __alloc);
    00343       __try
    00344     {
    00345       return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
    00346     }
    00347       __catch(...)
    00348     {
    00349       std::_Destroy(__result, __mid, __alloc);
    00350       __throw_exception_again;
    00351     }
    00352     }
    00353
    00354   // __uninitialized_move_copy
    00355   // Moves [first1, last1) into [result, result + (last1 - first1)), and
    00356   //  copies [first2, last2) into
    00357   //  [result, result + (last1 - first1) + (last2 - first2)).
    00358   template<typename _InputIterator1, typename _InputIterator2,
    00359        typename _ForwardIterator, typename _Allocator>
    00360     inline _ForwardIterator
    00361     __uninitialized_move_copy(_InputIterator1 __first1,
    00362                   _InputIterator1 __last1,
    00363                   _InputIterator2 __first2,
    00364                   _InputIterator2 __last2,
    00365                   _ForwardIterator __result,
    00366                   _Allocator& __alloc)
    00367     {
    00368       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
    00369                                __result,
    00370                                __alloc);
    00371       __try
    00372     {
    00373       return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
    00374     }
    00375       __catch(...)
    00376     {
    00377       std::_Destroy(__result, __mid, __alloc);
    00378       __throw_exception_again;
    00379     }
    00380     }
    00381
    00382   // __uninitialized_fill_move
    00383   // Fills [result, mid) with x, and moves [first, last) into
    00384   //  [mid, mid + (last - first)).
    00385   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
    00386        typename _Allocator>
    00387     inline _ForwardIterator
    00388     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
    00389                   const _Tp& __x, _InputIterator __first,
    00390                   _InputIterator __last, _Allocator& __alloc)
    00391     {
    00392       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
    00393       __try
    00394     {
    00395       return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
    00396     }
    00397       __catch(...)
    00398     {
    00399       std::_Destroy(__result, __mid, __alloc);
    00400       __throw_exception_again;
    00401     }
    00402     }
    00403
    00404   // __uninitialized_move_fill
    00405   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
    00406   //  fills [first2 + (last1 - first1), last2) with x.
    00407   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
    00408        typename _Allocator>
    00409     inline void
    00410     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
    00411                   _ForwardIterator __first2,
    00412                   _ForwardIterator __last2, const _Tp& __x,
    00413                   _Allocator& __alloc)
    00414     {
    00415       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
    00416                                 __first2,
    00417                                 __alloc);
    00418       __try
    00419     {
    00420       std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
    00421     }
    00422       __catch(...)
    00423     {
    00424       std::_Destroy(__first2, __mid2, __alloc);
    00425       __throw_exception_again;
    00426     }
    00427     }
    00428
    00429 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    00430   template<typename _InputIterator, typename _Size,
    00431        typename _ForwardIterator>
    00432     _ForwardIterator
    00433     __uninitialized_copy_n(_InputIterator __first, _Size __n,
    00434                _ForwardIterator __result, input_iterator_tag)
    00435     {
    00436       _ForwardIterator __cur = __result;
    00437       __try
    00438     {
    00439       for (; __n > 0; --__n, ++__first, ++__cur)
    00440         ::new(static_cast<void*>(&*__cur)) typename
    00441         iterator_traits<_ForwardIterator>::value_type(*__first);
    00442       return __cur;
    00443     }
    00444       __catch(...)
    00445     {
    00446       std::_Destroy(__result, __cur);
    00447       __throw_exception_again;
    00448     }
    00449     }
    00450
    00451   template<typename _RandomAccessIterator, typename _Size,
    00452        typename _ForwardIterator>
    00453     inline _ForwardIterator
    00454     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
    00455                _ForwardIterator __result,
    00456                random_access_iterator_tag)
    00457     { return std::uninitialized_copy(__first, __first + __n, __result); }
    00458
    00459   /**
    00460    *  @brief Copies the range [first,first+n) into result.
    00461    *  @param  first  An input iterator.
    00462    *  @param  n      The number of elements to copy.
    00463    *  @param  result An output iterator.
    00464    *  @return  result + n
    00465    *
    00466    *  Like copy_n(), but does not require an initialized output range.
    00467   */
    00468   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
    00469     inline _ForwardIterator
    00470     uninitialized_copy_n(_InputIterator __first, _Size __n,
    00471              _ForwardIterator __result)
    00472     { return std::__uninitialized_copy_n(__first, __n, __result,
    00473                      std::__iterator_category(__first)); }
    00474 #endif
    00475
    00476 _GLIBCXX_END_NAMESPACE
    00477
    00478 #endif /* _STL_UNINITIALIZED_H */