libstdc++
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, 2011
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       typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00245       for (; __first != __last; ++__first, ++__cur)
00246         __traits::construct(__alloc, std::__addressof(*__cur), *__first);
00247       return __cur;
00248     }
00249       __catch(...)
00250     {
00251       std::_Destroy(__result, __cur, __alloc);
00252       __throw_exception_again;
00253     }
00254     }
00255 
00256   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
00257     inline _ForwardIterator
00258     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
00259                _ForwardIterator __result, allocator<_Tp>&)
00260     { return std::uninitialized_copy(__first, __last, __result); }
00261 
00262   template<typename _InputIterator, typename _ForwardIterator,
00263        typename _Allocator>
00264     inline _ForwardIterator
00265     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
00266                _ForwardIterator __result, _Allocator& __alloc)
00267     {
00268       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
00269                      _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
00270                      __result, __alloc);
00271     }
00272 
00273   template<typename _InputIterator, typename _ForwardIterator,
00274        typename _Allocator>
00275     inline _ForwardIterator
00276     __uninitialized_move_if_noexcept_a(_InputIterator __first,
00277                        _InputIterator __last,
00278                        _ForwardIterator __result,
00279                        _Allocator& __alloc)
00280     {
00281       return std::__uninitialized_copy_a
00282     (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
00283      _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
00284     }
00285 
00286   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
00287     void
00288     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
00289                const _Tp& __x, _Allocator& __alloc)
00290     {
00291       _ForwardIterator __cur = __first;
00292       __try
00293     {
00294       typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00295       for (; __cur != __last; ++__cur)
00296         __traits::construct(__alloc, std::__addressof(*__cur), __x);
00297     }
00298       __catch(...)
00299     {
00300       std::_Destroy(__first, __cur, __alloc);
00301       __throw_exception_again;
00302     }
00303     }
00304 
00305   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
00306     inline void
00307     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
00308                const _Tp& __x, allocator<_Tp2>&)
00309     { std::uninitialized_fill(__first, __last, __x); }
00310 
00311   template<typename _ForwardIterator, typename _Size, typename _Tp,
00312        typename _Allocator>
00313     void
00314     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
00315                  const _Tp& __x, _Allocator& __alloc)
00316     {
00317       _ForwardIterator __cur = __first;
00318       __try
00319     {
00320       typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00321       for (; __n > 0; --__n, ++__cur)
00322         __traits::construct(__alloc, std::__addressof(*__cur), __x);
00323     }
00324       __catch(...)
00325     {
00326       std::_Destroy(__first, __cur, __alloc);
00327       __throw_exception_again;
00328     }
00329     }
00330 
00331   template<typename _ForwardIterator, typename _Size, typename _Tp,
00332        typename _Tp2>
00333     inline void
00334     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
00335                  const _Tp& __x, allocator<_Tp2>&)
00336     { std::uninitialized_fill_n(__first, __n, __x); }
00337 
00338 
00339   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
00340   // __uninitialized_fill_move, __uninitialized_move_fill.
00341   // All of these algorithms take a user-supplied allocator, which is used
00342   // for construction and destruction.
00343 
00344   // __uninitialized_copy_move
00345   // Copies [first1, last1) into [result, result + (last1 - first1)), and
00346   //  move [first2, last2) into
00347   //  [result, result + (last1 - first1) + (last2 - first2)).
00348   template<typename _InputIterator1, typename _InputIterator2,
00349        typename _ForwardIterator, typename _Allocator>
00350     inline _ForwardIterator
00351     __uninitialized_copy_move(_InputIterator1 __first1,
00352                   _InputIterator1 __last1,
00353                   _InputIterator2 __first2,
00354                   _InputIterator2 __last2,
00355                   _ForwardIterator __result,
00356                   _Allocator& __alloc)
00357     {
00358       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
00359                                __result,
00360                                __alloc);
00361       __try
00362     {
00363       return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
00364     }
00365       __catch(...)
00366     {
00367       std::_Destroy(__result, __mid, __alloc);
00368       __throw_exception_again;
00369     }
00370     }
00371 
00372   // __uninitialized_move_copy
00373   // Moves [first1, last1) into [result, result + (last1 - first1)), and
00374   //  copies [first2, last2) into
00375   //  [result, result + (last1 - first1) + (last2 - first2)).
00376   template<typename _InputIterator1, typename _InputIterator2,
00377        typename _ForwardIterator, typename _Allocator>
00378     inline _ForwardIterator
00379     __uninitialized_move_copy(_InputIterator1 __first1,
00380                   _InputIterator1 __last1,
00381                   _InputIterator2 __first2,
00382                   _InputIterator2 __last2,
00383                   _ForwardIterator __result,
00384                   _Allocator& __alloc)
00385     {
00386       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
00387                                __result,
00388                                __alloc);
00389       __try
00390     {
00391       return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
00392     }
00393       __catch(...)
00394     {
00395       std::_Destroy(__result, __mid, __alloc);
00396       __throw_exception_again;
00397     }
00398     }
00399   
00400   // __uninitialized_fill_move
00401   // Fills [result, mid) with x, and moves [first, last) into
00402   //  [mid, mid + (last - first)).
00403   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
00404        typename _Allocator>
00405     inline _ForwardIterator
00406     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
00407                   const _Tp& __x, _InputIterator __first,
00408                   _InputIterator __last, _Allocator& __alloc)
00409     {
00410       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
00411       __try
00412     {
00413       return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
00414     }
00415       __catch(...)
00416     {
00417       std::_Destroy(__result, __mid, __alloc);
00418       __throw_exception_again;
00419     }
00420     }
00421 
00422   // __uninitialized_move_fill
00423   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
00424   //  fills [first2 + (last1 - first1), last2) with x.
00425   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
00426        typename _Allocator>
00427     inline void
00428     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
00429                   _ForwardIterator __first2,
00430                   _ForwardIterator __last2, const _Tp& __x,
00431                   _Allocator& __alloc)
00432     {
00433       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
00434                                 __first2,
00435                                 __alloc);
00436       __try
00437     {
00438       std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
00439     }
00440       __catch(...)
00441     {
00442       std::_Destroy(__first2, __mid2, __alloc);
00443       __throw_exception_again;
00444     }
00445     }
00446 
00447 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00448   // Extensions: __uninitialized_default, __uninitialized_default_n,
00449   // __uninitialized_default_a, __uninitialized_default_n_a.
00450 
00451   template<bool _TrivialValueType>
00452     struct __uninitialized_default_1
00453     {
00454       template<typename _ForwardIterator>
00455         static void
00456         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
00457         {
00458       _ForwardIterator __cur = __first;
00459       __try
00460         {
00461           for (; __cur != __last; ++__cur)
00462         std::_Construct(std::__addressof(*__cur));
00463         }
00464       __catch(...)
00465         {
00466           std::_Destroy(__first, __cur);
00467           __throw_exception_again;
00468         }
00469     }
00470     };
00471 
00472   template<>
00473     struct __uninitialized_default_1<true>
00474     {
00475       template<typename _ForwardIterator>
00476         static void
00477         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
00478         {
00479       typedef typename iterator_traits<_ForwardIterator>::value_type
00480         _ValueType;
00481 
00482       std::fill(__first, __last, _ValueType());
00483     }
00484     };
00485 
00486   template<bool _TrivialValueType>
00487     struct __uninitialized_default_n_1
00488     {
00489       template<typename _ForwardIterator, typename _Size>
00490         static void
00491         __uninit_default_n(_ForwardIterator __first, _Size __n)
00492         {
00493       _ForwardIterator __cur = __first;
00494       __try
00495         {
00496           for (; __n > 0; --__n, ++__cur)
00497         std::_Construct(std::__addressof(*__cur));
00498         }
00499       __catch(...)
00500         {
00501           std::_Destroy(__first, __cur);
00502           __throw_exception_again;
00503         }
00504     }
00505     };
00506 
00507   template<>
00508     struct __uninitialized_default_n_1<true>
00509     {
00510       template<typename _ForwardIterator, typename _Size>
00511         static void
00512         __uninit_default_n(_ForwardIterator __first, _Size __n)
00513         {
00514       typedef typename iterator_traits<_ForwardIterator>::value_type
00515         _ValueType;
00516 
00517       std::fill_n(__first, __n, _ValueType());
00518     }
00519     };
00520 
00521   // __uninitialized_default
00522   // Fills [first, last) with std::distance(first, last) default
00523   // constructed value_types(s).
00524   template<typename _ForwardIterator>
00525     inline void
00526     __uninitialized_default(_ForwardIterator __first,
00527                 _ForwardIterator __last)
00528     {
00529       typedef typename iterator_traits<_ForwardIterator>::value_type
00530     _ValueType;
00531 
00532       std::__uninitialized_default_1<__is_trivial(_ValueType)>::
00533     __uninit_default(__first, __last);
00534     }
00535 
00536   // __uninitialized_default_n
00537   // Fills [first, first + n) with n default constructed value_type(s).
00538   template<typename _ForwardIterator, typename _Size>
00539     inline void
00540     __uninitialized_default_n(_ForwardIterator __first, _Size __n)
00541     {
00542       typedef typename iterator_traits<_ForwardIterator>::value_type
00543     _ValueType;
00544 
00545       std::__uninitialized_default_n_1<__is_trivial(_ValueType)>::
00546     __uninit_default_n(__first, __n);
00547     }
00548 
00549 
00550   // __uninitialized_default_a
00551   // Fills [first, last) with std::distance(first, last) default
00552   // constructed value_types(s), constructed with the allocator alloc.
00553   template<typename _ForwardIterator, typename _Allocator>
00554     void
00555     __uninitialized_default_a(_ForwardIterator __first,
00556                   _ForwardIterator __last,
00557                   _Allocator& __alloc)
00558     {
00559       _ForwardIterator __cur = __first;
00560       __try
00561     {
00562       typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00563       for (; __cur != __last; ++__cur)
00564         __traits::construct(__alloc, std::__addressof(*__cur));
00565     }
00566       __catch(...)
00567     {
00568       std::_Destroy(__first, __cur, __alloc);
00569       __throw_exception_again;
00570     }
00571     }
00572 
00573   template<typename _ForwardIterator, typename _Tp>
00574     inline void
00575     __uninitialized_default_a(_ForwardIterator __first,
00576                   _ForwardIterator __last,
00577                   allocator<_Tp>&)
00578     { std::__uninitialized_default(__first, __last); }
00579 
00580 
00581   // __uninitialized_default_n_a
00582   // Fills [first, first + n) with n default constructed value_types(s),
00583   // constructed with the allocator alloc.
00584   template<typename _ForwardIterator, typename _Size, typename _Allocator>
00585     void
00586     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
00587                 _Allocator& __alloc)
00588     {
00589       _ForwardIterator __cur = __first;
00590       __try
00591     {
00592       typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00593       for (; __n > 0; --__n, ++__cur)
00594         __traits::construct(__alloc, std::__addressof(*__cur));
00595     }
00596       __catch(...)
00597     {
00598       std::_Destroy(__first, __cur, __alloc);
00599       __throw_exception_again;
00600     }
00601     }
00602 
00603   template<typename _ForwardIterator, typename _Size, typename _Tp>
00604     inline void
00605     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
00606                 allocator<_Tp>&)
00607     { std::__uninitialized_default_n(__first, __n); }
00608 
00609 
00610   template<typename _InputIterator, typename _Size,
00611        typename _ForwardIterator>
00612     _ForwardIterator
00613     __uninitialized_copy_n(_InputIterator __first, _Size __n,
00614                _ForwardIterator __result, input_iterator_tag)
00615     {
00616       _ForwardIterator __cur = __result;
00617       __try
00618     {
00619       for (; __n > 0; --__n, ++__first, ++__cur)
00620         std::_Construct(std::__addressof(*__cur), *__first);
00621       return __cur;
00622     }
00623       __catch(...)
00624     {
00625       std::_Destroy(__result, __cur);
00626       __throw_exception_again;
00627     }
00628     }
00629 
00630   template<typename _RandomAccessIterator, typename _Size,
00631        typename _ForwardIterator>
00632     inline _ForwardIterator
00633     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
00634                _ForwardIterator __result,
00635                random_access_iterator_tag)
00636     { return std::uninitialized_copy(__first, __first + __n, __result); }
00637 
00638   /**
00639    *  @brief Copies the range [first,first+n) into result.
00640    *  @param  __first  An input iterator.
00641    *  @param  __n      The number of elements to copy.
00642    *  @param  __result An output iterator.
00643    *  @return  __result + __n
00644    *
00645    *  Like copy_n(), but does not require an initialized output range.
00646   */
00647   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
00648     inline _ForwardIterator
00649     uninitialized_copy_n(_InputIterator __first, _Size __n,
00650              _ForwardIterator __result)
00651     { return std::__uninitialized_copy_n(__first, __n, __result,
00652                      std::__iterator_category(__first)); }
00653 #endif
00654 
00655 _GLIBCXX_END_NAMESPACE_VERSION
00656 } // namespace
00657 
00658 #endif /* _STL_UNINITIALIZED_H */