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 bits/stl_uninitialized.h
00054  *  This is an internal header file, included by other library headers.
00055  *  Do not attempt to use it directly. @headername{memory}
00056  */
00057 
00058 #ifndef _STL_UNINITIALIZED_H
00059 #define _STL_UNINITIALIZED_H 1
00060 
00061 namespace std _GLIBCXX_VISIBILITY(default)
00062 {
00063 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00064 
00065   template<bool _TrivialValueTypes>
00066     struct __uninitialized_copy
00067     {
00068       template<typename _InputIterator, typename _ForwardIterator>
00069         static _ForwardIterator
00070         __uninit_copy(_InputIterator __first, _InputIterator __last,
00071               _ForwardIterator __result)
00072         {
00073       _ForwardIterator __cur = __result;
00074       __try
00075         {
00076           for (; __first != __last; ++__first, ++__cur)
00077         std::_Construct(std::__addressof(*__cur), *__first);
00078           return __cur;
00079         }
00080       __catch(...)
00081         {
00082           std::_Destroy(__result, __cur);
00083           __throw_exception_again;
00084         }
00085     }
00086     };
00087 
00088   template<>
00089     struct __uninitialized_copy<true>
00090     {
00091       template<typename _InputIterator, typename _ForwardIterator>
00092         static _ForwardIterator
00093         __uninit_copy(_InputIterator __first, _InputIterator __last,
00094               _ForwardIterator __result)
00095         { return std::copy(__first, __last, __result); }
00096     };
00097 
00098   /**
00099    *  @brief Copies the range [first,last) into result.
00100    *  @param  first  An input iterator.
00101    *  @param  last   An input iterator.
00102    *  @param  result An output iterator.
00103    *  @return   result + (first - last)
00104    *
00105    *  Like copy(), but does not require an initialized output range.
00106   */
00107   template<typename _InputIterator, typename _ForwardIterator>
00108     inline _ForwardIterator
00109     uninitialized_copy(_InputIterator __first, _InputIterator __last,
00110                _ForwardIterator __result)
00111     {
00112       typedef typename iterator_traits<_InputIterator>::value_type
00113     _ValueType1;
00114       typedef typename iterator_traits<_ForwardIterator>::value_type
00115     _ValueType2;
00116 
00117       return std::__uninitialized_copy<(__is_trivial(_ValueType1)
00118                     && __is_trivial(_ValueType2))>::
00119     __uninit_copy(__first, __last, __result);
00120     }
00121 
00122 
00123   template<bool _TrivialValueType>
00124     struct __uninitialized_fill
00125     {
00126       template<typename _ForwardIterator, typename _Tp>
00127         static void
00128         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
00129               const _Tp& __x)
00130         {
00131       _ForwardIterator __cur = __first;
00132       __try
00133         {
00134           for (; __cur != __last; ++__cur)
00135         std::_Construct(std::__addressof(*__cur), __x);
00136         }
00137       __catch(...)
00138         {
00139           std::_Destroy(__first, __cur);
00140           __throw_exception_again;
00141         }
00142     }
00143     };
00144 
00145   template<>
00146     struct __uninitialized_fill<true>
00147     {
00148       template<typename _ForwardIterator, typename _Tp>
00149         static void
00150         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
00151               const _Tp& __x)
00152         { std::fill(__first, __last, __x); }
00153     };
00154 
00155   /**
00156    *  @brief Copies the value x into the range [first,last).
00157    *  @param  first  An input iterator.
00158    *  @param  last   An input iterator.
00159    *  @param  x      The source value.
00160    *  @return   Nothing.
00161    *
00162    *  Like fill(), but does not require an initialized output range.
00163   */
00164   template<typename _ForwardIterator, typename _Tp>
00165     inline void
00166     uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
00167                const _Tp& __x)
00168     {
00169       typedef typename iterator_traits<_ForwardIterator>::value_type
00170     _ValueType;
00171 
00172       std::__uninitialized_fill<__is_trivial(_ValueType)>::
00173     __uninit_fill(__first, __last, __x);
00174     }
00175 
00176 
00177   template<bool _TrivialValueType>
00178     struct __uninitialized_fill_n
00179     {
00180       template<typename _ForwardIterator, typename _Size, typename _Tp>
00181         static void
00182         __uninit_fill_n(_ForwardIterator __first, _Size __n,
00183             const _Tp& __x)
00184         {
00185       _ForwardIterator __cur = __first;
00186       __try
00187         {
00188           for (; __n > 0; --__n, ++__cur)
00189         std::_Construct(std::__addressof(*__cur), __x);
00190         }
00191       __catch(...)
00192         {
00193           std::_Destroy(__first, __cur);
00194           __throw_exception_again;
00195         }
00196     }
00197     };
00198 
00199   template<>
00200     struct __uninitialized_fill_n<true>
00201     {
00202       template<typename _ForwardIterator, typename _Size, typename _Tp>
00203         static void
00204         __uninit_fill_n(_ForwardIterator __first, _Size __n,
00205             const _Tp& __x)
00206         { std::fill_n(__first, __n, __x); }
00207     };
00208 
00209   /**
00210    *  @brief Copies the value x into the range [first,first+n).
00211    *  @param  first  An input iterator.
00212    *  @param  n      The number of copies to make.
00213    *  @param  x      The source value.
00214    *  @return   Nothing.
00215    *
00216    *  Like fill_n(), but does not require an initialized output range.
00217   */
00218   template<typename _ForwardIterator, typename _Size, typename _Tp>
00219     inline void
00220     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
00221     {
00222       typedef typename iterator_traits<_ForwardIterator>::value_type
00223     _ValueType;
00224 
00225       std::__uninitialized_fill_n<__is_trivial(_ValueType)>::
00226     __uninit_fill_n(__first, __n, __x);
00227     }
00228 
00229   // Extensions: versions of uninitialized_copy, uninitialized_fill,
00230   //  and uninitialized_fill_n that take an allocator parameter.
00231   //  We dispatch back to the standard versions when we're given the
00232   //  default allocator.  For nondefault allocators we do not use 
00233   //  any of the POD optimizations.
00234 
00235   template<typename _InputIterator, typename _ForwardIterator,
00236        typename _Allocator>
00237     _ForwardIterator
00238     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
00239                _ForwardIterator __result, _Allocator& __alloc)
00240     {
00241       _ForwardIterator __cur = __result;
00242       __try
00243     {
00244       for (; __first != __last; ++__first, ++__cur)
00245         __alloc.construct(std::__addressof(*__cur), *__first);
00246       return __cur;
00247     }
00248       __catch(...)
00249     {
00250       std::_Destroy(__result, __cur, __alloc);
00251       __throw_exception_again;
00252     }
00253     }
00254 
00255   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
00256     inline _ForwardIterator
00257     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
00258                _ForwardIterator __result, allocator<_Tp>&)
00259     { return std::uninitialized_copy(__first, __last, __result); }
00260 
00261   template<typename _InputIterator, typename _ForwardIterator,
00262        typename _Allocator>
00263     inline _ForwardIterator
00264     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
00265                _ForwardIterator __result, _Allocator& __alloc)
00266     {
00267       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
00268                      _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
00269                      __result, __alloc);
00270     }
00271 
00272   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
00273     void
00274     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
00275                const _Tp& __x, _Allocator& __alloc)
00276     {
00277       _ForwardIterator __cur = __first;
00278       __try
00279     {
00280       for (; __cur != __last; ++__cur)
00281         __alloc.construct(std::__addressof(*__cur), __x);
00282     }
00283       __catch(...)
00284     {
00285       std::_Destroy(__first, __cur, __alloc);
00286       __throw_exception_again;
00287     }
00288     }
00289 
00290   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
00291     inline void
00292     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
00293                const _Tp& __x, allocator<_Tp2>&)
00294     { std::uninitialized_fill(__first, __last, __x); }
00295 
00296   template<typename _ForwardIterator, typename _Size, typename _Tp,
00297        typename _Allocator>
00298     void
00299     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
00300                  const _Tp& __x, _Allocator& __alloc)
00301     {
00302       _ForwardIterator __cur = __first;
00303       __try
00304     {
00305       for (; __n > 0; --__n, ++__cur)
00306         __alloc.construct(std::__addressof(*__cur), __x);
00307     }
00308       __catch(...)
00309     {
00310       std::_Destroy(__first, __cur, __alloc);
00311       __throw_exception_again;
00312     }
00313     }
00314 
00315   template<typename _ForwardIterator, typename _Size, typename _Tp,
00316        typename _Tp2>
00317     inline void
00318     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
00319                  const _Tp& __x, allocator<_Tp2>&)
00320     { std::uninitialized_fill_n(__first, __n, __x); }
00321 
00322 
00323   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
00324   // __uninitialized_fill_move, __uninitialized_move_fill.
00325   // All of these algorithms take a user-supplied allocator, which is used
00326   // for construction and destruction.
00327 
00328   // __uninitialized_copy_move
00329   // Copies [first1, last1) into [result, result + (last1 - first1)), and
00330   //  move [first2, last2) into
00331   //  [result, result + (last1 - first1) + (last2 - first2)).
00332   template<typename _InputIterator1, typename _InputIterator2,
00333        typename _ForwardIterator, typename _Allocator>
00334     inline _ForwardIterator
00335     __uninitialized_copy_move(_InputIterator1 __first1,
00336                   _InputIterator1 __last1,
00337                   _InputIterator2 __first2,
00338                   _InputIterator2 __last2,
00339                   _ForwardIterator __result,
00340                   _Allocator& __alloc)
00341     {
00342       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
00343                                __result,
00344                                __alloc);
00345       __try
00346     {
00347       return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
00348     }
00349       __catch(...)
00350     {
00351       std::_Destroy(__result, __mid, __alloc);
00352       __throw_exception_again;
00353     }
00354     }
00355 
00356   // __uninitialized_move_copy
00357   // Moves [first1, last1) into [result, result + (last1 - first1)), and
00358   //  copies [first2, last2) into
00359   //  [result, result + (last1 - first1) + (last2 - first2)).
00360   template<typename _InputIterator1, typename _InputIterator2,
00361        typename _ForwardIterator, typename _Allocator>
00362     inline _ForwardIterator
00363     __uninitialized_move_copy(_InputIterator1 __first1,
00364                   _InputIterator1 __last1,
00365                   _InputIterator2 __first2,
00366                   _InputIterator2 __last2,
00367                   _ForwardIterator __result,
00368                   _Allocator& __alloc)
00369     {
00370       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
00371                                __result,
00372                                __alloc);
00373       __try
00374     {
00375       return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
00376     }
00377       __catch(...)
00378     {
00379       std::_Destroy(__result, __mid, __alloc);
00380       __throw_exception_again;
00381     }
00382     }
00383   
00384   // __uninitialized_fill_move
00385   // Fills [result, mid) with x, and moves [first, last) into
00386   //  [mid, mid + (last - first)).
00387   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
00388        typename _Allocator>
00389     inline _ForwardIterator
00390     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
00391                   const _Tp& __x, _InputIterator __first,
00392                   _InputIterator __last, _Allocator& __alloc)
00393     {
00394       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
00395       __try
00396     {
00397       return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
00398     }
00399       __catch(...)
00400     {
00401       std::_Destroy(__result, __mid, __alloc);
00402       __throw_exception_again;
00403     }
00404     }
00405 
00406   // __uninitialized_move_fill
00407   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
00408   //  fills [first2 + (last1 - first1), last2) with x.
00409   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
00410        typename _Allocator>
00411     inline void
00412     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
00413                   _ForwardIterator __first2,
00414                   _ForwardIterator __last2, const _Tp& __x,
00415                   _Allocator& __alloc)
00416     {
00417       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
00418                                 __first2,
00419                                 __alloc);
00420       __try
00421     {
00422       std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
00423     }
00424       __catch(...)
00425     {
00426       std::_Destroy(__first2, __mid2, __alloc);
00427       __throw_exception_again;
00428     }
00429     }
00430 
00431 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00432   // Extensions: __uninitialized_default, __uninitialized_default_n,
00433   // __uninitialized_default_a, __uninitialized_default_n_a.
00434 
00435   template<bool _TrivialValueType>
00436     struct __uninitialized_default_1
00437     {
00438       template<typename _ForwardIterator>
00439         static void
00440         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
00441         {
00442       _ForwardIterator __cur = __first;
00443       __try
00444         {
00445           for (; __cur != __last; ++__cur)
00446         std::_Construct(std::__addressof(*__cur));
00447         }
00448       __catch(...)
00449         {
00450           std::_Destroy(__first, __cur);
00451           __throw_exception_again;
00452         }
00453     }
00454     };
00455 
00456   template<>
00457     struct __uninitialized_default_1<true>
00458     {
00459       template<typename _ForwardIterator>
00460         static void
00461         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
00462         {
00463       typedef typename iterator_traits<_ForwardIterator>::value_type
00464         _ValueType;
00465 
00466       std::fill(__first, __last, _ValueType());
00467     }
00468     };
00469 
00470   template<bool _TrivialValueType>
00471     struct __uninitialized_default_n_1
00472     {
00473       template<typename _ForwardIterator, typename _Size>
00474         static void
00475         __uninit_default_n(_ForwardIterator __first, _Size __n)
00476         {
00477       _ForwardIterator __cur = __first;
00478       __try
00479         {
00480           for (; __n > 0; --__n, ++__cur)
00481         std::_Construct(std::__addressof(*__cur));
00482         }
00483       __catch(...)
00484         {
00485           std::_Destroy(__first, __cur);
00486           __throw_exception_again;
00487         }
00488     }
00489     };
00490 
00491   template<>
00492     struct __uninitialized_default_n_1<true>
00493     {
00494       template<typename _ForwardIterator, typename _Size>
00495         static void
00496         __uninit_default_n(_ForwardIterator __first, _Size __n)
00497         {
00498       typedef typename iterator_traits<_ForwardIterator>::value_type
00499         _ValueType;
00500 
00501       std::fill_n(__first, __n, _ValueType());
00502     }
00503     };
00504 
00505   // __uninitialized_default
00506   // Fills [first, last) with std::distance(first, last) default
00507   // constructed value_types(s).
00508   template<typename _ForwardIterator>
00509     inline void
00510     __uninitialized_default(_ForwardIterator __first,
00511                 _ForwardIterator __last)
00512     {
00513       typedef typename iterator_traits<_ForwardIterator>::value_type
00514     _ValueType;
00515 
00516       std::__uninitialized_default_1<__is_trivial(_ValueType)>::
00517     __uninit_default(__first, __last);
00518     }
00519 
00520   // __uninitialized_default_n
00521   // Fills [first, first + n) with n default constructed value_type(s).
00522   template<typename _ForwardIterator, typename _Size>
00523     inline void
00524     __uninitialized_default_n(_ForwardIterator __first, _Size __n)
00525     {
00526       typedef typename iterator_traits<_ForwardIterator>::value_type
00527     _ValueType;
00528 
00529       std::__uninitialized_default_n_1<__is_trivial(_ValueType)>::
00530     __uninit_default_n(__first, __n);
00531     }
00532 
00533 
00534   // __uninitialized_default_a
00535   // Fills [first, last) with std::distance(first, last) default
00536   // constructed value_types(s), constructed with the allocator alloc.
00537   template<typename _ForwardIterator, typename _Allocator>
00538     void
00539     __uninitialized_default_a(_ForwardIterator __first,
00540                   _ForwardIterator __last,
00541                   _Allocator& __alloc)
00542     {
00543       _ForwardIterator __cur = __first;
00544       __try
00545     {
00546       for (; __cur != __last; ++__cur)
00547         __alloc.construct(std::__addressof(*__cur));
00548     }
00549       __catch(...)
00550     {
00551       std::_Destroy(__first, __cur, __alloc);
00552       __throw_exception_again;
00553     }
00554     }
00555 
00556   template<typename _ForwardIterator, typename _Tp>
00557     inline void
00558     __uninitialized_default_a(_ForwardIterator __first,
00559                   _ForwardIterator __last,
00560                   allocator<_Tp>&)
00561     { std::__uninitialized_default(__first, __last); }
00562 
00563 
00564   // __uninitialized_default_n_a
00565   // Fills [first, first + n) with n default constructed value_types(s),
00566   // constructed with the allocator alloc.
00567   template<typename _ForwardIterator, typename _Size, typename _Allocator>
00568     void
00569     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
00570                 _Allocator& __alloc)
00571     {
00572       _ForwardIterator __cur = __first;
00573       __try
00574     {
00575       for (; __n > 0; --__n, ++__cur)
00576         __alloc.construct(std::__addressof(*__cur));
00577     }
00578       __catch(...)
00579     {
00580       std::_Destroy(__first, __cur, __alloc);
00581       __throw_exception_again;
00582     }
00583     }
00584 
00585   template<typename _ForwardIterator, typename _Size, typename _Tp>
00586     inline void
00587     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
00588                 allocator<_Tp>&)
00589     { std::__uninitialized_default_n(__first, __n); }
00590 
00591 
00592   template<typename _InputIterator, typename _Size,
00593        typename _ForwardIterator>
00594     _ForwardIterator
00595     __uninitialized_copy_n(_InputIterator __first, _Size __n,
00596                _ForwardIterator __result, input_iterator_tag)
00597     {
00598       _ForwardIterator __cur = __result;
00599       __try
00600     {
00601       for (; __n > 0; --__n, ++__first, ++__cur)
00602         std::_Construct(std::__addressof(*__cur), *__first);
00603       return __cur;
00604     }
00605       __catch(...)
00606     {
00607       std::_Destroy(__result, __cur);
00608       __throw_exception_again;
00609     }
00610     }
00611 
00612   template<typename _RandomAccessIterator, typename _Size,
00613        typename _ForwardIterator>
00614     inline _ForwardIterator
00615     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
00616                _ForwardIterator __result,
00617                random_access_iterator_tag)
00618     { return std::uninitialized_copy(__first, __first + __n, __result); }
00619 
00620   /**
00621    *  @brief Copies the range [first,first+n) into result.
00622    *  @param  first  An input iterator.
00623    *  @param  n      The number of elements to copy.
00624    *  @param  result An output iterator.
00625    *  @return  result + n
00626    *
00627    *  Like copy_n(), but does not require an initialized output range.
00628   */
00629   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
00630     inline _ForwardIterator
00631     uninitialized_copy_n(_InputIterator __first, _Size __n,
00632              _ForwardIterator __result)
00633     { return std::__uninitialized_copy_n(__first, __n, __result,
00634                      std::__iterator_category(__first)); }
00635 #endif
00636 
00637 _GLIBCXX_END_NAMESPACE_VERSION
00638 } // namespace
00639 
00640 #endif /* _STL_UNINITIALIZED_H */