# 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
    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 2, 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 // You should have received a copy of the GNU General Public License along
    00018 // with this library; see the file COPYING.  If not, write to the Free
    00019 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    00020 // USA.
    00021
    00022 // As a special exception, you may use this file as part of a free software
    00023 // library without restriction.  Specifically, if other files instantiate
    00024 // templates or use macros or inline functions from this file, or you compile
    00025 // this file and link it with other files to produce an executable, this
    00026 // file does not by itself cause the resulting executable to be covered by
    00027 // the GNU General Public License.  This exception does not however
    00028 // invalidate any other reasons why the executable file might be covered by
    00029 // the GNU General Public License.
    00030
    00031 /*
    00032  *
    00033  * Copyright (c) 1994
    00034  * Hewlett-Packard Company
    00035  *
    00036  * Permission to use, copy, modify, distribute and sell this software
    00037  * and its documentation for any purpose is hereby granted without fee,
    00038  * provided that the above copyright notice appear in all copies and
    00039  * that both that copyright notice and this permission notice appear
    00040  * in supporting documentation.  Hewlett-Packard Company makes no
    00041  * representations about the suitability of this software for any
    00042  * purpose.  It is provided "as is" without express or implied warranty.
    00043  *
    00044  *
    00045  * Copyright (c) 1996,1997
    00046  * Silicon Graphics Computer Systems, Inc.
    00047  *
    00048  * Permission to use, copy, modify, distribute and sell this software
    00049  * and its documentation for any purpose is hereby granted without fee,
    00050  * provided that the above copyright notice appear in all copies and
    00051  * that both that copyright notice and this permission notice appear
    00052  * in supporting documentation.  Silicon Graphics makes no
    00053  * representations about the suitability of this software for any
    00054  * purpose.  It is provided "as is" without express or implied warranty.
    00055  */
    00056
    00057 /** @file stl_uninitialized.h
    00058  *  This is an internal header file, included by other library headers.
    00059  *  You should not attempt to use it directly.
    00060  */
    00061
    00062 #ifndef _STL_UNINITIALIZED_H
    00063 #define _STL_UNINITIALIZED_H 1
    00064
    00065 _GLIBCXX_BEGIN_NAMESPACE(std)
    00066
    00067   template<bool>
    00068     struct __uninitialized_copy
    00069     {
    00070       template<typename _InputIterator, typename _ForwardIterator>
    00071         static _ForwardIterator
    00072         uninitialized_copy(_InputIterator __first, _InputIterator __last,
    00073                _ForwardIterator __result)
    00074         {
    00075       _ForwardIterator __cur = __result;
    00076       try
    00077         {
    00078           for (; __first != __last; ++__first, ++__cur)
    00079         ::new(static_cast<void*>(&*__cur)) typename
    00080             iterator_traits<_ForwardIterator>::value_type(*__first);
    00081           return __cur;
    00082         }
    00083       catch(...)
    00084         {
    00085           std::_Destroy(__result, __cur);
    00086           __throw_exception_again;
    00087         }
    00088     }
    00089     };
    00090
    00091   template<>
    00092     struct __uninitialized_copy<true>
    00093     {
    00094       template<typename _InputIterator, typename _ForwardIterator>
    00095         static _ForwardIterator
    00096         uninitialized_copy(_InputIterator __first, _InputIterator __last,
    00097                _ForwardIterator __result)
    00098         { return std::copy(__first, __last, __result); }
    00099     };
    00100
    00101   /**
    00102    *  @brief Copies the range [first,last) into result.
    00103    *  @param  first  An input iterator.
    00104    *  @param  last   An input iterator.
    00105    *  @param  result An output iterator.
    00106    *  @return   result + (first - last)
    00107    *
    00108    *  Like copy(), but does not require an initialized output range.
    00109   */
    00110   template<typename _InputIterator, typename _ForwardIterator>
    00111     inline _ForwardIterator
    00112     uninitialized_copy(_InputIterator __first, _InputIterator __last,
    00113                _ForwardIterator __result)
    00114     {
    00115       typedef typename iterator_traits<_InputIterator>::value_type
    00116     _ValueType1;
    00117       typedef typename iterator_traits<_ForwardIterator>::value_type
    00118     _ValueType2;
    00119
    00120       return std::__uninitialized_copy<(__is_pod(_ValueType1)
    00121                     && __is_pod(_ValueType2))>::
    00122     uninitialized_copy(__first, __last, __result);
    00123     }
    00124
    00125
    00126   template<bool>
    00127     struct __uninitialized_fill
    00128     {
    00129       template<typename _ForwardIterator, typename _Tp>
    00130         static void
    00131         uninitialized_fill(_ForwardIterator __first,
    00132                _ForwardIterator __last, const _Tp& __x)
    00133         {
    00134       _ForwardIterator __cur = __first;
    00135       try
    00136         {
    00137           for (; __cur != __last; ++__cur)
    00138         std::_Construct(&*__cur, __x);
    00139         }
    00140       catch(...)
    00141         {
    00142           std::_Destroy(__first, __cur);
    00143           __throw_exception_again;
    00144         }
    00145     }
    00146     };
    00147
    00148   template<>
    00149     struct __uninitialized_fill<true>
    00150     {
    00151       template<typename _ForwardIterator, typename _Tp>
    00152         static void
    00153         uninitialized_fill(_ForwardIterator __first,
    00154                _ForwardIterator __last, const _Tp& __x)
    00155         { std::fill(__first, __last, __x); }
    00156     };
    00157
    00158   /**
    00159    *  @brief Copies the value x into the range [first,last).
    00160    *  @param  first  An input iterator.
    00161    *  @param  last   An input iterator.
    00162    *  @param  x      The source value.
    00163    *  @return   Nothing.
    00164    *
    00165    *  Like fill(), but does not require an initialized output range.
    00166   */
    00167   template<typename _ForwardIterator, typename _Tp>
    00168     inline void
    00169     uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
    00170                const _Tp& __x)
    00171     {
    00172       typedef typename iterator_traits<_ForwardIterator>::value_type
    00173     _ValueType;
    00174
    00175       std::__uninitialized_fill<__is_pod(_ValueType)>::
    00176 	uninitialized_fill(__first, __last, __x);
    00177     }
    00178
    00179
    00180   template<bool>
    00181     struct __uninitialized_fill_n
    00182     {
    00183       template<typename _ForwardIterator, typename _Size, typename _Tp>
    00184         static void
    00185         uninitialized_fill_n(_ForwardIterator __first, _Size __n,
    00186                  const _Tp& __x)
    00187         {
    00188       _ForwardIterator __cur = __first;
    00189       try
    00190         {
    00191           for (; __n > 0; --__n, ++__cur)
    00192         std::_Construct(&*__cur, __x);
    00193         }
    00194       catch(...)
    00195         {
    00196           std::_Destroy(__first, __cur);
    00197           __throw_exception_again;
    00198         }
    00199     }
    00200     };
    00201
    00202   template<>
    00203     struct __uninitialized_fill_n<true>
    00204     {
    00205       template<typename _ForwardIterator, typename _Size, typename _Tp>
    00206         static void
    00207         uninitialized_fill_n(_ForwardIterator __first, _Size __n,
    00208                  const _Tp& __x)
    00209         { std::fill_n(__first, __n, __x); }
    00210     };
    00211
    00212   /**
    00213    *  @brief Copies the value x into the range [first,first+n).
    00214    *  @param  first  An input iterator.
    00215    *  @param  n      The number of copies to make.
    00216    *  @param  x      The source value.
    00217    *  @return   Nothing.
    00218    *
    00219    *  Like fill_n(), but does not require an initialized output range.
    00220   */
    00221   template<typename _ForwardIterator, typename _Size, typename _Tp>
    00222     inline void
    00223     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
    00224     {
    00225       typedef typename iterator_traits<_ForwardIterator>::value_type
    00226     _ValueType;
    00227
    00228       std::__uninitialized_fill_n<__is_pod(_ValueType)>::
    00229 	uninitialized_fill_n(__first, __n, __x);
    00230     }
    00231
    00232   // Extensions: versions of uninitialized_copy, uninitialized_fill,
    00233   //  and uninitialized_fill_n that take an allocator parameter.
    00234   //  We dispatch back to the standard versions when we're given the
    00235   //  default allocator.  For nondefault allocators we do not use
    00236   //  any of the POD optimizations.
    00237
    00238   template<typename _InputIterator, typename _ForwardIterator,
    00239        typename _Allocator>
    00240     _ForwardIterator
    00241     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
    00242                _ForwardIterator __result, _Allocator& __alloc)
    00243     {
    00244       _ForwardIterator __cur = __result;
    00245       try
    00246     {
    00247       for (; __first != __last; ++__first, ++__cur)
    00248         __alloc.construct(&*__cur, *__first);
    00249       return __cur;
    00250     }
    00251       catch(...)
    00252     {
    00253       std::_Destroy(__result, __cur, __alloc);
    00254       __throw_exception_again;
    00255     }
    00256     }
    00257
    00258   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
    00259     inline _ForwardIterator
    00260     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
    00261                _ForwardIterator __result, allocator<_Tp>&)
    00262     { return std::uninitialized_copy(__first, __last, __result); }
    00263
    00264   template<typename _InputIterator, typename _ForwardIterator,
    00265        typename _Allocator>
    00266     inline _ForwardIterator
    00267     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
    00268                _ForwardIterator __result, _Allocator& __alloc)
    00269     {
    00270       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
    00271                      _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
    00272                      __result, __alloc);
    00273     }
    00274
    00275   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
    00276     void
    00277     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
    00278                const _Tp& __x, _Allocator& __alloc)
    00279     {
    00280       _ForwardIterator __cur = __first;
    00281       try
    00282     {
    00283       for (; __cur != __last; ++__cur)
    00284         __alloc.construct(&*__cur, __x);
    00285     }
    00286       catch(...)
    00287     {
    00288       std::_Destroy(__first, __cur, __alloc);
    00289       __throw_exception_again;
    00290     }
    00291     }
    00292
    00293   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
    00294     inline void
    00295     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
    00296                const _Tp& __x, allocator<_Tp2>&)
    00297     { std::uninitialized_fill(__first, __last, __x); }
    00298
    00299   template<typename _ForwardIterator, typename _Size, typename _Tp,
    00300        typename _Allocator>
    00301     void
    00302     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
    00303                  const _Tp& __x, _Allocator& __alloc)
    00304     {
    00305       _ForwardIterator __cur = __first;
    00306       try
    00307     {
    00308       for (; __n > 0; --__n, ++__cur)
    00309         __alloc.construct(&*__cur, __x);
    00310     }
    00311       catch(...)
    00312     {
    00313       std::_Destroy(__first, __cur, __alloc);
    00314       __throw_exception_again;
    00315     }
    00316     }
    00317
    00318   template<typename _ForwardIterator, typename _Size, typename _Tp,
    00319        typename _Tp2>
    00320     inline void
    00321     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
    00322                  const _Tp& __x, allocator<_Tp2>&)
    00323     { std::uninitialized_fill_n(__first, __n, __x); }
    00324
    00325
    00326   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
    00327   // __uninitialized_fill_move, __uninitialized_move_fill.
    00328   // All of these algorithms take a user-supplied allocator, which is used
    00329   // for construction and destruction.
    00330
    00331   // __uninitialized_copy_move
    00332   // Copies [first1, last1) into [result, result + (last1 - first1)), and
    00333   //  move [first2, last2) into
    00334   //  [result, result + (last1 - first1) + (last2 - first2)).
    00335   template<typename _InputIterator1, typename _InputIterator2,
    00336        typename _ForwardIterator, typename _Allocator>
    00337     inline _ForwardIterator
    00338     __uninitialized_copy_move(_InputIterator1 __first1,
    00339                   _InputIterator1 __last1,
    00340                   _InputIterator2 __first2,
    00341                   _InputIterator2 __last2,
    00342                   _ForwardIterator __result,
    00343                   _Allocator& __alloc)
    00344     {
    00345       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
    00346                                __result,
    00347                                __alloc);
    00348       try
    00349     {
    00350       return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
    00351     }
    00352       catch(...)
    00353     {
    00354       std::_Destroy(__result, __mid, __alloc);
    00355       __throw_exception_again;
    00356     }
    00357     }
    00358
    00359   // __uninitialized_move_copy
    00360   // Moves [first1, last1) into [result, result + (last1 - first1)), and
    00361   //  copies [first2, last2) into
    00362   //  [result, result + (last1 - first1) + (last2 - first2)).
    00363   template<typename _InputIterator1, typename _InputIterator2,
    00364        typename _ForwardIterator, typename _Allocator>
    00365     inline _ForwardIterator
    00366     __uninitialized_move_copy(_InputIterator1 __first1,
    00367                   _InputIterator1 __last1,
    00368                   _InputIterator2 __first2,
    00369                   _InputIterator2 __last2,
    00370                   _ForwardIterator __result,
    00371                   _Allocator& __alloc)
    00372     {
    00373       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
    00374                                __result,
    00375                                __alloc);
    00376       try
    00377     {
    00378       return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
    00379     }
    00380       catch(...)
    00381     {
    00382       std::_Destroy(__result, __mid, __alloc);
    00383       __throw_exception_again;
    00384     }
    00385     }
    00386
    00387   // __uninitialized_fill_move
    00388   // Fills [result, mid) with x, and moves [first, last) into
    00389   //  [mid, mid + (last - first)).
    00390   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
    00391        typename _Allocator>
    00392     inline _ForwardIterator
    00393     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
    00394                   const _Tp& __x, _InputIterator __first,
    00395                   _InputIterator __last, _Allocator& __alloc)
    00396     {
    00397       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
    00398       try
    00399     {
    00400       return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
    00401     }
    00402       catch(...)
    00403     {
    00404       std::_Destroy(__result, __mid, __alloc);
    00405       __throw_exception_again;
    00406     }
    00407     }
    00408
    00409   // __uninitialized_move_fill
    00410   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
    00411   //  fills [first2 + (last1 - first1), last2) with x.
    00412   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
    00413        typename _Allocator>
    00414     inline void
    00415     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
    00416                   _ForwardIterator __first2,
    00417                   _ForwardIterator __last2, const _Tp& __x,
    00418                   _Allocator& __alloc)
    00419     {
    00420       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
    00421                                 __first2,
    00422                                 __alloc);
    00423       try
    00424     {
    00425       std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
    00426     }
    00427       catch(...)
    00428     {
    00429       std::_Destroy(__first2, __mid2, __alloc);
    00430       __throw_exception_again;
    00431     }
    00432     }
    00433
    00434 _GLIBCXX_END_NAMESPACE
    00435
    00436 #endif /* _STL_UNINITIALIZED_H */