xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/stl_uninitialized.h (revision 23f5f46327e37e7811da3520f4bb933f9489322f)
11debfc3dSmrg // Raw memory manipulators -*- C++ -*-
21debfc3dSmrg 
38feb0f0bSmrg // Copyright (C) 2001-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg 
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg 
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg 
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg 
251debfc3dSmrg /*
261debfc3dSmrg  *
271debfc3dSmrg  * Copyright (c) 1994
281debfc3dSmrg  * Hewlett-Packard Company
291debfc3dSmrg  *
301debfc3dSmrg  * Permission to use, copy, modify, distribute and sell this software
311debfc3dSmrg  * and its documentation for any purpose is hereby granted without fee,
321debfc3dSmrg  * provided that the above copyright notice appear in all copies and
331debfc3dSmrg  * that both that copyright notice and this permission notice appear
341debfc3dSmrg  * in supporting documentation.  Hewlett-Packard Company makes no
351debfc3dSmrg  * representations about the suitability of this software for any
361debfc3dSmrg  * purpose.  It is provided "as is" without express or implied warranty.
371debfc3dSmrg  *
381debfc3dSmrg  *
391debfc3dSmrg  * Copyright (c) 1996,1997
401debfc3dSmrg  * Silicon Graphics Computer Systems, Inc.
411debfc3dSmrg  *
421debfc3dSmrg  * Permission to use, copy, modify, distribute and sell this software
431debfc3dSmrg  * and its documentation for any purpose is hereby granted without fee,
441debfc3dSmrg  * provided that the above copyright notice appear in all copies and
451debfc3dSmrg  * that both that copyright notice and this permission notice appear
461debfc3dSmrg  * in supporting documentation.  Silicon Graphics makes no
471debfc3dSmrg  * representations about the suitability of this software for any
481debfc3dSmrg  * purpose.  It is provided "as is" without express or implied warranty.
491debfc3dSmrg  */
501debfc3dSmrg 
511debfc3dSmrg /** @file bits/stl_uninitialized.h
521debfc3dSmrg  *  This is an internal header file, included by other library headers.
531debfc3dSmrg  *  Do not attempt to use it directly. @headername{memory}
541debfc3dSmrg  */
551debfc3dSmrg 
561debfc3dSmrg #ifndef _STL_UNINITIALIZED_H
571debfc3dSmrg #define _STL_UNINITIALIZED_H 1
581debfc3dSmrg 
591debfc3dSmrg #if __cplusplus > 201402L
608feb0f0bSmrg #include <bits/stl_pair.h>
611debfc3dSmrg #endif
621debfc3dSmrg 
631debfc3dSmrg #if __cplusplus >= 201103L
641debfc3dSmrg #include <type_traits>
651debfc3dSmrg #endif
661debfc3dSmrg 
678feb0f0bSmrg #include <ext/alloc_traits.h>
688feb0f0bSmrg 
_GLIBCXX_VISIBILITY(default)691debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
701debfc3dSmrg {
711debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
721debfc3dSmrg 
738feb0f0bSmrg   /** @addtogroup memory
748feb0f0bSmrg    *  @{
758feb0f0bSmrg    */
768feb0f0bSmrg 
778feb0f0bSmrg   /// @cond undocumented
788feb0f0bSmrg 
791debfc3dSmrg   template<bool _TrivialValueTypes>
801debfc3dSmrg     struct __uninitialized_copy
811debfc3dSmrg     {
821debfc3dSmrg       template<typename _InputIterator, typename _ForwardIterator>
831debfc3dSmrg         static _ForwardIterator
841debfc3dSmrg         __uninit_copy(_InputIterator __first, _InputIterator __last,
851debfc3dSmrg 		      _ForwardIterator __result)
861debfc3dSmrg         {
871debfc3dSmrg 	  _ForwardIterator __cur = __result;
881debfc3dSmrg 	  __try
891debfc3dSmrg 	    {
901debfc3dSmrg 	      for (; __first != __last; ++__first, (void)++__cur)
911debfc3dSmrg 		std::_Construct(std::__addressof(*__cur), *__first);
921debfc3dSmrg 	      return __cur;
931debfc3dSmrg 	    }
941debfc3dSmrg 	  __catch(...)
951debfc3dSmrg 	    {
961debfc3dSmrg 	      std::_Destroy(__result, __cur);
971debfc3dSmrg 	      __throw_exception_again;
981debfc3dSmrg 	    }
991debfc3dSmrg 	}
1001debfc3dSmrg     };
1011debfc3dSmrg 
1021debfc3dSmrg   template<>
1031debfc3dSmrg     struct __uninitialized_copy<true>
1041debfc3dSmrg     {
1051debfc3dSmrg       template<typename _InputIterator, typename _ForwardIterator>
1061debfc3dSmrg         static _ForwardIterator
1071debfc3dSmrg         __uninit_copy(_InputIterator __first, _InputIterator __last,
1081debfc3dSmrg 		      _ForwardIterator __result)
1091debfc3dSmrg         { return std::copy(__first, __last, __result); }
1101debfc3dSmrg     };
1111debfc3dSmrg 
1128feb0f0bSmrg   /// @endcond
1138feb0f0bSmrg 
1141debfc3dSmrg   /**
1151debfc3dSmrg    *  @brief Copies the range [first,last) into result.
1161debfc3dSmrg    *  @param  __first  An input iterator.
1171debfc3dSmrg    *  @param  __last   An input iterator.
1181debfc3dSmrg    *  @param  __result An output iterator.
1191debfc3dSmrg    *  @return   __result + (__first - __last)
1201debfc3dSmrg    *
1211debfc3dSmrg    *  Like copy(), but does not require an initialized output range.
1221debfc3dSmrg   */
1231debfc3dSmrg   template<typename _InputIterator, typename _ForwardIterator>
1241debfc3dSmrg     inline _ForwardIterator
1251debfc3dSmrg     uninitialized_copy(_InputIterator __first, _InputIterator __last,
1261debfc3dSmrg 		       _ForwardIterator __result)
1271debfc3dSmrg     {
1281debfc3dSmrg       typedef typename iterator_traits<_InputIterator>::value_type
1291debfc3dSmrg 	_ValueType1;
1301debfc3dSmrg       typedef typename iterator_traits<_ForwardIterator>::value_type
1311debfc3dSmrg 	_ValueType2;
1321debfc3dSmrg #if __cplusplus < 201103L
1331debfc3dSmrg       const bool __assignable = true;
1341debfc3dSmrg #else
135c0a68be4Smrg       // Trivial types can have deleted copy constructor, but the std::copy
136c0a68be4Smrg       // optimization that uses memmove would happily "copy" them anyway.
137c0a68be4Smrg       static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
138c0a68be4Smrg 	  "result type must be constructible from value type of input range");
139c0a68be4Smrg 
1401debfc3dSmrg       typedef typename iterator_traits<_InputIterator>::reference _RefType1;
1411debfc3dSmrg       typedef typename iterator_traits<_ForwardIterator>::reference _RefType2;
142c0a68be4Smrg       // Trivial types can have deleted assignment, so using std::copy
143c0a68be4Smrg       // would be ill-formed. Require assignability before using std::copy:
1441debfc3dSmrg       const bool __assignable = is_assignable<_RefType2, _RefType1>::value;
1451debfc3dSmrg #endif
1461debfc3dSmrg 
1471debfc3dSmrg       return std::__uninitialized_copy<__is_trivial(_ValueType1)
1481debfc3dSmrg 				       && __is_trivial(_ValueType2)
1491debfc3dSmrg 				       && __assignable>::
1501debfc3dSmrg 	__uninit_copy(__first, __last, __result);
1511debfc3dSmrg     }
1521debfc3dSmrg 
1538feb0f0bSmrg   /// @cond undocumented
1541debfc3dSmrg 
1551debfc3dSmrg   template<bool _TrivialValueType>
1561debfc3dSmrg     struct __uninitialized_fill
1571debfc3dSmrg     {
1581debfc3dSmrg       template<typename _ForwardIterator, typename _Tp>
1591debfc3dSmrg         static void
1601debfc3dSmrg         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
1611debfc3dSmrg 		      const _Tp& __x)
1621debfc3dSmrg         {
1631debfc3dSmrg 	  _ForwardIterator __cur = __first;
1641debfc3dSmrg 	  __try
1651debfc3dSmrg 	    {
1661debfc3dSmrg 	      for (; __cur != __last; ++__cur)
1671debfc3dSmrg 		std::_Construct(std::__addressof(*__cur), __x);
1681debfc3dSmrg 	    }
1691debfc3dSmrg 	  __catch(...)
1701debfc3dSmrg 	    {
1711debfc3dSmrg 	      std::_Destroy(__first, __cur);
1721debfc3dSmrg 	      __throw_exception_again;
1731debfc3dSmrg 	    }
1741debfc3dSmrg 	}
1751debfc3dSmrg     };
1761debfc3dSmrg 
1771debfc3dSmrg   template<>
1781debfc3dSmrg     struct __uninitialized_fill<true>
1791debfc3dSmrg     {
1801debfc3dSmrg       template<typename _ForwardIterator, typename _Tp>
1811debfc3dSmrg         static void
1821debfc3dSmrg         __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
1831debfc3dSmrg 		      const _Tp& __x)
1841debfc3dSmrg         { std::fill(__first, __last, __x); }
1851debfc3dSmrg     };
1861debfc3dSmrg 
1878feb0f0bSmrg   /// @endcond
1888feb0f0bSmrg 
1891debfc3dSmrg   /**
1901debfc3dSmrg    *  @brief Copies the value x into the range [first,last).
1911debfc3dSmrg    *  @param  __first  An input iterator.
1921debfc3dSmrg    *  @param  __last   An input iterator.
1931debfc3dSmrg    *  @param  __x      The source value.
1941debfc3dSmrg    *  @return   Nothing.
1951debfc3dSmrg    *
1961debfc3dSmrg    *  Like fill(), but does not require an initialized output range.
1971debfc3dSmrg   */
1981debfc3dSmrg   template<typename _ForwardIterator, typename _Tp>
1991debfc3dSmrg     inline void
2001debfc3dSmrg     uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
2011debfc3dSmrg 		       const _Tp& __x)
2021debfc3dSmrg     {
2031debfc3dSmrg       typedef typename iterator_traits<_ForwardIterator>::value_type
2041debfc3dSmrg 	_ValueType;
2051debfc3dSmrg #if __cplusplus < 201103L
2061debfc3dSmrg       const bool __assignable = true;
2071debfc3dSmrg #else
208c0a68be4Smrg       // Trivial types can have deleted copy constructor, but the std::fill
209c0a68be4Smrg       // optimization that uses memmove would happily "copy" them anyway.
210c0a68be4Smrg       static_assert(is_constructible<_ValueType, const _Tp&>::value,
211c0a68be4Smrg 	  "result type must be constructible from input type");
212c0a68be4Smrg 
213c0a68be4Smrg       // Trivial types can have deleted assignment, so using std::fill
214c0a68be4Smrg       // would be ill-formed. Require assignability before using std::fill:
2151debfc3dSmrg       const bool __assignable = is_copy_assignable<_ValueType>::value;
2161debfc3dSmrg #endif
2171debfc3dSmrg 
2181debfc3dSmrg       std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>::
2191debfc3dSmrg 	__uninit_fill(__first, __last, __x);
2201debfc3dSmrg     }
2211debfc3dSmrg 
2228feb0f0bSmrg   /// @cond undocumented
2231debfc3dSmrg 
2241debfc3dSmrg   template<bool _TrivialValueType>
2251debfc3dSmrg     struct __uninitialized_fill_n
2261debfc3dSmrg     {
2271debfc3dSmrg       template<typename _ForwardIterator, typename _Size, typename _Tp>
2281debfc3dSmrg         static _ForwardIterator
2291debfc3dSmrg         __uninit_fill_n(_ForwardIterator __first, _Size __n,
2301debfc3dSmrg 			const _Tp& __x)
2311debfc3dSmrg         {
2321debfc3dSmrg 	  _ForwardIterator __cur = __first;
2331debfc3dSmrg 	  __try
2341debfc3dSmrg 	    {
235a2dc1f3fSmrg 	      for (; __n > 0; --__n, (void) ++__cur)
2361debfc3dSmrg 		std::_Construct(std::__addressof(*__cur), __x);
2371debfc3dSmrg 	      return __cur;
2381debfc3dSmrg 	    }
2391debfc3dSmrg 	  __catch(...)
2401debfc3dSmrg 	    {
2411debfc3dSmrg 	      std::_Destroy(__first, __cur);
2421debfc3dSmrg 	      __throw_exception_again;
2431debfc3dSmrg 	    }
2441debfc3dSmrg 	}
2451debfc3dSmrg     };
2461debfc3dSmrg 
2471debfc3dSmrg   template<>
2481debfc3dSmrg     struct __uninitialized_fill_n<true>
2491debfc3dSmrg     {
2501debfc3dSmrg       template<typename _ForwardIterator, typename _Size, typename _Tp>
2511debfc3dSmrg         static _ForwardIterator
2521debfc3dSmrg         __uninit_fill_n(_ForwardIterator __first, _Size __n,
2531debfc3dSmrg 			const _Tp& __x)
2541debfc3dSmrg         { return std::fill_n(__first, __n, __x); }
2551debfc3dSmrg     };
2561debfc3dSmrg 
2578feb0f0bSmrg   /// @endcond
2588feb0f0bSmrg 
2591debfc3dSmrg    // _GLIBCXX_RESOLVE_LIB_DEFECTS
2601debfc3dSmrg    // DR 1339. uninitialized_fill_n should return the end of its range
2611debfc3dSmrg   /**
2621debfc3dSmrg    *  @brief Copies the value x into the range [first,first+n).
2631debfc3dSmrg    *  @param  __first  An input iterator.
2641debfc3dSmrg    *  @param  __n      The number of copies to make.
2651debfc3dSmrg    *  @param  __x      The source value.
2661debfc3dSmrg    *  @return   Nothing.
2671debfc3dSmrg    *
2681debfc3dSmrg    *  Like fill_n(), but does not require an initialized output range.
2691debfc3dSmrg   */
2701debfc3dSmrg   template<typename _ForwardIterator, typename _Size, typename _Tp>
2711debfc3dSmrg     inline _ForwardIterator
2721debfc3dSmrg     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
2731debfc3dSmrg     {
2741debfc3dSmrg       typedef typename iterator_traits<_ForwardIterator>::value_type
2751debfc3dSmrg 	_ValueType;
2761debfc3dSmrg #if __cplusplus < 201103L
2771debfc3dSmrg       const bool __assignable = true;
2781debfc3dSmrg #else
279c0a68be4Smrg       // Trivial types can have deleted copy constructor, but the std::fill
280c0a68be4Smrg       // optimization that uses memmove would happily "copy" them anyway.
281c0a68be4Smrg       static_assert(is_constructible<_ValueType, const _Tp&>::value,
282c0a68be4Smrg 	  "result type must be constructible from input type");
283c0a68be4Smrg 
284c0a68be4Smrg       // Trivial types can have deleted assignment, so using std::fill
285c0a68be4Smrg       // would be ill-formed. Require assignability before using std::fill:
2861debfc3dSmrg       const bool __assignable = is_copy_assignable<_ValueType>::value;
2871debfc3dSmrg #endif
2881debfc3dSmrg       return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
2891debfc3dSmrg 	__uninit_fill_n(__first, __n, __x);
2901debfc3dSmrg     }
2911debfc3dSmrg 
2928feb0f0bSmrg   /// @cond undocumented
2938feb0f0bSmrg 
2941debfc3dSmrg   // Extensions: versions of uninitialized_copy, uninitialized_fill,
2951debfc3dSmrg   //  and uninitialized_fill_n that take an allocator parameter.
2961debfc3dSmrg   //  We dispatch back to the standard versions when we're given the
2971debfc3dSmrg   //  default allocator.  For nondefault allocators we do not use
2981debfc3dSmrg   //  any of the POD optimizations.
2991debfc3dSmrg 
3001debfc3dSmrg   template<typename _InputIterator, typename _ForwardIterator,
3011debfc3dSmrg 	   typename _Allocator>
3021debfc3dSmrg     _ForwardIterator
3031debfc3dSmrg     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
3041debfc3dSmrg 			   _ForwardIterator __result, _Allocator& __alloc)
3051debfc3dSmrg     {
3061debfc3dSmrg       _ForwardIterator __cur = __result;
3071debfc3dSmrg       __try
3081debfc3dSmrg 	{
3091debfc3dSmrg 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
3101debfc3dSmrg 	  for (; __first != __last; ++__first, (void)++__cur)
3111debfc3dSmrg 	    __traits::construct(__alloc, std::__addressof(*__cur), *__first);
3121debfc3dSmrg 	  return __cur;
3131debfc3dSmrg 	}
3141debfc3dSmrg       __catch(...)
3151debfc3dSmrg 	{
3161debfc3dSmrg 	  std::_Destroy(__result, __cur, __alloc);
3171debfc3dSmrg 	  __throw_exception_again;
3181debfc3dSmrg 	}
3191debfc3dSmrg     }
3201debfc3dSmrg 
3211debfc3dSmrg   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
3221debfc3dSmrg     inline _ForwardIterator
3231debfc3dSmrg     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
3241debfc3dSmrg 			   _ForwardIterator __result, allocator<_Tp>&)
3251debfc3dSmrg     { return std::uninitialized_copy(__first, __last, __result); }
3261debfc3dSmrg 
3271debfc3dSmrg   template<typename _InputIterator, typename _ForwardIterator,
3281debfc3dSmrg 	   typename _Allocator>
3291debfc3dSmrg     inline _ForwardIterator
3301debfc3dSmrg     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
3311debfc3dSmrg 			   _ForwardIterator __result, _Allocator& __alloc)
3321debfc3dSmrg     {
3331debfc3dSmrg       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
3341debfc3dSmrg 					 _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
3351debfc3dSmrg 					 __result, __alloc);
3361debfc3dSmrg     }
3371debfc3dSmrg 
3381debfc3dSmrg   template<typename _InputIterator, typename _ForwardIterator,
3391debfc3dSmrg 	   typename _Allocator>
3401debfc3dSmrg     inline _ForwardIterator
3411debfc3dSmrg     __uninitialized_move_if_noexcept_a(_InputIterator __first,
3421debfc3dSmrg 				       _InputIterator __last,
3431debfc3dSmrg 				       _ForwardIterator __result,
3441debfc3dSmrg 				       _Allocator& __alloc)
3451debfc3dSmrg     {
3461debfc3dSmrg       return std::__uninitialized_copy_a
3471debfc3dSmrg 	(_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
3481debfc3dSmrg 	 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
3491debfc3dSmrg     }
3501debfc3dSmrg 
3511debfc3dSmrg   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
3521debfc3dSmrg     void
3531debfc3dSmrg     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
3541debfc3dSmrg 			   const _Tp& __x, _Allocator& __alloc)
3551debfc3dSmrg     {
3561debfc3dSmrg       _ForwardIterator __cur = __first;
3571debfc3dSmrg       __try
3581debfc3dSmrg 	{
3591debfc3dSmrg 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
3601debfc3dSmrg 	  for (; __cur != __last; ++__cur)
3611debfc3dSmrg 	    __traits::construct(__alloc, std::__addressof(*__cur), __x);
3621debfc3dSmrg 	}
3631debfc3dSmrg       __catch(...)
3641debfc3dSmrg 	{
3651debfc3dSmrg 	  std::_Destroy(__first, __cur, __alloc);
3661debfc3dSmrg 	  __throw_exception_again;
3671debfc3dSmrg 	}
3681debfc3dSmrg     }
3691debfc3dSmrg 
3701debfc3dSmrg   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
3711debfc3dSmrg     inline void
3721debfc3dSmrg     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
3731debfc3dSmrg 			   const _Tp& __x, allocator<_Tp2>&)
3741debfc3dSmrg     { std::uninitialized_fill(__first, __last, __x); }
3751debfc3dSmrg 
3761debfc3dSmrg   template<typename _ForwardIterator, typename _Size, typename _Tp,
3771debfc3dSmrg 	   typename _Allocator>
3781debfc3dSmrg     _ForwardIterator
3791debfc3dSmrg     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
3801debfc3dSmrg 			     const _Tp& __x, _Allocator& __alloc)
3811debfc3dSmrg     {
3821debfc3dSmrg       _ForwardIterator __cur = __first;
3831debfc3dSmrg       __try
3841debfc3dSmrg 	{
3851debfc3dSmrg 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
386a2dc1f3fSmrg 	  for (; __n > 0; --__n, (void) ++__cur)
3871debfc3dSmrg 	    __traits::construct(__alloc, std::__addressof(*__cur), __x);
3881debfc3dSmrg 	  return __cur;
3891debfc3dSmrg 	}
3901debfc3dSmrg       __catch(...)
3911debfc3dSmrg 	{
3921debfc3dSmrg 	  std::_Destroy(__first, __cur, __alloc);
3931debfc3dSmrg 	  __throw_exception_again;
3941debfc3dSmrg 	}
3951debfc3dSmrg     }
3961debfc3dSmrg 
3971debfc3dSmrg   template<typename _ForwardIterator, typename _Size, typename _Tp,
3981debfc3dSmrg 	   typename _Tp2>
3991debfc3dSmrg     inline _ForwardIterator
4001debfc3dSmrg     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
4011debfc3dSmrg 			     const _Tp& __x, allocator<_Tp2>&)
4021debfc3dSmrg     { return std::uninitialized_fill_n(__first, __n, __x); }
4031debfc3dSmrg 
4041debfc3dSmrg 
4051debfc3dSmrg   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
4061debfc3dSmrg   // __uninitialized_fill_move, __uninitialized_move_fill.
4071debfc3dSmrg   // All of these algorithms take a user-supplied allocator, which is used
4081debfc3dSmrg   // for construction and destruction.
4091debfc3dSmrg 
4101debfc3dSmrg   // __uninitialized_copy_move
4111debfc3dSmrg   // Copies [first1, last1) into [result, result + (last1 - first1)), and
4121debfc3dSmrg   //  move [first2, last2) into
4131debfc3dSmrg   //  [result, result + (last1 - first1) + (last2 - first2)).
4141debfc3dSmrg   template<typename _InputIterator1, typename _InputIterator2,
4151debfc3dSmrg 	   typename _ForwardIterator, typename _Allocator>
4161debfc3dSmrg     inline _ForwardIterator
4171debfc3dSmrg     __uninitialized_copy_move(_InputIterator1 __first1,
4181debfc3dSmrg 			      _InputIterator1 __last1,
4191debfc3dSmrg 			      _InputIterator2 __first2,
4201debfc3dSmrg 			      _InputIterator2 __last2,
4211debfc3dSmrg 			      _ForwardIterator __result,
4221debfc3dSmrg 			      _Allocator& __alloc)
4231debfc3dSmrg     {
4241debfc3dSmrg       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
4251debfc3dSmrg 							   __result,
4261debfc3dSmrg 							   __alloc);
4271debfc3dSmrg       __try
4281debfc3dSmrg 	{
4291debfc3dSmrg 	  return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
4301debfc3dSmrg 	}
4311debfc3dSmrg       __catch(...)
4321debfc3dSmrg 	{
4331debfc3dSmrg 	  std::_Destroy(__result, __mid, __alloc);
4341debfc3dSmrg 	  __throw_exception_again;
4351debfc3dSmrg 	}
4361debfc3dSmrg     }
4371debfc3dSmrg 
4381debfc3dSmrg   // __uninitialized_move_copy
4391debfc3dSmrg   // Moves [first1, last1) into [result, result + (last1 - first1)), and
4401debfc3dSmrg   //  copies [first2, last2) into
4411debfc3dSmrg   //  [result, result + (last1 - first1) + (last2 - first2)).
4421debfc3dSmrg   template<typename _InputIterator1, typename _InputIterator2,
4431debfc3dSmrg 	   typename _ForwardIterator, typename _Allocator>
4441debfc3dSmrg     inline _ForwardIterator
4451debfc3dSmrg     __uninitialized_move_copy(_InputIterator1 __first1,
4461debfc3dSmrg 			      _InputIterator1 __last1,
4471debfc3dSmrg 			      _InputIterator2 __first2,
4481debfc3dSmrg 			      _InputIterator2 __last2,
4491debfc3dSmrg 			      _ForwardIterator __result,
4501debfc3dSmrg 			      _Allocator& __alloc)
4511debfc3dSmrg     {
4521debfc3dSmrg       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
4531debfc3dSmrg 							   __result,
4541debfc3dSmrg 							   __alloc);
4551debfc3dSmrg       __try
4561debfc3dSmrg 	{
4571debfc3dSmrg 	  return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
4581debfc3dSmrg 	}
4591debfc3dSmrg       __catch(...)
4601debfc3dSmrg 	{
4611debfc3dSmrg 	  std::_Destroy(__result, __mid, __alloc);
4621debfc3dSmrg 	  __throw_exception_again;
4631debfc3dSmrg 	}
4641debfc3dSmrg     }
4651debfc3dSmrg 
4661debfc3dSmrg   // __uninitialized_fill_move
4671debfc3dSmrg   // Fills [result, mid) with x, and moves [first, last) into
4681debfc3dSmrg   //  [mid, mid + (last - first)).
4691debfc3dSmrg   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
4701debfc3dSmrg 	   typename _Allocator>
4711debfc3dSmrg     inline _ForwardIterator
4721debfc3dSmrg     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
4731debfc3dSmrg 			      const _Tp& __x, _InputIterator __first,
4741debfc3dSmrg 			      _InputIterator __last, _Allocator& __alloc)
4751debfc3dSmrg     {
4761debfc3dSmrg       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
4771debfc3dSmrg       __try
4781debfc3dSmrg 	{
4791debfc3dSmrg 	  return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
4801debfc3dSmrg 	}
4811debfc3dSmrg       __catch(...)
4821debfc3dSmrg 	{
4831debfc3dSmrg 	  std::_Destroy(__result, __mid, __alloc);
4841debfc3dSmrg 	  __throw_exception_again;
4851debfc3dSmrg 	}
4861debfc3dSmrg     }
4871debfc3dSmrg 
4881debfc3dSmrg   // __uninitialized_move_fill
4891debfc3dSmrg   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
4901debfc3dSmrg   //  fills [first2 + (last1 - first1), last2) with x.
4911debfc3dSmrg   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
4921debfc3dSmrg 	   typename _Allocator>
4931debfc3dSmrg     inline void
4941debfc3dSmrg     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
4951debfc3dSmrg 			      _ForwardIterator __first2,
4961debfc3dSmrg 			      _ForwardIterator __last2, const _Tp& __x,
4971debfc3dSmrg 			      _Allocator& __alloc)
4981debfc3dSmrg     {
4991debfc3dSmrg       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
5001debfc3dSmrg 							    __first2,
5011debfc3dSmrg 							    __alloc);
5021debfc3dSmrg       __try
5031debfc3dSmrg 	{
5041debfc3dSmrg 	  std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
5051debfc3dSmrg 	}
5061debfc3dSmrg       __catch(...)
5071debfc3dSmrg 	{
5081debfc3dSmrg 	  std::_Destroy(__first2, __mid2, __alloc);
5091debfc3dSmrg 	  __throw_exception_again;
5101debfc3dSmrg 	}
5111debfc3dSmrg     }
5121debfc3dSmrg 
5138feb0f0bSmrg   /// @endcond
5148feb0f0bSmrg 
5151debfc3dSmrg #if __cplusplus >= 201103L
5168feb0f0bSmrg   /// @cond undocumented
5178feb0f0bSmrg 
5181debfc3dSmrg   // Extensions: __uninitialized_default, __uninitialized_default_n,
5191debfc3dSmrg   // __uninitialized_default_a, __uninitialized_default_n_a.
5201debfc3dSmrg 
5211debfc3dSmrg   template<bool _TrivialValueType>
5221debfc3dSmrg     struct __uninitialized_default_1
5231debfc3dSmrg     {
5241debfc3dSmrg       template<typename _ForwardIterator>
5251debfc3dSmrg         static void
5261debfc3dSmrg         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
5271debfc3dSmrg         {
5281debfc3dSmrg 	  _ForwardIterator __cur = __first;
5291debfc3dSmrg 	  __try
5301debfc3dSmrg 	    {
5311debfc3dSmrg 	      for (; __cur != __last; ++__cur)
5321debfc3dSmrg 		std::_Construct(std::__addressof(*__cur));
5331debfc3dSmrg 	    }
5341debfc3dSmrg 	  __catch(...)
5351debfc3dSmrg 	    {
5361debfc3dSmrg 	      std::_Destroy(__first, __cur);
5371debfc3dSmrg 	      __throw_exception_again;
5381debfc3dSmrg 	    }
5391debfc3dSmrg 	}
5401debfc3dSmrg     };
5411debfc3dSmrg 
5421debfc3dSmrg   template<>
5431debfc3dSmrg     struct __uninitialized_default_1<true>
5441debfc3dSmrg     {
5451debfc3dSmrg       template<typename _ForwardIterator>
5461debfc3dSmrg         static void
5471debfc3dSmrg         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
5481debfc3dSmrg         {
5491debfc3dSmrg 	  typedef typename iterator_traits<_ForwardIterator>::value_type
5501debfc3dSmrg 	    _ValueType;
5511debfc3dSmrg 
552*23f5f463Smrg 	  if (__first == __last)
553*23f5f463Smrg 	    return;
554*23f5f463Smrg 
555*23f5f463Smrg 	  typename iterator_traits<_ForwardIterator>::value_type* __val
556*23f5f463Smrg 	    = std::__addressof(*__first);
557*23f5f463Smrg 	  std::_Construct(__val);
558*23f5f463Smrg 	  if (++__first != __last)
559*23f5f463Smrg 	    std::fill(__first, __last, *__val);
5601debfc3dSmrg 	}
5611debfc3dSmrg     };
5621debfc3dSmrg 
5631debfc3dSmrg   template<bool _TrivialValueType>
5641debfc3dSmrg     struct __uninitialized_default_n_1
5651debfc3dSmrg     {
5661debfc3dSmrg       template<typename _ForwardIterator, typename _Size>
5671debfc3dSmrg         static _ForwardIterator
5681debfc3dSmrg         __uninit_default_n(_ForwardIterator __first, _Size __n)
5691debfc3dSmrg         {
5701debfc3dSmrg 	  _ForwardIterator __cur = __first;
5711debfc3dSmrg 	  __try
5721debfc3dSmrg 	    {
573a2dc1f3fSmrg 	      for (; __n > 0; --__n, (void) ++__cur)
5741debfc3dSmrg 		std::_Construct(std::__addressof(*__cur));
5751debfc3dSmrg 	      return __cur;
5761debfc3dSmrg 	    }
5771debfc3dSmrg 	  __catch(...)
5781debfc3dSmrg 	    {
5791debfc3dSmrg 	      std::_Destroy(__first, __cur);
5801debfc3dSmrg 	      __throw_exception_again;
5811debfc3dSmrg 	    }
5821debfc3dSmrg 	}
5831debfc3dSmrg     };
5841debfc3dSmrg 
5851debfc3dSmrg   template<>
5861debfc3dSmrg     struct __uninitialized_default_n_1<true>
5871debfc3dSmrg     {
5881debfc3dSmrg       template<typename _ForwardIterator, typename _Size>
5891debfc3dSmrg         static _ForwardIterator
5901debfc3dSmrg         __uninit_default_n(_ForwardIterator __first, _Size __n)
5911debfc3dSmrg         {
592*23f5f463Smrg 	  if (__n > 0)
593*23f5f463Smrg 	    {
594*23f5f463Smrg 	      typename iterator_traits<_ForwardIterator>::value_type* __val
595*23f5f463Smrg 		= std::__addressof(*__first);
596*23f5f463Smrg 	      std::_Construct(__val);
597*23f5f463Smrg 	      ++__first;
598*23f5f463Smrg 	      __first = std::fill_n(__first, __n - 1, *__val);
599*23f5f463Smrg 	    }
600*23f5f463Smrg 	  return __first;
6011debfc3dSmrg 	}
6021debfc3dSmrg     };
6031debfc3dSmrg 
6041debfc3dSmrg   // __uninitialized_default
605*23f5f463Smrg   // Fills [first, last) with value-initialized value_types.
6061debfc3dSmrg   template<typename _ForwardIterator>
6071debfc3dSmrg     inline void
6081debfc3dSmrg     __uninitialized_default(_ForwardIterator __first,
6091debfc3dSmrg 			    _ForwardIterator __last)
6101debfc3dSmrg     {
6111debfc3dSmrg       typedef typename iterator_traits<_ForwardIterator>::value_type
6121debfc3dSmrg 	_ValueType;
6131debfc3dSmrg       // trivial types can have deleted assignment
6141debfc3dSmrg       const bool __assignable = is_copy_assignable<_ValueType>::value;
6151debfc3dSmrg 
6161debfc3dSmrg       std::__uninitialized_default_1<__is_trivial(_ValueType)
6171debfc3dSmrg 				     && __assignable>::
6181debfc3dSmrg 	__uninit_default(__first, __last);
6191debfc3dSmrg     }
6201debfc3dSmrg 
6211debfc3dSmrg   // __uninitialized_default_n
622*23f5f463Smrg   // Fills [first, first + n) with value-initialized value_types.
6231debfc3dSmrg   template<typename _ForwardIterator, typename _Size>
6241debfc3dSmrg     inline _ForwardIterator
6251debfc3dSmrg     __uninitialized_default_n(_ForwardIterator __first, _Size __n)
6261debfc3dSmrg     {
6271debfc3dSmrg       typedef typename iterator_traits<_ForwardIterator>::value_type
6281debfc3dSmrg 	_ValueType;
6291debfc3dSmrg       // trivial types can have deleted assignment
6301debfc3dSmrg       const bool __assignable = is_copy_assignable<_ValueType>::value;
6311debfc3dSmrg 
6321debfc3dSmrg       return __uninitialized_default_n_1<__is_trivial(_ValueType)
6331debfc3dSmrg 				       && __assignable>::
6341debfc3dSmrg 	__uninit_default_n(__first, __n);
6351debfc3dSmrg     }
6361debfc3dSmrg 
6371debfc3dSmrg 
6381debfc3dSmrg   // __uninitialized_default_a
639*23f5f463Smrg   // Fills [first, last) with value_types constructed by the allocator
640*23f5f463Smrg   // alloc, with no arguments passed to the construct call.
6411debfc3dSmrg   template<typename _ForwardIterator, typename _Allocator>
6421debfc3dSmrg     void
6431debfc3dSmrg     __uninitialized_default_a(_ForwardIterator __first,
6441debfc3dSmrg 			      _ForwardIterator __last,
6451debfc3dSmrg 			      _Allocator& __alloc)
6461debfc3dSmrg     {
6471debfc3dSmrg       _ForwardIterator __cur = __first;
6481debfc3dSmrg       __try
6491debfc3dSmrg 	{
6501debfc3dSmrg 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
6511debfc3dSmrg 	  for (; __cur != __last; ++__cur)
6521debfc3dSmrg 	    __traits::construct(__alloc, std::__addressof(*__cur));
6531debfc3dSmrg 	}
6541debfc3dSmrg       __catch(...)
6551debfc3dSmrg 	{
6561debfc3dSmrg 	  std::_Destroy(__first, __cur, __alloc);
6571debfc3dSmrg 	  __throw_exception_again;
6581debfc3dSmrg 	}
6591debfc3dSmrg     }
6601debfc3dSmrg 
6611debfc3dSmrg   template<typename _ForwardIterator, typename _Tp>
6621debfc3dSmrg     inline void
6631debfc3dSmrg     __uninitialized_default_a(_ForwardIterator __first,
6641debfc3dSmrg 			      _ForwardIterator __last,
6651debfc3dSmrg 			      allocator<_Tp>&)
6661debfc3dSmrg     { std::__uninitialized_default(__first, __last); }
6671debfc3dSmrg 
6681debfc3dSmrg 
6691debfc3dSmrg   // __uninitialized_default_n_a
670*23f5f463Smrg   // Fills [first, first + n) with value_types constructed by the allocator
671*23f5f463Smrg   // alloc, with no arguments passed to the construct call.
6721debfc3dSmrg   template<typename _ForwardIterator, typename _Size, typename _Allocator>
6731debfc3dSmrg     _ForwardIterator
6741debfc3dSmrg     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
6751debfc3dSmrg 				_Allocator& __alloc)
6761debfc3dSmrg     {
6771debfc3dSmrg       _ForwardIterator __cur = __first;
6781debfc3dSmrg       __try
6791debfc3dSmrg 	{
6801debfc3dSmrg 	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
681a2dc1f3fSmrg 	  for (; __n > 0; --__n, (void) ++__cur)
6821debfc3dSmrg 	    __traits::construct(__alloc, std::__addressof(*__cur));
6831debfc3dSmrg 	  return __cur;
6841debfc3dSmrg 	}
6851debfc3dSmrg       __catch(...)
6861debfc3dSmrg 	{
6871debfc3dSmrg 	  std::_Destroy(__first, __cur, __alloc);
6881debfc3dSmrg 	  __throw_exception_again;
6891debfc3dSmrg 	}
6901debfc3dSmrg     }
6911debfc3dSmrg 
692*23f5f463Smrg   // __uninitialized_default_n_a specialization for std::allocator,
693*23f5f463Smrg   // which ignores the allocator and value-initializes the elements.
6941debfc3dSmrg   template<typename _ForwardIterator, typename _Size, typename _Tp>
6951debfc3dSmrg     inline _ForwardIterator
6961debfc3dSmrg     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
6971debfc3dSmrg 				allocator<_Tp>&)
6981debfc3dSmrg     { return std::__uninitialized_default_n(__first, __n); }
6991debfc3dSmrg 
7001debfc3dSmrg   template<bool _TrivialValueType>
7011debfc3dSmrg     struct __uninitialized_default_novalue_1
7021debfc3dSmrg     {
7031debfc3dSmrg       template<typename _ForwardIterator>
7041debfc3dSmrg 	static void
7051debfc3dSmrg 	__uninit_default_novalue(_ForwardIterator __first,
7061debfc3dSmrg 				 _ForwardIterator __last)
7071debfc3dSmrg 	{
7081debfc3dSmrg 	  _ForwardIterator __cur = __first;
7091debfc3dSmrg 	  __try
7101debfc3dSmrg 	    {
7111debfc3dSmrg 	      for (; __cur != __last; ++__cur)
7121debfc3dSmrg 		std::_Construct_novalue(std::__addressof(*__cur));
7131debfc3dSmrg 	    }
7141debfc3dSmrg 	  __catch(...)
7151debfc3dSmrg 	    {
7161debfc3dSmrg 	      std::_Destroy(__first, __cur);
7171debfc3dSmrg 	      __throw_exception_again;
7181debfc3dSmrg 	    }
7191debfc3dSmrg 	}
7201debfc3dSmrg     };
7211debfc3dSmrg 
7221debfc3dSmrg   template<>
7231debfc3dSmrg     struct __uninitialized_default_novalue_1<true>
7241debfc3dSmrg     {
7251debfc3dSmrg       template<typename _ForwardIterator>
7261debfc3dSmrg         static void
7271debfc3dSmrg         __uninit_default_novalue(_ForwardIterator __first,
7281debfc3dSmrg 				 _ForwardIterator __last)
7291debfc3dSmrg 	{
7301debfc3dSmrg 	}
7311debfc3dSmrg     };
7321debfc3dSmrg 
7331debfc3dSmrg   template<bool _TrivialValueType>
7341debfc3dSmrg     struct __uninitialized_default_novalue_n_1
7351debfc3dSmrg     {
7361debfc3dSmrg       template<typename _ForwardIterator, typename _Size>
7371debfc3dSmrg 	static _ForwardIterator
7381debfc3dSmrg 	__uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
7391debfc3dSmrg 	{
7401debfc3dSmrg 	  _ForwardIterator __cur = __first;
7411debfc3dSmrg 	  __try
7421debfc3dSmrg 	    {
743a2dc1f3fSmrg 	      for (; __n > 0; --__n, (void) ++__cur)
7441debfc3dSmrg 		std::_Construct_novalue(std::__addressof(*__cur));
7451debfc3dSmrg 	      return __cur;
7461debfc3dSmrg 	    }
7471debfc3dSmrg 	  __catch(...)
7481debfc3dSmrg 	    {
7491debfc3dSmrg 	      std::_Destroy(__first, __cur);
7501debfc3dSmrg 	      __throw_exception_again;
7511debfc3dSmrg 	    }
7521debfc3dSmrg 	}
7531debfc3dSmrg     };
7541debfc3dSmrg 
7551debfc3dSmrg   template<>
7561debfc3dSmrg     struct __uninitialized_default_novalue_n_1<true>
7571debfc3dSmrg     {
7581debfc3dSmrg       template<typename _ForwardIterator, typename _Size>
7591debfc3dSmrg 	static _ForwardIterator
7601debfc3dSmrg 	__uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
7611debfc3dSmrg 	{ return std::next(__first, __n); }
7621debfc3dSmrg     };
7631debfc3dSmrg 
7641debfc3dSmrg   // __uninitialized_default_novalue
765*23f5f463Smrg   // Fills [first, last) with default-initialized value_types.
7661debfc3dSmrg   template<typename _ForwardIterator>
7671debfc3dSmrg     inline void
7681debfc3dSmrg     __uninitialized_default_novalue(_ForwardIterator __first,
7691debfc3dSmrg 				    _ForwardIterator __last)
7701debfc3dSmrg     {
7711debfc3dSmrg       typedef typename iterator_traits<_ForwardIterator>::value_type
7721debfc3dSmrg 	_ValueType;
7731debfc3dSmrg 
7741debfc3dSmrg       std::__uninitialized_default_novalue_1<
7751debfc3dSmrg 	is_trivially_default_constructible<_ValueType>::value>::
7761debfc3dSmrg 	__uninit_default_novalue(__first, __last);
7771debfc3dSmrg     }
7781debfc3dSmrg 
779*23f5f463Smrg   // __uninitialized_default_novalue_n
780*23f5f463Smrg   // Fills [first, first + n) with default-initialized value_types.
7811debfc3dSmrg   template<typename _ForwardIterator, typename _Size>
7821debfc3dSmrg     inline _ForwardIterator
7831debfc3dSmrg     __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
7841debfc3dSmrg     {
7851debfc3dSmrg       typedef typename iterator_traits<_ForwardIterator>::value_type
7861debfc3dSmrg 	_ValueType;
7871debfc3dSmrg 
7881debfc3dSmrg       return __uninitialized_default_novalue_n_1<
7891debfc3dSmrg 	is_trivially_default_constructible<_ValueType>::value>::
7901debfc3dSmrg 	__uninit_default_novalue_n(__first, __n);
7911debfc3dSmrg     }
7921debfc3dSmrg 
7931debfc3dSmrg   template<typename _InputIterator, typename _Size,
7941debfc3dSmrg 	   typename _ForwardIterator>
7951debfc3dSmrg     _ForwardIterator
7961debfc3dSmrg     __uninitialized_copy_n(_InputIterator __first, _Size __n,
7971debfc3dSmrg 			   _ForwardIterator __result, input_iterator_tag)
7981debfc3dSmrg     {
7991debfc3dSmrg       _ForwardIterator __cur = __result;
8001debfc3dSmrg       __try
8011debfc3dSmrg 	{
802a2dc1f3fSmrg 	  for (; __n > 0; --__n, (void) ++__first, ++__cur)
8031debfc3dSmrg 	    std::_Construct(std::__addressof(*__cur), *__first);
8041debfc3dSmrg 	  return __cur;
8051debfc3dSmrg 	}
8061debfc3dSmrg       __catch(...)
8071debfc3dSmrg 	{
8081debfc3dSmrg 	  std::_Destroy(__result, __cur);
8091debfc3dSmrg 	  __throw_exception_again;
8101debfc3dSmrg 	}
8111debfc3dSmrg     }
8121debfc3dSmrg 
8131debfc3dSmrg   template<typename _RandomAccessIterator, typename _Size,
8141debfc3dSmrg 	   typename _ForwardIterator>
8151debfc3dSmrg     inline _ForwardIterator
8161debfc3dSmrg     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
8171debfc3dSmrg 			   _ForwardIterator __result,
8181debfc3dSmrg 			   random_access_iterator_tag)
8191debfc3dSmrg     { return std::uninitialized_copy(__first, __first + __n, __result); }
8201debfc3dSmrg 
8211debfc3dSmrg   template<typename _InputIterator, typename _Size,
8221debfc3dSmrg 	   typename _ForwardIterator>
8231debfc3dSmrg     pair<_InputIterator, _ForwardIterator>
8241debfc3dSmrg     __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
8251debfc3dSmrg 			   _ForwardIterator __result, input_iterator_tag)
8261debfc3dSmrg     {
8271debfc3dSmrg       _ForwardIterator __cur = __result;
8281debfc3dSmrg       __try
8291debfc3dSmrg 	{
830a2dc1f3fSmrg 	  for (; __n > 0; --__n, (void) ++__first, ++__cur)
8311debfc3dSmrg 	    std::_Construct(std::__addressof(*__cur), *__first);
8321debfc3dSmrg 	  return {__first, __cur};
8331debfc3dSmrg 	}
8341debfc3dSmrg       __catch(...)
8351debfc3dSmrg 	{
8361debfc3dSmrg 	  std::_Destroy(__result, __cur);
8371debfc3dSmrg 	  __throw_exception_again;
8381debfc3dSmrg 	}
8391debfc3dSmrg     }
8401debfc3dSmrg 
8411debfc3dSmrg   template<typename _RandomAccessIterator, typename _Size,
8421debfc3dSmrg 	   typename _ForwardIterator>
8431debfc3dSmrg     inline pair<_RandomAccessIterator, _ForwardIterator>
8441debfc3dSmrg     __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
8451debfc3dSmrg 			   _ForwardIterator __result,
8461debfc3dSmrg 			   random_access_iterator_tag)
8471debfc3dSmrg     {
8481debfc3dSmrg       auto __second_res = uninitialized_copy(__first, __first + __n, __result);
8491debfc3dSmrg       auto __first_res = std::next(__first, __n);
8501debfc3dSmrg       return {__first_res, __second_res};
8511debfc3dSmrg     }
8521debfc3dSmrg 
8538feb0f0bSmrg   /// @endcond
8548feb0f0bSmrg 
8551debfc3dSmrg   /**
8561debfc3dSmrg    *  @brief Copies the range [first,first+n) into result.
8571debfc3dSmrg    *  @param  __first  An input iterator.
8581debfc3dSmrg    *  @param  __n      The number of elements to copy.
8591debfc3dSmrg    *  @param  __result An output iterator.
8601debfc3dSmrg    *  @return  __result + __n
8611debfc3dSmrg    *
8621debfc3dSmrg    *  Like copy_n(), but does not require an initialized output range.
8631debfc3dSmrg   */
8641debfc3dSmrg   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
8651debfc3dSmrg     inline _ForwardIterator
8661debfc3dSmrg     uninitialized_copy_n(_InputIterator __first, _Size __n,
8671debfc3dSmrg 			 _ForwardIterator __result)
8681debfc3dSmrg     { return std::__uninitialized_copy_n(__first, __n, __result,
8691debfc3dSmrg 					 std::__iterator_category(__first)); }
8701debfc3dSmrg 
8718feb0f0bSmrg   /// @cond undocumented
8721debfc3dSmrg   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
8731debfc3dSmrg     inline pair<_InputIterator, _ForwardIterator>
8741debfc3dSmrg     __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
8751debfc3dSmrg 			      _ForwardIterator __result)
8761debfc3dSmrg     {
8771debfc3dSmrg       return
8781debfc3dSmrg 	std::__uninitialized_copy_n_pair(__first, __n, __result,
8791debfc3dSmrg 					 std::__iterator_category(__first));
8801debfc3dSmrg     }
8818feb0f0bSmrg   /// @endcond
8821debfc3dSmrg #endif
8831debfc3dSmrg 
884a2dc1f3fSmrg #if __cplusplus >= 201703L
885a2dc1f3fSmrg # define __cpp_lib_raw_memory_algorithms 201606L
886a2dc1f3fSmrg 
8878feb0f0bSmrg   /**
8888feb0f0bSmrg    *  @brief Default-initializes objects in the range [first,last).
8898feb0f0bSmrg    *  @param  __first  A forward iterator.
8908feb0f0bSmrg    *  @param  __last   A forward iterator.
8918feb0f0bSmrg   */
8921debfc3dSmrg   template <typename _ForwardIterator>
8931debfc3dSmrg     inline void
8941debfc3dSmrg     uninitialized_default_construct(_ForwardIterator __first,
8951debfc3dSmrg 				    _ForwardIterator __last)
8961debfc3dSmrg     {
8971debfc3dSmrg       __uninitialized_default_novalue(__first, __last);
8981debfc3dSmrg     }
8991debfc3dSmrg 
9008feb0f0bSmrg   /**
9018feb0f0bSmrg    *  @brief Default-initializes objects in the range [first,first+count).
9028feb0f0bSmrg    *  @param  __first  A forward iterator.
9038feb0f0bSmrg    *  @param  __count  The number of objects to construct.
9048feb0f0bSmrg    *  @return   __first + __count
9058feb0f0bSmrg   */
9061debfc3dSmrg   template <typename _ForwardIterator, typename _Size>
9071debfc3dSmrg     inline _ForwardIterator
9081debfc3dSmrg     uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
9091debfc3dSmrg     {
9101debfc3dSmrg       return __uninitialized_default_novalue_n(__first, __count);
9111debfc3dSmrg     }
9121debfc3dSmrg 
9138feb0f0bSmrg   /**
9148feb0f0bSmrg    *  @brief Value-initializes objects in the range [first,last).
9158feb0f0bSmrg    *  @param  __first  A forward iterator.
9168feb0f0bSmrg    *  @param  __last   A forward iterator.
9178feb0f0bSmrg   */
9181debfc3dSmrg   template <typename _ForwardIterator>
9191debfc3dSmrg     inline void
9201debfc3dSmrg     uninitialized_value_construct(_ForwardIterator __first,
9211debfc3dSmrg 				  _ForwardIterator __last)
9221debfc3dSmrg     {
9231debfc3dSmrg       return __uninitialized_default(__first, __last);
9241debfc3dSmrg     }
9251debfc3dSmrg 
9268feb0f0bSmrg   /**
9278feb0f0bSmrg    *  @brief Value-initializes objects in the range [first,first+count).
9288feb0f0bSmrg    *  @param  __first  A forward iterator.
9298feb0f0bSmrg    *  @param  __count  The number of objects to construct.
9308feb0f0bSmrg    *  @return   __result + __count
9318feb0f0bSmrg   */
9321debfc3dSmrg   template <typename _ForwardIterator, typename _Size>
9331debfc3dSmrg     inline _ForwardIterator
9341debfc3dSmrg     uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
9351debfc3dSmrg     {
9361debfc3dSmrg       return __uninitialized_default_n(__first, __count);
9371debfc3dSmrg     }
9381debfc3dSmrg 
9398feb0f0bSmrg   /**
9408feb0f0bSmrg    *  @brief Move-construct from the range [first,last) into result.
9418feb0f0bSmrg    *  @param  __first  An input iterator.
9428feb0f0bSmrg    *  @param  __last   An input iterator.
9438feb0f0bSmrg    *  @param  __result An output iterator.
9448feb0f0bSmrg    *  @return   __result + (__first - __last)
9458feb0f0bSmrg   */
9461debfc3dSmrg   template <typename _InputIterator, typename _ForwardIterator>
9471debfc3dSmrg     inline _ForwardIterator
9481debfc3dSmrg     uninitialized_move(_InputIterator __first, _InputIterator __last,
9491debfc3dSmrg 		       _ForwardIterator __result)
9501debfc3dSmrg     {
9511debfc3dSmrg       return std::uninitialized_copy
9521debfc3dSmrg 	(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
9531debfc3dSmrg 	 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
9541debfc3dSmrg     }
9551debfc3dSmrg 
9568feb0f0bSmrg   /**
9578feb0f0bSmrg    *  @brief Move-construct from the range [first,first+count) into result.
9588feb0f0bSmrg    *  @param  __first  An input iterator.
9598feb0f0bSmrg    *  @param  __count  The number of objects to initialize.
9608feb0f0bSmrg    *  @param  __result An output iterator.
9618feb0f0bSmrg    *  @return  __result + __count
9628feb0f0bSmrg   */
9631debfc3dSmrg   template <typename _InputIterator, typename _Size, typename _ForwardIterator>
9641debfc3dSmrg     inline pair<_InputIterator, _ForwardIterator>
9651debfc3dSmrg     uninitialized_move_n(_InputIterator __first, _Size __count,
9661debfc3dSmrg 			 _ForwardIterator __result)
9671debfc3dSmrg     {
9681debfc3dSmrg       auto __res = std::__uninitialized_copy_n_pair
9691debfc3dSmrg 	(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
9701debfc3dSmrg 	 __count, __result);
9711debfc3dSmrg       return {__res.first.base(), __res.second};
9721debfc3dSmrg     }
973a2dc1f3fSmrg #endif // C++17
9741debfc3dSmrg 
975c0a68be4Smrg #if __cplusplus >= 201103L
9768feb0f0bSmrg   /// @cond undocumented
9778feb0f0bSmrg 
978c0a68be4Smrg   template<typename _Tp, typename _Up, typename _Allocator>
979c0a68be4Smrg     inline void
9808feb0f0bSmrg     __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig,
9818feb0f0bSmrg 			_Allocator& __alloc)
982c0a68be4Smrg     noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc,
983c0a68be4Smrg 			 __dest, std::move(*__orig)))
984c0a68be4Smrg 	     && noexcept(std::allocator_traits<_Allocator>::destroy(
985c0a68be4Smrg 			    __alloc, std::__addressof(*__orig))))
986c0a68be4Smrg     {
987c0a68be4Smrg       typedef std::allocator_traits<_Allocator> __traits;
988c0a68be4Smrg       __traits::construct(__alloc, __dest, std::move(*__orig));
989c0a68be4Smrg       __traits::destroy(__alloc, std::__addressof(*__orig));
990c0a68be4Smrg     }
991c0a68be4Smrg 
992c0a68be4Smrg   // This class may be specialized for specific types.
993c0a68be4Smrg   // Also known as is_trivially_relocatable.
994c0a68be4Smrg   template<typename _Tp, typename = void>
995c0a68be4Smrg     struct __is_bitwise_relocatable
996c0a68be4Smrg     : is_trivial<_Tp> { };
997c0a68be4Smrg 
998c0a68be4Smrg   template <typename _Tp, typename _Up>
999c0a68be4Smrg     inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*>
1000c0a68be4Smrg     __relocate_a_1(_Tp* __first, _Tp* __last,
1001c0a68be4Smrg 		   _Tp* __result, allocator<_Up>&) noexcept
1002c0a68be4Smrg     {
1003c0a68be4Smrg       ptrdiff_t __count = __last - __first;
1004c0a68be4Smrg       if (__count > 0)
1005c0a68be4Smrg 	__builtin_memmove(__result, __first, __count * sizeof(_Tp));
1006c0a68be4Smrg       return __result + __count;
1007c0a68be4Smrg     }
1008c0a68be4Smrg 
1009c0a68be4Smrg   template <typename _InputIterator, typename _ForwardIterator,
1010c0a68be4Smrg 	    typename _Allocator>
1011c0a68be4Smrg     inline _ForwardIterator
1012c0a68be4Smrg     __relocate_a_1(_InputIterator __first, _InputIterator __last,
1013c0a68be4Smrg 		   _ForwardIterator __result, _Allocator& __alloc)
1014c0a68be4Smrg     noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result),
1015c0a68be4Smrg 					       std::addressof(*__first),
1016c0a68be4Smrg 					       __alloc)))
1017c0a68be4Smrg     {
1018c0a68be4Smrg       typedef typename iterator_traits<_InputIterator>::value_type
1019c0a68be4Smrg 	_ValueType;
1020c0a68be4Smrg       typedef typename iterator_traits<_ForwardIterator>::value_type
1021c0a68be4Smrg 	_ValueType2;
1022c0a68be4Smrg       static_assert(std::is_same<_ValueType, _ValueType2>::value,
1023c0a68be4Smrg 	  "relocation is only possible for values of the same type");
1024c0a68be4Smrg       _ForwardIterator __cur = __result;
1025c0a68be4Smrg       for (; __first != __last; ++__first, (void)++__cur)
1026c0a68be4Smrg 	std::__relocate_object_a(std::__addressof(*__cur),
1027c0a68be4Smrg 				 std::__addressof(*__first), __alloc);
1028c0a68be4Smrg       return __cur;
1029c0a68be4Smrg     }
1030c0a68be4Smrg 
1031c0a68be4Smrg   template <typename _InputIterator, typename _ForwardIterator,
1032c0a68be4Smrg 	    typename _Allocator>
1033c0a68be4Smrg     inline _ForwardIterator
1034c0a68be4Smrg     __relocate_a(_InputIterator __first, _InputIterator __last,
1035c0a68be4Smrg 		 _ForwardIterator __result, _Allocator& __alloc)
1036c0a68be4Smrg     noexcept(noexcept(__relocate_a_1(std::__niter_base(__first),
1037c0a68be4Smrg 				     std::__niter_base(__last),
1038c0a68be4Smrg 				     std::__niter_base(__result), __alloc)))
1039c0a68be4Smrg     {
1040c0a68be4Smrg       return __relocate_a_1(std::__niter_base(__first),
1041c0a68be4Smrg 			    std::__niter_base(__last),
1042c0a68be4Smrg 			    std::__niter_base(__result), __alloc);
1043c0a68be4Smrg     }
10448feb0f0bSmrg 
10458feb0f0bSmrg   /// @endcond
1046c0a68be4Smrg #endif
1047c0a68be4Smrg 
10488feb0f0bSmrg   /// @} group memory
10498feb0f0bSmrg 
10501debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
10511debfc3dSmrg } // namespace
10521debfc3dSmrg 
10531debfc3dSmrg #endif /* _STL_UNINITIALIZED_H */
1054