stl_uninitialized.h

Go to the documentation of this file.
00001 // Raw memory manipulators -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 /*
00027  *
00028  * Copyright (c) 1994
00029  * Hewlett-Packard Company
00030  *
00031  * Permission to use, copy, modify, distribute and sell this software
00032  * and its documentation for any purpose is hereby granted without fee,
00033  * provided that the above copyright notice appear in all copies and
00034  * that both that copyright notice and this permission notice appear
00035  * in supporting documentation.  Hewlett-Packard Company makes no
00036  * representations about the suitability of this software for any
00037  * purpose.  It is provided "as is" without express or implied warranty.
00038  *
00039  *
00040  * Copyright (c) 1996,1997
00041  * Silicon Graphics Computer Systems, Inc.
00042  *
00043  * Permission to use, copy, modify, distribute and sell this software
00044  * and its documentation for any purpose is hereby granted without fee,
00045  * provided that the above copyright notice appear in all copies and
00046  * that both that copyright notice and this permission notice appear
00047  * in supporting documentation.  Silicon Graphics makes no
00048  * representations about the suitability of this software for any
00049  * purpose.  It is provided "as is" without express or implied warranty.
00050  */
00051 
00052 /** @file stl_uninitialized.h
00053  *  This is an internal header file, included by other library headers.
00054  *  You should not attempt to use it directly.
00055  */
00056 
00057 #ifndef _STL_UNINITIALIZED_H
00058 #define _STL_UNINITIALIZED_H 1
00059 
00060 _GLIBCXX_BEGIN_NAMESPACE(std)
00061 
00062   template<bool>
00063     struct __uninitialized_copy
00064     {
00065       template<typename _InputIterator, typename _ForwardIterator>
00066         static _ForwardIterator
00067         uninitialized_copy(_InputIterator __first, _InputIterator __last,
00068                _ForwardIterator __result)
00069         {
00070       _ForwardIterator __cur = __result;
00071       __try
00072         {
00073           for (; __first != __last; ++__first, ++__cur)
00074         std::_Construct(&*__cur, *__first);
00075           return __cur;
00076         }
00077       __catch(...)
00078         {
00079           std::_Destroy(__result, __cur);
00080           __throw_exception_again;
00081         }
00082     }
00083     };
00084 
00085   template<>
00086     struct __uninitialized_copy<true>
00087     {
00088       template<typename _InputIterator, typename _ForwardIterator>
00089         static _ForwardIterator
00090         uninitialized_copy(_InputIterator __first, _InputIterator __last,
00091                _ForwardIterator __result)
00092         { return std::copy(__first, __last, __result); }
00093     };
00094 
00095   /**
00096    *  @brief Copies the range [first,last) into result.
00097    *  @param  first  An input iterator.
00098    *  @param  last   An input iterator.
00099    *  @param  result An output iterator.
00100    *  @return   result + (first - last)
00101    *
00102    *  Like copy(), but does not require an initialized output range.
00103   */
00104   template<typename _InputIterator, typename _ForwardIterator>
00105     inline _ForwardIterator
00106     uninitialized_copy(_InputIterator __first, _InputIterator __last,
00107                _ForwardIterator __result)
00108     {
00109       typedef typename iterator_traits<_InputIterator>::value_type
00110     _ValueType1;
00111       typedef typename iterator_traits<_ForwardIterator>::value_type
00112     _ValueType2;
00113 
00114       return std::__uninitialized_copy<(__is_pod(_ValueType1)
00115                     && __is_pod(_ValueType2))>::
00116     uninitialized_copy(__first, __last, __result);
00117     }
00118 
00119 
00120   template<bool>
00121     struct __uninitialized_fill
00122     {
00123       template<typename _ForwardIterator, typename _Tp>
00124         static void
00125         uninitialized_fill(_ForwardIterator __first,
00126                _ForwardIterator __last, const _Tp& __x)
00127         {
00128       _ForwardIterator __cur = __first;
00129       __try
00130         {
00131           for (; __cur != __last; ++__cur)
00132         std::_Construct(&*__cur, __x);
00133         }
00134       __catch(...)
00135         {
00136           std::_Destroy(__first, __cur);
00137           __throw_exception_again;
00138         }
00139     }
00140     };
00141 
00142   template<>
00143     struct __uninitialized_fill<true>
00144     {
00145       template<typename _ForwardIterator, typename _Tp>
00146         static void
00147         uninitialized_fill(_ForwardIterator __first,
00148                _ForwardIterator __last, const _Tp& __x)
00149         { std::fill(__first, __last, __x); }
00150     };
00151 
00152   /**
00153    *  @brief Copies the value x into the range [first,last).
00154    *  @param  first  An input iterator.
00155    *  @param  last   An input iterator.
00156    *  @param  x      The source value.
00157    *  @return   Nothing.
00158    *
00159    *  Like fill(), but does not require an initialized output range.
00160   */
00161   template<typename _ForwardIterator, typename _Tp>
00162     inline void
00163     uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
00164                const _Tp& __x)
00165     {
00166       typedef typename iterator_traits<_ForwardIterator>::value_type
00167     _ValueType;
00168 
00169       std::__uninitialized_fill<__is_pod(_ValueType)>::
00170 	uninitialized_fill(__first, __last, __x);
00171     }
00172 
00173 
00174   template<bool>
00175     struct __uninitialized_fill_n
00176     {
00177       template<typename _ForwardIterator, typename _Size, typename _Tp>
00178         static void
00179         uninitialized_fill_n(_ForwardIterator __first, _Size __n,
00180                  const _Tp& __x)
00181         {
00182       _ForwardIterator __cur = __first;
00183       __try
00184         {
00185           for (; __n > 0; --__n, ++__cur)
00186         std::_Construct(&*__cur, __x);
00187         }
00188       __catch(...)
00189         {
00190           std::_Destroy(__first, __cur);
00191           __throw_exception_again;
00192         }
00193     }
00194     };
00195 
00196   template<>
00197     struct __uninitialized_fill_n<true>
00198     {
00199       template<typename _ForwardIterator, typename _Size, typename _Tp>
00200         static void
00201         uninitialized_fill_n(_ForwardIterator __first, _Size __n,
00202                  const _Tp& __x)
00203         { std::fill_n(__first, __n, __x); }
00204     };
00205 
00206   /**
00207    *  @brief Copies the value x into the range [first,first+n).
00208    *  @param  first  An input iterator.
00209    *  @param  n      The number of copies to make.
00210    *  @param  x      The source value.
00211    *  @return   Nothing.
00212    *
00213    *  Like fill_n(), but does not require an initialized output range.
00214   */
00215   template<typename _ForwardIterator, typename _Size, typename _Tp>
00216     inline void
00217     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
00218     {
00219       typedef typename iterator_traits<_ForwardIterator>::value_type
00220     _ValueType;
00221 
00222       std::__uninitialized_fill_n<__is_pod(_ValueType)>::
00223 	uninitialized_fill_n(__first, __n, __x);
00224     }
00225 
00226   // Extensions: versions of uninitialized_copy, uninitialized_fill,
00227   //  and uninitialized_fill_n that take an allocator parameter.
00228   //  We dispatch back to the standard versions when we're given the
00229   //  default allocator.  For nondefault allocators we do not use 
00230   //  any of the POD optimizations.
00231 
00232   template<typename _InputIterator, typename _ForwardIterator,
00233        typename _Allocator>
00234     _ForwardIterator
00235     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
00236                _ForwardIterator __result, _Allocator& __alloc)
00237     {
00238       _ForwardIterator __cur = __result;
00239       __try
00240     {
00241       for (; __first != __last; ++__first, ++__cur)
00242         __alloc.construct(&*__cur, *__first);
00243       return __cur;
00244     }
00245       __catch(...)
00246     {
00247       std::_Destroy(__result, __cur, __alloc);
00248       __throw_exception_again;
00249     }
00250     }
00251 
00252   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
00253     inline _ForwardIterator
00254     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
00255                _ForwardIterator __result, allocator<_Tp>&)
00256     { return std::uninitialized_copy(__first, __last, __result); }
00257 
00258   template<typename _InputIterator, typename _ForwardIterator,
00259        typename _Allocator>
00260     inline _ForwardIterator
00261     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
00262                _ForwardIterator __result, _Allocator& __alloc)
00263     {
00264       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
00265                      _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
00266                      __result, __alloc);
00267     }
00268 
00269   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
00270     void
00271     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
00272                const _Tp& __x, _Allocator& __alloc)
00273     {
00274       _ForwardIterator __cur = __first;
00275       __try
00276     {
00277       for (; __cur != __last; ++__cur)
00278         __alloc.construct(&*__cur, __x);
00279     }
00280       __catch(...)
00281     {
00282       std::_Destroy(__first, __cur, __alloc);
00283       __throw_exception_again;
00284     }
00285     }
00286 
00287   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
00288     inline void
00289     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
00290                const _Tp& __x, allocator<_Tp2>&)
00291     { std::uninitialized_fill(__first, __last, __x); }
00292 
00293   template<typename _ForwardIterator, typename _Size, typename _Tp,
00294        typename _Allocator>
00295     void
00296     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
00297                  const _Tp& __x, _Allocator& __alloc)
00298     {
00299       _ForwardIterator __cur = __first;
00300       __try
00301     {
00302       for (; __n > 0; --__n, ++__cur)
00303         __alloc.construct(&*__cur, __x);
00304     }
00305       __catch(...)
00306     {
00307       std::_Destroy(__first, __cur, __alloc);
00308       __throw_exception_again;
00309     }
00310     }
00311 
00312   template<typename _ForwardIterator, typename _Size, typename _Tp,
00313        typename _Tp2>
00314     inline void
00315     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
00316                  const _Tp& __x, allocator<_Tp2>&)
00317     { std::uninitialized_fill_n(__first, __n, __x); }
00318 
00319 
00320   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
00321   // __uninitialized_fill_move, __uninitialized_move_fill.
00322   // All of these algorithms take a user-supplied allocator, which is used
00323   // for construction and destruction.
00324 
00325   // __uninitialized_copy_move
00326   // Copies [first1, last1) into [result, result + (last1 - first1)), and
00327   //  move [first2, last2) into
00328   //  [result, result + (last1 - first1) + (last2 - first2)).
00329   template<typename _InputIterator1, typename _InputIterator2,
00330        typename _ForwardIterator, typename _Allocator>
00331     inline _ForwardIterator
00332     __uninitialized_copy_move(_InputIterator1 __first1,
00333                   _InputIterator1 __last1,
00334                   _InputIterator2 __first2,
00335                   _InputIterator2 __last2,
00336                   _ForwardIterator __result,
00337                   _Allocator& __alloc)
00338     {
00339       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
00340                                __result,
00341                                __alloc);
00342       __try
00343     {
00344       return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
00345     }
00346       __catch(...)
00347     {
00348       std::_Destroy(__result, __mid, __alloc);
00349       __throw_exception_again;
00350     }
00351     }
00352 
00353   // __uninitialized_move_copy
00354   // Moves [first1, last1) into [result, result + (last1 - first1)), and
00355   //  copies [first2, last2) into
00356   //  [result, result + (last1 - first1) + (last2 - first2)).
00357   template<typename _InputIterator1, typename _InputIterator2,
00358        typename _ForwardIterator, typename _Allocator>
00359     inline _ForwardIterator
00360     __uninitialized_move_copy(_InputIterator1 __first1,
00361                   _InputIterator1 __last1,
00362                   _InputIterator2 __first2,
00363                   _InputIterator2 __last2,
00364                   _ForwardIterator __result,
00365                   _Allocator& __alloc)
00366     {
00367       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
00368                                __result,
00369                                __alloc);
00370       __try
00371     {
00372       return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
00373     }
00374       __catch(...)
00375     {
00376       std::_Destroy(__result, __mid, __alloc);
00377       __throw_exception_again;
00378     }
00379     }
00380   
00381   // __uninitialized_fill_move
00382   // Fills [result, mid) with x, and moves [first, last) into
00383   //  [mid, mid + (last - first)).
00384   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
00385        typename _Allocator>
00386     inline _ForwardIterator
00387     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
00388                   const _Tp& __x, _InputIterator __first,
00389                   _InputIterator __last, _Allocator& __alloc)
00390     {
00391       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
00392       __try
00393     {
00394       return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
00395     }
00396       __catch(...)
00397     {
00398       std::_Destroy(__result, __mid, __alloc);
00399       __throw_exception_again;
00400     }
00401     }
00402 
00403   // __uninitialized_move_fill
00404   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
00405   //  fills [first2 + (last1 - first1), last2) with x.
00406   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
00407        typename _Allocator>
00408     inline void
00409     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
00410                   _ForwardIterator __first2,
00411                   _ForwardIterator __last2, const _Tp& __x,
00412                   _Allocator& __alloc)
00413     {
00414       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
00415                                 __first2,
00416                                 __alloc);
00417       __try
00418     {
00419       std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
00420     }
00421       __catch(...)
00422     {
00423       std::_Destroy(__first2, __mid2, __alloc);
00424       __throw_exception_again;
00425     }
00426     }
00427 
00428 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00429   template<typename _InputIterator, typename _Size,
00430        typename _ForwardIterator>
00431     _ForwardIterator
00432     __uninitialized_copy_n(_InputIterator __first, _Size __n,
00433                _ForwardIterator __result, input_iterator_tag)
00434     {
00435       _ForwardIterator __cur = __result;
00436       __try
00437     {
00438       for (; __n > 0; --__n, ++__first, ++__cur)
00439         ::new(static_cast<void*>(&*__cur)) typename
00440         iterator_traits<_ForwardIterator>::value_type(*__first);
00441       return __cur;
00442     }
00443       __catch(...)
00444     {
00445       std::_Destroy(__result, __cur);
00446       __throw_exception_again;
00447     }
00448     }
00449 
00450   template<typename _RandomAccessIterator, typename _Size,
00451        typename _ForwardIterator>
00452     inline _ForwardIterator
00453     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
00454                _ForwardIterator __result,
00455                random_access_iterator_tag)
00456     { return std::uninitialized_copy(__first, __first + __n, __result); }
00457 
00458   /**
00459    *  @brief Copies the range [first,first+n) into result.
00460    *  @param  first  An input iterator.
00461    *  @param  n      The number of elements to copy.
00462    *  @param  result An output iterator.
00463    *  @return  result + n
00464    *
00465    *  Like copy_n(), but does not require an initialized output range.
00466   */
00467   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
00468     inline _ForwardIterator
00469     uninitialized_copy_n(_InputIterator __first, _Size __n,
00470              _ForwardIterator __result)
00471     { return std::__uninitialized_copy_n(__first, __n, __result,
00472                      std::__iterator_category(__first)); }
00473 #endif
00474 
00475 _GLIBCXX_END_NAMESPACE
00476 
00477 #endif /* _STL_UNINITIALIZED_H */

Generated on 19 Jun 2018 for libstdc++ by  doxygen 1.6.1