# 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
    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 #include <cstring>
    00066
    00067 _GLIBCXX_BEGIN_NAMESPACE(std)
    00068
    00069   // uninitialized_copy
    00070   template<typename _InputIterator, typename _ForwardIterator>
    00071     inline _ForwardIterator
    00072     __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last,
    00073                  _ForwardIterator __result,
    00074                  __true_type)
    00075     { return std::copy(__first, __last, __result); }
    00076
    00077   template<typename _InputIterator, typename _ForwardIterator>
    00078     inline _ForwardIterator
    00079     __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last,
    00080                  _ForwardIterator __result,
    00081                  __false_type)
    00082     {
    00083       _ForwardIterator __cur = __result;
    00084       try
    00085     {
    00086       for (; __first != __last; ++__first, ++__cur)
    00087         std::_Construct(&*__cur, *__first);
    00088       return __cur;
    00089     }
    00090       catch(...)
    00091     {
    00092       std::_Destroy(__result, __cur);
    00093       __throw_exception_again;
    00094     }
    00095     }
    00096
    00097   /**
    00098    *  @brief Copies the range [first,last) into result.
    00099    *  @param  first  An input iterator.
    00100    *  @param  last   An input iterator.
    00101    *  @param  result An output iterator.
    00102    *  @return   result + (first - last)
    00103    *
    00104    *  Like copy(), but does not require an initialized output range.
    00105   */
    00106   template<typename _InputIterator, typename _ForwardIterator>
    00107     inline _ForwardIterator
    00108     uninitialized_copy(_InputIterator __first, _InputIterator __last,
    00109                _ForwardIterator __result)
    00110     {
    00111       typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
    00112       typedef typename std::__is_scalar<_ValueType>::__type _Is_POD;
    00113       return std::__uninitialized_copy_aux(__first, __last, __result,
    00114                        _Is_POD());
    00115     }
    00116
    00117   inline char*
    00118   uninitialized_copy(const char* __first, const char* __last, char* __result)
    00119   {
    00120     std::memmove(__result, __first, __last - __first);
    00121     return __result + (__last - __first);
    00122   }
    00123
    00124   inline wchar_t*
    00125   uninitialized_copy(const wchar_t* __first, const wchar_t* __last,
    00126              wchar_t* __result)
    00127   {
    00128     std::memmove(__result, __first, sizeof(wchar_t) * (__last - __first));
    00129     return __result + (__last - __first);
    00130   }
    00131
    00132   // Valid if copy construction is equivalent to assignment, and if the
    00133   // destructor is trivial.
    00134   template<typename _ForwardIterator, typename _Tp>
    00135     inline void
    00136     __uninitialized_fill_aux(_ForwardIterator __first,
    00137                  _ForwardIterator __last,
    00138                  const _Tp& __x, __true_type)
    00139     { std::fill(__first, __last, __x); }
    00140
    00141   template<typename _ForwardIterator, typename _Tp>
    00142     void
    00143     __uninitialized_fill_aux(_ForwardIterator __first, _ForwardIterator __last,
    00144                  const _Tp& __x, __false_type)
    00145     {
    00146       _ForwardIterator __cur = __first;
    00147       try
    00148     {
    00149       for (; __cur != __last; ++__cur)
    00150         std::_Construct(&*__cur, __x);
    00151     }
    00152       catch(...)
    00153     {
    00154       std::_Destroy(__first, __cur);
    00155       __throw_exception_again;
    00156     }
    00157     }
    00158
    00159   /**
    00160    *  @brief Copies the value x into the range [first,last).
    00161    *  @param  first  An input iterator.
    00162    *  @param  last   An input iterator.
    00163    *  @param  x      The source value.
    00164    *  @return   Nothing.
    00165    *
    00166    *  Like fill(), but does not require an initialized output range.
    00167   */
    00168   template<typename _ForwardIterator, typename _Tp>
    00169     inline void
    00170     uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
    00171                const _Tp& __x)
    00172     {
    00173       typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
    00174       typedef typename std::__is_scalar<_ValueType>::__type _Is_POD;
    00175       std::__uninitialized_fill_aux(__first, __last, __x, _Is_POD());
    00176     }
    00177
    00178   // Valid if copy construction is equivalent to assignment, and if the
    00179   //  destructor is trivial.
    00180   template<typename _ForwardIterator, typename _Size, typename _Tp>
    00181     inline void
    00182     __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n,
    00183                    const _Tp& __x, __true_type)
    00184     { std::fill_n(__first, __n, __x); }
    00185
    00186   template<typename _ForwardIterator, typename _Size, typename _Tp>
    00187     void
    00188     __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n,
    00189                    const _Tp& __x, __false_type)
    00190     {
    00191       _ForwardIterator __cur = __first;
    00192       try
    00193     {
    00194       for (; __n > 0; --__n, ++__cur)
    00195         std::_Construct(&*__cur, __x);
    00196     }
    00197       catch(...)
    00198     {
    00199       std::_Destroy(__first, __cur);
    00200       __throw_exception_again;
    00201     }
    00202     }
    00203
    00204   /**
    00205    *  @brief Copies the value x into the range [first,first+n).
    00206    *  @param  first  An input iterator.
    00207    *  @param  n      The number of copies to make.
    00208    *  @param  x      The source value.
    00209    *  @return   Nothing.
    00210    *
    00211    *  Like fill_n(), but does not require an initialized output range.
    00212   */
    00213   template<typename _ForwardIterator, typename _Size, typename _Tp>
    00214     inline void
    00215     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
    00216     {
    00217       typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
    00218       typedef typename std::__is_scalar<_ValueType>::__type _Is_POD;
    00219       std::__uninitialized_fill_n_aux(__first, __n, __x, _Is_POD());
    00220     }
    00221
    00222   // Extensions: versions of uninitialized_copy, uninitialized_fill,
    00223   //  and uninitialized_fill_n that take an allocator parameter.
    00224   //  We dispatch back to the standard versions when we're given the
    00225   //  default allocator.  For nondefault allocators we do not use
    00226   //  any of the POD optimizations.
    00227
    00228   template<typename _InputIterator, typename _ForwardIterator,
    00229        typename _Allocator>
    00230     _ForwardIterator
    00231     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
    00232                _ForwardIterator __result,
    00233                _Allocator __alloc)
    00234     {
    00235       _ForwardIterator __cur = __result;
    00236       try
    00237     {
    00238       for (; __first != __last; ++__first, ++__cur)
    00239         __alloc.construct(&*__cur, *__first);
    00240       return __cur;
    00241     }
    00242       catch(...)
    00243     {
    00244       std::_Destroy(__result, __cur, __alloc);
    00245       __throw_exception_again;
    00246     }
    00247     }
    00248
    00249   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
    00250     inline _ForwardIterator
    00251     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
    00252                _ForwardIterator __result,
    00253                allocator<_Tp>)
    00254     { return std::uninitialized_copy(__first, __last, __result); }
    00255
    00256   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
    00257     void
    00258     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
    00259                const _Tp& __x, _Allocator __alloc)
    00260     {
    00261       _ForwardIterator __cur = __first;
    00262       try
    00263     {
    00264       for (; __cur != __last; ++__cur)
    00265         __alloc.construct(&*__cur, __x);
    00266     }
    00267       catch(...)
    00268     {
    00269       std::_Destroy(__first, __cur, __alloc);
    00270       __throw_exception_again;
    00271     }
    00272     }
    00273
    00274   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
    00275     inline void
    00276     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
    00277                const _Tp& __x, allocator<_Tp2>)
    00278     { std::uninitialized_fill(__first, __last, __x); }
    00279
    00280   template<typename _ForwardIterator, typename _Size, typename _Tp,
    00281        typename _Allocator>
    00282     void
    00283     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
    00284                  const _Tp& __x,
    00285                  _Allocator __alloc)
    00286     {
    00287       _ForwardIterator __cur = __first;
    00288       try
    00289     {
    00290       for (; __n > 0; --__n, ++__cur)
    00291         __alloc.construct(&*__cur, __x);
    00292     }
    00293       catch(...)
    00294     {
    00295       std::_Destroy(__first, __cur, __alloc);
    00296       __throw_exception_again;
    00297     }
    00298     }
    00299
    00300   template<typename _ForwardIterator, typename _Size, typename _Tp,
    00301        typename _Tp2>
    00302     inline void
    00303     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
    00304                  const _Tp& __x,
    00305                  allocator<_Tp2>)
    00306     { std::uninitialized_fill_n(__first, __n, __x); }
    00307
    00308
    00309   // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill,
    00310   // __uninitialized_fill_copy.  All of these algorithms take a user-
    00311   // supplied allocator, which is used for construction and destruction.
    00312
    00313   // __uninitialized_copy_copy
    00314   // Copies [first1, last1) into [result, result + (last1 - first1)), and
    00315   //  copies [first2, last2) into
    00316   //  [result, result + (last1 - first1) + (last2 - first2)).
    00317
    00318   template<typename _InputIterator1, typename _InputIterator2,
    00319        typename _ForwardIterator, typename _Allocator>
    00320     inline _ForwardIterator
    00321     __uninitialized_copy_copy(_InputIterator1 __first1,
    00322                   _InputIterator1 __last1,
    00323                   _InputIterator2 __first2,
    00324                   _InputIterator2 __last2,
    00325                   _ForwardIterator __result,
    00326                   _Allocator __alloc)
    00327     {
    00328       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
    00329                                __result,
    00330                                __alloc);
    00331       try
    00332     {
    00333       return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
    00334     }
    00335       catch(...)
    00336     {
    00337       std::_Destroy(__result, __mid, __alloc);
    00338       __throw_exception_again;
    00339     }
    00340     }
    00341
    00342   // __uninitialized_fill_copy
    00343   // Fills [result, mid) with x, and copies [first, last) into
    00344   //  [mid, mid + (last - first)).
    00345   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
    00346        typename _Allocator>
    00347     inline _ForwardIterator
    00348     __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid,
    00349                   const _Tp& __x, _InputIterator __first,
    00350                   _InputIterator __last,
    00351                   _Allocator __alloc)
    00352     {
    00353       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
    00354       try
    00355     {
    00356       return std::__uninitialized_copy_a(__first, __last, __mid, __alloc);
    00357     }
    00358       catch(...)
    00359     {
    00360       std::_Destroy(__result, __mid, __alloc);
    00361       __throw_exception_again;
    00362     }
    00363     }
    00364
    00365   // __uninitialized_copy_fill
    00366   // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and
    00367   //  fills [first2 + (last1 - first1), last2) with x.
    00368   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
    00369        typename _Allocator>
    00370     inline void
    00371     __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1,
    00372                   _ForwardIterator __first2,
    00373                   _ForwardIterator __last2, const _Tp& __x,
    00374                   _Allocator __alloc)
    00375     {
    00376       _ForwardIterator __mid2 = std::__uninitialized_copy_a(__first1, __last1,
    00377                                 __first2,
    00378                                 __alloc);
    00379       try
    00380     {
    00381       std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
    00382     }
    00383       catch(...)
    00384     {
    00385       std::_Destroy(__first2, __mid2, __alloc);
    00386       __throw_exception_again;
    00387     }
    00388     }
    00389
    00390 _GLIBCXX_END_NAMESPACE
    00391
    00392 #endif /* _STL_UNINITIALIZED_H */