libstdc++
stl_uninitialized.h
Go to the documentation of this file.
00001 // Raw memory manipulators -*- C++ -*-
00002 
00003 // Copyright (C) 2001-2013 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /*
00026  *
00027  * Copyright (c) 1994
00028  * Hewlett-Packard Company
00029  *
00030  * Permission to use, copy, modify, distribute and sell this software
00031  * and its documentation for any purpose is hereby granted without fee,
00032  * provided that the above copyright notice appear in all copies and
00033  * that both that copyright notice and this permission notice appear
00034  * in supporting documentation.  Hewlett-Packard Company makes no
00035  * representations about the suitability of this software for any
00036  * purpose.  It is provided "as is" without express or implied warranty.
00037  *
00038  *
00039  * Copyright (c) 1996,1997
00040  * Silicon Graphics Computer Systems, Inc.
00041  *
00042  * Permission to use, copy, modify, distribute and sell this software
00043  * and its documentation for any purpose is hereby granted without fee,
00044  * provided that the above copyright notice appear in all copies and
00045  * that both that copyright notice and this permission notice appear
00046  * in supporting documentation.  Silicon Graphics makes no
00047  * representations about the suitability of this software for any
00048  * purpose.  It is provided "as is" without express or implied warranty.
00049  */
00050 
00051 /** @file bits/stl_uninitialized.h
00052  *  This is an internal header file, included by other library headers.
00053  *  Do not attempt to use it directly. @headername{memory}
00054  */
00055 
00056 #ifndef _STL_UNINITIALIZED_H
00057 #define _STL_UNINITIALIZED_H 1
00058 
00059 namespace std _GLIBCXX_VISIBILITY(default)
00060 {
00061 _GLIBCXX_BEGIN_NAMESPACE_VERSION
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       typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00243       for (; __first != __last; ++__first, ++__cur)
00244         __traits::construct(__alloc, std::__addressof(*__cur), *__first);
00245       return __cur;
00246     }
00247       __catch(...)
00248     {
00249       std::_Destroy(__result, __cur, __alloc);
00250       __throw_exception_again;
00251     }
00252     }
00253 
00254   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
00255     inline _ForwardIterator
00256     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
00257                _ForwardIterator __result, allocator<_Tp>&)
00258     { return std::uninitialized_copy(__first, __last, __result); }
00259 
00260   template<typename _InputIterator, typename _ForwardIterator,
00261        typename _Allocator>
00262     inline _ForwardIterator
00263     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
00264                _ForwardIterator __result, _Allocator& __alloc)
00265     {
00266       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
00267                      _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
00268                      __result, __alloc);
00269     }
00270 
00271   template<typename _InputIterator, typename _ForwardIterator,
00272        typename _Allocator>
00273     inline _ForwardIterator
00274     __uninitialized_move_if_noexcept_a(_InputIterator __first,
00275                        _InputIterator __last,
00276                        _ForwardIterator __result,
00277                        _Allocator& __alloc)
00278     {
00279       return std::__uninitialized_copy_a
00280     (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
00281      _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
00282     }
00283 
00284   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
00285     void
00286     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
00287                const _Tp& __x, _Allocator& __alloc)
00288     {
00289       _ForwardIterator __cur = __first;
00290       __try
00291     {
00292       typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00293       for (; __cur != __last; ++__cur)
00294         __traits::construct(__alloc, std::__addressof(*__cur), __x);
00295     }
00296       __catch(...)
00297     {
00298       std::_Destroy(__first, __cur, __alloc);
00299       __throw_exception_again;
00300     }
00301     }
00302 
00303   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
00304     inline void
00305     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
00306                const _Tp& __x, allocator<_Tp2>&)
00307     { std::uninitialized_fill(__first, __last, __x); }
00308 
00309   template<typename _ForwardIterator, typename _Size, typename _Tp,
00310        typename _Allocator>
00311     void
00312     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
00313                  const _Tp& __x, _Allocator& __alloc)
00314     {
00315       _ForwardIterator __cur = __first;
00316       __try
00317     {
00318       typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00319       for (; __n > 0; --__n, ++__cur)
00320         __traits::construct(__alloc, std::__addressof(*__cur), __x);
00321     }
00322       __catch(...)
00323     {
00324       std::_Destroy(__first, __cur, __alloc);
00325       __throw_exception_again;
00326     }
00327     }
00328 
00329   template<typename _ForwardIterator, typename _Size, typename _Tp,
00330        typename _Tp2>
00331     inline void
00332     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
00333                  const _Tp& __x, allocator<_Tp2>&)
00334     { std::uninitialized_fill_n(__first, __n, __x); }
00335 
00336 
00337   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
00338   // __uninitialized_fill_move, __uninitialized_move_fill.
00339   // All of these algorithms take a user-supplied allocator, which is used
00340   // for construction and destruction.
00341 
00342   // __uninitialized_copy_move
00343   // Copies [first1, last1) into [result, result + (last1 - first1)), and
00344   //  move [first2, last2) into
00345   //  [result, result + (last1 - first1) + (last2 - first2)).
00346   template<typename _InputIterator1, typename _InputIterator2,
00347        typename _ForwardIterator, typename _Allocator>
00348     inline _ForwardIterator
00349     __uninitialized_copy_move(_InputIterator1 __first1,
00350                   _InputIterator1 __last1,
00351                   _InputIterator2 __first2,
00352                   _InputIterator2 __last2,
00353                   _ForwardIterator __result,
00354                   _Allocator& __alloc)
00355     {
00356       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
00357                                __result,
00358                                __alloc);
00359       __try
00360     {
00361       return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
00362     }
00363       __catch(...)
00364     {
00365       std::_Destroy(__result, __mid, __alloc);
00366       __throw_exception_again;
00367     }
00368     }
00369 
00370   // __uninitialized_move_copy
00371   // Moves [first1, last1) into [result, result + (last1 - first1)), and
00372   //  copies [first2, last2) into
00373   //  [result, result + (last1 - first1) + (last2 - first2)).
00374   template<typename _InputIterator1, typename _InputIterator2,
00375        typename _ForwardIterator, typename _Allocator>
00376     inline _ForwardIterator
00377     __uninitialized_move_copy(_InputIterator1 __first1,
00378                   _InputIterator1 __last1,
00379                   _InputIterator2 __first2,
00380                   _InputIterator2 __last2,
00381                   _ForwardIterator __result,
00382                   _Allocator& __alloc)
00383     {
00384       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
00385                                __result,
00386                                __alloc);
00387       __try
00388     {
00389       return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
00390     }
00391       __catch(...)
00392     {
00393       std::_Destroy(__result, __mid, __alloc);
00394       __throw_exception_again;
00395     }
00396     }
00397   
00398   // __uninitialized_fill_move
00399   // Fills [result, mid) with x, and moves [first, last) into
00400   //  [mid, mid + (last - first)).
00401   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
00402        typename _Allocator>
00403     inline _ForwardIterator
00404     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
00405                   const _Tp& __x, _InputIterator __first,
00406                   _InputIterator __last, _Allocator& __alloc)
00407     {
00408       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
00409       __try
00410     {
00411       return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
00412     }
00413       __catch(...)
00414     {
00415       std::_Destroy(__result, __mid, __alloc);
00416       __throw_exception_again;
00417     }
00418     }
00419 
00420   // __uninitialized_move_fill
00421   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
00422   //  fills [first2 + (last1 - first1), last2) with x.
00423   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
00424        typename _Allocator>
00425     inline void
00426     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
00427                   _ForwardIterator __first2,
00428                   _ForwardIterator __last2, const _Tp& __x,
00429                   _Allocator& __alloc)
00430     {
00431       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
00432                                 __first2,
00433                                 __alloc);
00434       __try
00435     {
00436       std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
00437     }
00438       __catch(...)
00439     {
00440       std::_Destroy(__first2, __mid2, __alloc);
00441       __throw_exception_again;
00442     }
00443     }
00444 
00445 #if __cplusplus >= 201103L
00446   // Extensions: __uninitialized_default, __uninitialized_default_n,
00447   // __uninitialized_default_a, __uninitialized_default_n_a.
00448 
00449   template<bool _TrivialValueType>
00450     struct __uninitialized_default_1
00451     {
00452       template<typename _ForwardIterator>
00453         static void
00454         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
00455         {
00456       _ForwardIterator __cur = __first;
00457       __try
00458         {
00459           for (; __cur != __last; ++__cur)
00460         std::_Construct(std::__addressof(*__cur));
00461         }
00462       __catch(...)
00463         {
00464           std::_Destroy(__first, __cur);
00465           __throw_exception_again;
00466         }
00467     }
00468     };
00469 
00470   template<>
00471     struct __uninitialized_default_1<true>
00472     {
00473       template<typename _ForwardIterator>
00474         static void
00475         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
00476         {
00477       typedef typename iterator_traits<_ForwardIterator>::value_type
00478         _ValueType;
00479 
00480       std::fill(__first, __last, _ValueType());
00481     }
00482     };
00483 
00484   template<bool _TrivialValueType>
00485     struct __uninitialized_default_n_1
00486     {
00487       template<typename _ForwardIterator, typename _Size>
00488         static void
00489         __uninit_default_n(_ForwardIterator __first, _Size __n)
00490         {
00491       _ForwardIterator __cur = __first;
00492       __try
00493         {
00494           for (; __n > 0; --__n, ++__cur)
00495         std::_Construct(std::__addressof(*__cur));
00496         }
00497       __catch(...)
00498         {
00499           std::_Destroy(__first, __cur);
00500           __throw_exception_again;
00501         }
00502     }
00503     };
00504 
00505   template<>
00506     struct __uninitialized_default_n_1<true>
00507     {
00508       template<typename _ForwardIterator, typename _Size>
00509         static void
00510         __uninit_default_n(_ForwardIterator __first, _Size __n)
00511         {
00512       typedef typename iterator_traits<_ForwardIterator>::value_type
00513         _ValueType;
00514 
00515       std::fill_n(__first, __n, _ValueType());
00516     }
00517     };
00518 
00519   // __uninitialized_default
00520   // Fills [first, last) with std::distance(first, last) default
00521   // constructed value_types(s).
00522   template<typename _ForwardIterator>
00523     inline void
00524     __uninitialized_default(_ForwardIterator __first,
00525                 _ForwardIterator __last)
00526     {
00527       typedef typename iterator_traits<_ForwardIterator>::value_type
00528     _ValueType;
00529 
00530       std::__uninitialized_default_1<__is_trivial(_ValueType)>::
00531     __uninit_default(__first, __last);
00532     }
00533 
00534   // __uninitialized_default_n
00535   // Fills [first, first + n) with n default constructed value_type(s).
00536   template<typename _ForwardIterator, typename _Size>
00537     inline void
00538     __uninitialized_default_n(_ForwardIterator __first, _Size __n)
00539     {
00540       typedef typename iterator_traits<_ForwardIterator>::value_type
00541     _ValueType;
00542 
00543       std::__uninitialized_default_n_1<__is_trivial(_ValueType)>::
00544     __uninit_default_n(__first, __n);
00545     }
00546 
00547 
00548   // __uninitialized_default_a
00549   // Fills [first, last) with std::distance(first, last) default
00550   // constructed value_types(s), constructed with the allocator alloc.
00551   template<typename _ForwardIterator, typename _Allocator>
00552     void
00553     __uninitialized_default_a(_ForwardIterator __first,
00554                   _ForwardIterator __last,
00555                   _Allocator& __alloc)
00556     {
00557       _ForwardIterator __cur = __first;
00558       __try
00559     {
00560       typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00561       for (; __cur != __last; ++__cur)
00562         __traits::construct(__alloc, std::__addressof(*__cur));
00563     }
00564       __catch(...)
00565     {
00566       std::_Destroy(__first, __cur, __alloc);
00567       __throw_exception_again;
00568     }
00569     }
00570 
00571   template<typename _ForwardIterator, typename _Tp>
00572     inline void
00573     __uninitialized_default_a(_ForwardIterator __first,
00574                   _ForwardIterator __last,
00575                   allocator<_Tp>&)
00576     { std::__uninitialized_default(__first, __last); }
00577 
00578 
00579   // __uninitialized_default_n_a
00580   // Fills [first, first + n) with n default constructed value_types(s),
00581   // constructed with the allocator alloc.
00582   template<typename _ForwardIterator, typename _Size, typename _Allocator>
00583     void
00584     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
00585                 _Allocator& __alloc)
00586     {
00587       _ForwardIterator __cur = __first;
00588       __try
00589     {
00590       typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
00591       for (; __n > 0; --__n, ++__cur)
00592         __traits::construct(__alloc, std::__addressof(*__cur));
00593     }
00594       __catch(...)
00595     {
00596       std::_Destroy(__first, __cur, __alloc);
00597       __throw_exception_again;
00598     }
00599     }
00600 
00601   template<typename _ForwardIterator, typename _Size, typename _Tp>
00602     inline void
00603     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
00604                 allocator<_Tp>&)
00605     { std::__uninitialized_default_n(__first, __n); }
00606 
00607 
00608   template<typename _InputIterator, typename _Size,
00609        typename _ForwardIterator>
00610     _ForwardIterator
00611     __uninitialized_copy_n(_InputIterator __first, _Size __n,
00612                _ForwardIterator __result, input_iterator_tag)
00613     {
00614       _ForwardIterator __cur = __result;
00615       __try
00616     {
00617       for (; __n > 0; --__n, ++__first, ++__cur)
00618         std::_Construct(std::__addressof(*__cur), *__first);
00619       return __cur;
00620     }
00621       __catch(...)
00622     {
00623       std::_Destroy(__result, __cur);
00624       __throw_exception_again;
00625     }
00626     }
00627 
00628   template<typename _RandomAccessIterator, typename _Size,
00629        typename _ForwardIterator>
00630     inline _ForwardIterator
00631     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
00632                _ForwardIterator __result,
00633                random_access_iterator_tag)
00634     { return std::uninitialized_copy(__first, __first + __n, __result); }
00635 
00636   /**
00637    *  @brief Copies the range [first,first+n) into result.
00638    *  @param  __first  An input iterator.
00639    *  @param  __n      The number of elements to copy.
00640    *  @param  __result An output iterator.
00641    *  @return  __result + __n
00642    *
00643    *  Like copy_n(), but does not require an initialized output range.
00644   */
00645   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
00646     inline _ForwardIterator
00647     uninitialized_copy_n(_InputIterator __first, _Size __n,
00648              _ForwardIterator __result)
00649     { return std::__uninitialized_copy_n(__first, __n, __result,
00650                      std::__iterator_category(__first)); }
00651 #endif
00652 
00653 _GLIBCXX_END_NAMESPACE_VERSION
00654 } // namespace
00655 
00656 #endif /* _STL_UNINITIALIZED_H */