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 */

Generated on Wed Dec 31 12:49:03 2008 for libstdc++ by  doxygen 1.5.6