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,
00004 // 2009, 2010
00005 // Free Software Foundation, Inc.
00006 //
00007 // This file is part of the GNU ISO C++ Library.  This library is free
00008 // software; you can redistribute it and/or modify it under the
00009 // terms of the GNU General Public License as published by the
00010 // Free Software Foundation; either version 3, or (at your option)
00011 // any later version.
00012 
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 
00018 // Under Section 7 of GPL version 3, you are granted additional
00019 // permissions described in the GCC Runtime Library Exception, version
00020 // 3.1, as published by the Free Software Foundation.
00021 
00022 // You should have received a copy of the GNU General Public License and
00023 // a copy of the GCC Runtime Library Exception along with this program;
00024 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00025 // <http://www.gnu.org/licenses/>.
00026 
00027 /*
00028  *
00029  * Copyright (c) 1994
00030  * Hewlett-Packard Company
00031  *
00032  * Permission to use, copy, modify, distribute and sell this software
00033  * and its documentation for any purpose is hereby granted without fee,
00034  * provided that the above copyright notice appear in all copies and
00035  * that both that copyright notice and this permission notice appear
00036  * in supporting documentation.  Hewlett-Packard Company makes no
00037  * representations about the suitability of this software for any
00038  * purpose.  It is provided "as is" without express or implied warranty.
00039  *
00040  *
00041  * Copyright (c) 1996,1997
00042  * Silicon Graphics Computer Systems, Inc.
00043  *
00044  * Permission to use, copy, modify, distribute and sell this software
00045  * and its documentation for any purpose is hereby granted without fee,
00046  * provided that the above copyright notice appear in all copies and
00047  * that both that copyright notice and this permission notice appear
00048  * in supporting documentation.  Silicon Graphics makes no
00049  * representations about the suitability of this software for any
00050  * purpose.  It is provided "as is" without express or implied warranty.
00051  */
00052 
00053 /** @file stl_uninitialized.h
00054  *  This is an internal header file, included by other library headers.
00055  *  You should not attempt to use it directly.
00056  */
00057 
00058 #ifndef _STL_UNINITIALIZED_H
00059 #define _STL_UNINITIALIZED_H 1
00060 
00061 _GLIBCXX_BEGIN_NAMESPACE(std)
00062 
00063   template<bool _TrivialValueTypes>
00064     struct __uninitialized_copy
00065     {
00066       template<typename _InputIterator, typename _ForwardIterator>
00067         static _ForwardIterator
00068         __uninit_copy(_InputIterator __first, _InputIterator __last,
00069               _ForwardIterator __result)
00070         {
00071       _ForwardIterator __cur = __result;
00072       __try
00073         {
00074           for (; __first != __last; ++__first, ++__cur)
00075         std::_Construct(std::__addressof(*__cur), *__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         __uninit_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_trivial(_ValueType1)
00116                     && __is_trivial(_ValueType2))>::
00117     __uninit_copy(__first, __last, __result);
00118     }
00119 
00120 
00121   template<bool _TrivialValueType>
00122     struct __uninitialized_fill
00123     {
00124       template<typename _ForwardIterator, typename _Tp>
00125         static void
00126         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
00127               const _Tp& __x)
00128         {
00129       _ForwardIterator __cur = __first;
00130       __try
00131         {
00132           for (; __cur != __last; ++__cur)
00133         std::_Construct(std::__addressof(*__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         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
00149               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_trivial(_ValueType)>::
00171     __uninit_fill(__first, __last, __x);
00172     }
00173 
00174 
00175   template<bool _TrivialValueType>
00176     struct __uninitialized_fill_n
00177     {
00178       template<typename _ForwardIterator, typename _Size, typename _Tp>
00179         static void
00180         __uninit_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(std::__addressof(*__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         __uninit_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_trivial(_ValueType)>::
00224     __uninit_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(std::__addressof(*__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(std::__addressof(*__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(std::__addressof(*__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   // Extensions: __uninitialized_default, __uninitialized_default_n,
00431   // __uninitialized_default_a, __uninitialized_default_n_a.
00432 
00433   template<bool _TrivialValueType>
00434     struct __uninitialized_default_1
00435     {
00436       template<typename _ForwardIterator>
00437         static void
00438         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
00439         {
00440       _ForwardIterator __cur = __first;
00441       __try
00442         {
00443           for (; __cur != __last; ++__cur)
00444         std::_Construct(std::__addressof(*__cur));
00445         }
00446       __catch(...)
00447         {
00448           std::_Destroy(__first, __cur);
00449           __throw_exception_again;
00450         }
00451     }
00452     };
00453 
00454   template<>
00455     struct __uninitialized_default_1<true>
00456     {
00457       template<typename _ForwardIterator>
00458         static void
00459         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
00460         {
00461       typedef typename iterator_traits<_ForwardIterator>::value_type
00462         _ValueType;
00463 
00464       std::fill(__first, __last, _ValueType());
00465     }
00466     };
00467 
00468   template<bool _TrivialValueType>
00469     struct __uninitialized_default_n_1
00470     {
00471       template<typename _ForwardIterator, typename _Size>
00472         static void
00473         __uninit_default_n(_ForwardIterator __first, _Size __n)
00474         {
00475       _ForwardIterator __cur = __first;
00476       __try
00477         {
00478           for (; __n > 0; --__n, ++__cur)
00479         std::_Construct(std::__addressof(*__cur));
00480         }
00481       __catch(...)
00482         {
00483           std::_Destroy(__first, __cur);
00484           __throw_exception_again;
00485         }
00486     }
00487     };
00488 
00489   template<>
00490     struct __uninitialized_default_n_1<true>
00491     {
00492       template<typename _ForwardIterator, typename _Size>
00493         static void
00494         __uninit_default_n(_ForwardIterator __first, _Size __n)
00495         {
00496       typedef typename iterator_traits<_ForwardIterator>::value_type
00497         _ValueType;
00498 
00499       std::fill_n(__first, __n, _ValueType());
00500     }
00501     };
00502 
00503   // __uninitialized_default
00504   // Fills [first, last) with std::distance(first, last) default
00505   // constructed value_types(s).
00506   template<typename _ForwardIterator>
00507     inline void
00508     __uninitialized_default(_ForwardIterator __first,
00509                 _ForwardIterator __last)
00510     {
00511       typedef typename iterator_traits<_ForwardIterator>::value_type
00512     _ValueType;
00513 
00514       std::__uninitialized_default_1<__is_trivial(_ValueType)>::
00515     __uninit_default(__first, __last);
00516     }
00517 
00518   // __uninitialized_default_n
00519   // Fills [first, first + n) with n default constructed value_type(s).
00520   template<typename _ForwardIterator, typename _Size>
00521     inline void
00522     __uninitialized_default_n(_ForwardIterator __first, _Size __n)
00523     {
00524       typedef typename iterator_traits<_ForwardIterator>::value_type
00525     _ValueType;
00526 
00527       std::__uninitialized_default_n_1<__is_trivial(_ValueType)>::
00528     __uninit_default_n(__first, __n);
00529     }
00530 
00531 
00532   // __uninitialized_default_a
00533   // Fills [first, last) with std::distance(first, last) default
00534   // constructed value_types(s), constructed with the allocator alloc.
00535   template<typename _ForwardIterator, typename _Allocator>
00536     void
00537     __uninitialized_default_a(_ForwardIterator __first,
00538                   _ForwardIterator __last,
00539                   _Allocator& __alloc)
00540     {
00541       _ForwardIterator __cur = __first;
00542       __try
00543     {
00544       for (; __cur != __last; ++__cur)
00545         __alloc.construct(std::__addressof(*__cur));
00546     }
00547       __catch(...)
00548     {
00549       std::_Destroy(__first, __cur, __alloc);
00550       __throw_exception_again;
00551     }
00552     }
00553 
00554   template<typename _ForwardIterator, typename _Tp>
00555     inline void
00556     __uninitialized_default_a(_ForwardIterator __first,
00557                   _ForwardIterator __last,
00558                   allocator<_Tp>&)
00559     { std::__uninitialized_default(__first, __last); }
00560 
00561 
00562   // __uninitialized_default_n_a
00563   // Fills [first, first + n) with n default constructed value_types(s),
00564   // constructed with the allocator alloc.
00565   template<typename _ForwardIterator, typename _Size, typename _Allocator>
00566     void
00567     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
00568                 _Allocator& __alloc)
00569     {
00570       _ForwardIterator __cur = __first;
00571       __try
00572     {
00573       for (; __n > 0; --__n, ++__cur)
00574         __alloc.construct(std::__addressof(*__cur));
00575     }
00576       __catch(...)
00577     {
00578       std::_Destroy(__first, __cur, __alloc);
00579       __throw_exception_again;
00580     }
00581     }
00582 
00583   template<typename _ForwardIterator, typename _Size, typename _Tp>
00584     inline void
00585     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
00586                 allocator<_Tp>&)
00587     { std::__uninitialized_default_n(__first, __n); }
00588 
00589 
00590   template<typename _InputIterator, typename _Size,
00591        typename _ForwardIterator>
00592     _ForwardIterator
00593     __uninitialized_copy_n(_InputIterator __first, _Size __n,
00594                _ForwardIterator __result, input_iterator_tag)
00595     {
00596       _ForwardIterator __cur = __result;
00597       __try
00598     {
00599       for (; __n > 0; --__n, ++__first, ++__cur)
00600         std::_Construct(std::__addressof(*__cur), *__first);
00601       return __cur;
00602     }
00603       __catch(...)
00604     {
00605       std::_Destroy(__result, __cur);
00606       __throw_exception_again;
00607     }
00608     }
00609 
00610   template<typename _RandomAccessIterator, typename _Size,
00611        typename _ForwardIterator>
00612     inline _ForwardIterator
00613     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
00614                _ForwardIterator __result,
00615                random_access_iterator_tag)
00616     { return std::uninitialized_copy(__first, __first + __n, __result); }
00617 
00618   /**
00619    *  @brief Copies the range [first,first+n) into result.
00620    *  @param  first  An input iterator.
00621    *  @param  n      The number of elements to copy.
00622    *  @param  result An output iterator.
00623    *  @return  result + n
00624    *
00625    *  Like copy_n(), but does not require an initialized output range.
00626   */
00627   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
00628     inline _ForwardIterator
00629     uninitialized_copy_n(_InputIterator __first, _Size __n,
00630              _ForwardIterator __result)
00631     { return std::__uninitialized_copy_n(__first, __n, __result,
00632                      std::__iterator_category(__first)); }
00633 #endif
00634 
00635 _GLIBCXX_END_NAMESPACE
00636 
00637 #endif /* _STL_UNINITIALIZED_H */