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

Generated on Tue Apr 21 13:13:32 2009 for libstdc++ by  doxygen 1.5.8