(root)/
gcc-13.2.0/
libstdc++-v3/
include/
bits/
stl_uninitialized.h
       1  // Raw memory manipulators -*- C++ -*-
       2  
       3  // Copyright (C) 2001-2023 Free Software Foundation, Inc.
       4  //
       5  // This file is part of the GNU ISO C++ Library.  This library is free
       6  // software; you can redistribute it and/or modify it under the
       7  // terms of the GNU General Public License as published by the
       8  // Free Software Foundation; either version 3, or (at your option)
       9  // any later version.
      10  
      11  // This library is distributed in the hope that it will be useful,
      12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  // GNU General Public License for more details.
      15  
      16  // Under Section 7 of GPL version 3, you are granted additional
      17  // permissions described in the GCC Runtime Library Exception, version
      18  // 3.1, as published by the Free Software Foundation.
      19  
      20  // You should have received a copy of the GNU General Public License and
      21  // a copy of the GCC Runtime Library Exception along with this program;
      22  // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23  // <http://www.gnu.org/licenses/>.
      24  
      25  /*
      26   *
      27   * Copyright (c) 1994
      28   * Hewlett-Packard Company
      29   *
      30   * Permission to use, copy, modify, distribute and sell this software
      31   * and its documentation for any purpose is hereby granted without fee,
      32   * provided that the above copyright notice appear in all copies and
      33   * that both that copyright notice and this permission notice appear
      34   * in supporting documentation.  Hewlett-Packard Company makes no
      35   * representations about the suitability of this software for any
      36   * purpose.  It is provided "as is" without express or implied warranty.
      37   *
      38   *
      39   * Copyright (c) 1996,1997
      40   * Silicon Graphics Computer Systems, Inc.
      41   *
      42   * Permission to use, copy, modify, distribute and sell this software
      43   * and its documentation for any purpose is hereby granted without fee,
      44   * provided that the above copyright notice appear in all copies and
      45   * that both that copyright notice and this permission notice appear
      46   * in supporting documentation.  Silicon Graphics makes no
      47   * representations about the suitability of this software for any
      48   * purpose.  It is provided "as is" without express or implied warranty.
      49   */
      50  
      51  /** @file bits/stl_uninitialized.h
      52   *  This is an internal header file, included by other library headers.
      53   *  Do not attempt to use it directly. @headername{memory}
      54   */
      55  
      56  #ifndef _STL_UNINITIALIZED_H
      57  #define _STL_UNINITIALIZED_H 1
      58  
      59  #if __cplusplus >= 201103L
      60  #include <type_traits>
      61  #endif
      62  
      63  #include <bits/stl_algobase.h>    // copy
      64  #include <ext/alloc_traits.h>     // __alloc_traits
      65  
      66  #if __cplusplus >= 201703L
      67  #include <bits/stl_pair.h>
      68  #endif
      69  
      70  namespace std _GLIBCXX_VISIBILITY(default)
      71  {
      72  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      73  
      74    /** @addtogroup memory
      75     *  @{
      76     */
      77  
      78    /// @cond undocumented
      79  
      80  #if __cplusplus >= 201103L
      81    template<typename _ValueType, typename _Tp>
      82      constexpr bool
      83      __check_constructible()
      84      {
      85        // Trivial types can have deleted constructors, but std::copy etc.
      86        // only use assignment (or memmove) not construction, so we need an
      87        // explicit check that construction from _Tp is actually valid,
      88        // otherwise some ill-formed uses of std::uninitialized_xxx would
      89        // compile without errors. This gives a nice clear error message.
      90        static_assert(is_constructible<_ValueType, _Tp>::value,
      91  	  "result type must be constructible from input type");
      92  
      93        return true;
      94      }
      95  
      96  // If the type is trivial we don't need to construct it, just assign to it.
      97  // But trivial types can still have deleted or inaccessible assignment,
      98  // so don't try to use std::copy or std::fill etc. if we can't assign.
      99  # define _GLIBCXX_USE_ASSIGN_FOR_INIT(T, U) \
     100      __is_trivial(T) && __is_assignable(T&, U) \
     101      && std::__check_constructible<T, U>()
     102  #else
     103  // No need to check if is_constructible<T, U> for C++98. Trivial types have
     104  // no user-declared constructors, so if the assignment is valid, construction
     105  // should be too.
     106  # define _GLIBCXX_USE_ASSIGN_FOR_INIT(T, U) \
     107      __is_trivial(T) && __is_assignable(T&, U)
     108  #endif
     109  
     110    template<typename _InputIterator, typename _ForwardIterator>
     111      _GLIBCXX20_CONSTEXPR
     112      _ForwardIterator
     113      __do_uninit_copy(_InputIterator __first, _InputIterator __last,
     114  		     _ForwardIterator __result)
     115      {
     116        _ForwardIterator __cur = __result;
     117        __try
     118  	{
     119  	  for (; __first != __last; ++__first, (void)++__cur)
     120  	    std::_Construct(std::__addressof(*__cur), *__first);
     121  	  return __cur;
     122  	}
     123        __catch(...)
     124  	{
     125  	  std::_Destroy(__result, __cur);
     126  	  __throw_exception_again;
     127  	}
     128      }
     129  
     130    template<bool _TrivialValueTypes>
     131      struct __uninitialized_copy
     132      {
     133        template<typename _InputIterator, typename _ForwardIterator>
     134          static _ForwardIterator
     135          __uninit_copy(_InputIterator __first, _InputIterator __last,
     136  		      _ForwardIterator __result)
     137  	{ return std::__do_uninit_copy(__first, __last, __result); }
     138      };
     139  
     140    template<>
     141      struct __uninitialized_copy<true>
     142      {
     143        template<typename _InputIterator, typename _ForwardIterator>
     144          static _ForwardIterator
     145          __uninit_copy(_InputIterator __first, _InputIterator __last,
     146  		      _ForwardIterator __result)
     147          { return std::copy(__first, __last, __result); }
     148      };
     149  
     150    /// @endcond
     151  
     152    /**
     153     *  @brief Copies the range [first,last) into result.
     154     *  @param  __first  An input iterator.
     155     *  @param  __last   An input iterator.
     156     *  @param  __result An output iterator.
     157     *  @return   __result + (__first - __last)
     158     *
     159     *  Like copy(), but does not require an initialized output range.
     160    */
     161    template<typename _InputIterator, typename _ForwardIterator>
     162      inline _ForwardIterator
     163      uninitialized_copy(_InputIterator __first, _InputIterator __last,
     164  		       _ForwardIterator __result)
     165      {
     166        typedef typename iterator_traits<_InputIterator>::value_type
     167  	_ValueType1;
     168        typedef typename iterator_traits<_ForwardIterator>::value_type
     169  	_ValueType2;
     170  
     171        // _ValueType1 must be trivially-copyable to use memmove, so don't
     172        // bother optimizing to std::copy if it isn't.
     173        // XXX Unnecessary because std::copy would check it anyway?
     174        const bool __can_memmove = __is_trivial(_ValueType1);
     175  
     176  #if __cplusplus < 201103L
     177        typedef typename iterator_traits<_InputIterator>::reference _From;
     178  #else
     179        using _From = decltype(*__first);
     180  #endif
     181        const bool __assignable
     182  	= _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType2, _From);
     183  
     184        return std::__uninitialized_copy<__can_memmove && __assignable>::
     185  	__uninit_copy(__first, __last, __result);
     186      }
     187  
     188    /// @cond undocumented
     189  
     190    template<typename _ForwardIterator, typename _Tp>
     191      _GLIBCXX20_CONSTEXPR void
     192      __do_uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
     193  		     const _Tp& __x)
     194      {
     195        _ForwardIterator __cur = __first;
     196        __try
     197  	{
     198  	  for (; __cur != __last; ++__cur)
     199  	    std::_Construct(std::__addressof(*__cur), __x);
     200  	}
     201        __catch(...)
     202  	{
     203  	  std::_Destroy(__first, __cur);
     204  	  __throw_exception_again;
     205  	}
     206      }
     207  
     208    template<bool _TrivialValueType>
     209      struct __uninitialized_fill
     210      {
     211        template<typename _ForwardIterator, typename _Tp>
     212          static void
     213          __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
     214  		      const _Tp& __x)
     215  	{ std::__do_uninit_fill(__first, __last, __x); }
     216      };
     217  
     218    template<>
     219      struct __uninitialized_fill<true>
     220      {
     221        template<typename _ForwardIterator, typename _Tp>
     222          static void
     223          __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
     224  		      const _Tp& __x)
     225          { std::fill(__first, __last, __x); }
     226      };
     227  
     228    /// @endcond
     229  
     230    /**
     231     *  @brief Copies the value x into the range [first,last).
     232     *  @param  __first  An input iterator.
     233     *  @param  __last   An input iterator.
     234     *  @param  __x      The source value.
     235     *  @return   Nothing.
     236     *
     237     *  Like fill(), but does not require an initialized output range.
     238    */
     239    template<typename _ForwardIterator, typename _Tp>
     240      inline void
     241      uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
     242  		       const _Tp& __x)
     243      {
     244        typedef typename iterator_traits<_ForwardIterator>::value_type
     245  	_ValueType;
     246  
     247        // Trivial types do not need a constructor to begin their lifetime,
     248        // so try to use std::fill to benefit from its memset optimization.
     249        const bool __can_fill
     250  	= _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType, const _Tp&);
     251  
     252        std::__uninitialized_fill<__can_fill>::
     253  	__uninit_fill(__first, __last, __x);
     254      }
     255  
     256    /// @cond undocumented
     257  
     258    template<typename _ForwardIterator, typename _Size, typename _Tp>
     259      _GLIBCXX20_CONSTEXPR
     260      _ForwardIterator
     261      __do_uninit_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
     262      {
     263        _ForwardIterator __cur = __first;
     264        __try
     265  	{
     266  	  for (; __n > 0; --__n, (void) ++__cur)
     267  	    std::_Construct(std::__addressof(*__cur), __x);
     268  	  return __cur;
     269  	}
     270        __catch(...)
     271  	{
     272  	  std::_Destroy(__first, __cur);
     273  	  __throw_exception_again;
     274  	}
     275      }
     276  
     277    template<bool _TrivialValueType>
     278      struct __uninitialized_fill_n
     279      {
     280        template<typename _ForwardIterator, typename _Size, typename _Tp>
     281  	static _ForwardIterator
     282          __uninit_fill_n(_ForwardIterator __first, _Size __n,
     283  			const _Tp& __x)
     284  	{ return std::__do_uninit_fill_n(__first, __n, __x); }
     285      };
     286  
     287    template<>
     288      struct __uninitialized_fill_n<true>
     289      {
     290        template<typename _ForwardIterator, typename _Size, typename _Tp>
     291  	static _ForwardIterator
     292          __uninit_fill_n(_ForwardIterator __first, _Size __n,
     293  			const _Tp& __x)
     294          { return std::fill_n(__first, __n, __x); }
     295      };
     296  
     297    /// @endcond
     298  
     299     // _GLIBCXX_RESOLVE_LIB_DEFECTS
     300     // DR 1339. uninitialized_fill_n should return the end of its range
     301    /**
     302     *  @brief Copies the value x into the range [first,first+n).
     303     *  @param  __first  An input iterator.
     304     *  @param  __n      The number of copies to make.
     305     *  @param  __x      The source value.
     306     *  @return   Nothing.
     307     *
     308     *  Like fill_n(), but does not require an initialized output range.
     309    */
     310    template<typename _ForwardIterator, typename _Size, typename _Tp>
     311      inline _ForwardIterator
     312      uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
     313      {
     314        typedef typename iterator_traits<_ForwardIterator>::value_type
     315  	_ValueType;
     316  
     317        // Trivial types do not need a constructor to begin their lifetime,
     318        // so try to use std::fill_n to benefit from its optimizations.
     319        const bool __can_fill
     320  	= _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType, const _Tp&)
     321        // For arbitrary class types and floating point types we can't assume
     322        // that __n > 0 and std::__size_to_integer(__n) > 0 are equivalent,
     323        // so only use std::fill_n when _Size is already an integral type.
     324  	&& __is_integer<_Size>::__value;
     325  
     326        return __uninitialized_fill_n<__can_fill>::
     327  	__uninit_fill_n(__first, __n, __x);
     328      }
     329  
     330  #undef _GLIBCXX_USE_ASSIGN_FOR_INIT
     331  
     332    /// @cond undocumented
     333  
     334    // Extensions: versions of uninitialized_copy, uninitialized_fill,
     335    //  and uninitialized_fill_n that take an allocator parameter.
     336    //  We dispatch back to the standard versions when we're given the
     337    //  default allocator.  For nondefault allocators we do not use
     338    //  any of the POD optimizations.
     339  
     340    template<typename _InputIterator, typename _ForwardIterator,
     341  	   typename _Allocator>
     342      _GLIBCXX20_CONSTEXPR
     343      _ForwardIterator
     344      __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
     345  			   _ForwardIterator __result, _Allocator& __alloc)
     346      {
     347        _ForwardIterator __cur = __result;
     348        __try
     349  	{
     350  	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
     351  	  for (; __first != __last; ++__first, (void)++__cur)
     352  	    __traits::construct(__alloc, std::__addressof(*__cur), *__first);
     353  	  return __cur;
     354  	}
     355        __catch(...)
     356  	{
     357  	  std::_Destroy(__result, __cur, __alloc);
     358  	  __throw_exception_again;
     359  	}
     360      }
     361  
     362  #if _GLIBCXX_HOSTED
     363    template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
     364      _GLIBCXX20_CONSTEXPR
     365      inline _ForwardIterator
     366      __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
     367  			   _ForwardIterator __result, allocator<_Tp>&)
     368      {
     369  #ifdef __cpp_lib_is_constant_evaluated
     370        if (std::is_constant_evaluated())
     371  	return std::__do_uninit_copy(__first, __last, __result);
     372  #endif
     373        return std::uninitialized_copy(__first, __last, __result);
     374      }
     375  #endif
     376  
     377    template<typename _InputIterator, typename _ForwardIterator,
     378  	   typename _Allocator>
     379      _GLIBCXX20_CONSTEXPR
     380      inline _ForwardIterator
     381      __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
     382  			   _ForwardIterator __result, _Allocator& __alloc)
     383      {
     384        return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
     385  					 _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
     386  					 __result, __alloc);
     387      }
     388  
     389    template<typename _InputIterator, typename _ForwardIterator,
     390  	   typename _Allocator>
     391      _GLIBCXX20_CONSTEXPR
     392      inline _ForwardIterator
     393      __uninitialized_move_if_noexcept_a(_InputIterator __first,
     394  				       _InputIterator __last,
     395  				       _ForwardIterator __result,
     396  				       _Allocator& __alloc)
     397      {
     398        return std::__uninitialized_copy_a
     399  	(_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
     400  	 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
     401      }
     402  
     403    template<typename _ForwardIterator, typename _Tp, typename _Allocator>
     404      _GLIBCXX20_CONSTEXPR
     405      void
     406      __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
     407  			   const _Tp& __x, _Allocator& __alloc)
     408      {
     409        _ForwardIterator __cur = __first;
     410        __try
     411  	{
     412  	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
     413  	  for (; __cur != __last; ++__cur)
     414  	    __traits::construct(__alloc, std::__addressof(*__cur), __x);
     415  	}
     416        __catch(...)
     417  	{
     418  	  std::_Destroy(__first, __cur, __alloc);
     419  	  __throw_exception_again;
     420  	}
     421      }
     422  
     423  #if _GLIBCXX_HOSTED
     424    template<typename _ForwardIterator, typename _Tp, typename _Tp2>
     425      _GLIBCXX20_CONSTEXPR
     426      inline void
     427      __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
     428  			   const _Tp& __x, allocator<_Tp2>&)
     429      {
     430  #ifdef __cpp_lib_is_constant_evaluated
     431        if (std::is_constant_evaluated())
     432  	return std::__do_uninit_fill(__first, __last, __x);
     433  #endif
     434        std::uninitialized_fill(__first, __last, __x);
     435      }
     436  #endif
     437  
     438    template<typename _ForwardIterator, typename _Size, typename _Tp,
     439  	   typename _Allocator>
     440       _GLIBCXX20_CONSTEXPR
     441      _ForwardIterator
     442      __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
     443  			     const _Tp& __x, _Allocator& __alloc)
     444      {
     445        _ForwardIterator __cur = __first;
     446        __try
     447  	{
     448  	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
     449  	  for (; __n > 0; --__n, (void) ++__cur)
     450  	    __traits::construct(__alloc, std::__addressof(*__cur), __x);
     451  	  return __cur;
     452  	}
     453        __catch(...)
     454  	{
     455  	  std::_Destroy(__first, __cur, __alloc);
     456  	  __throw_exception_again;
     457  	}
     458      }
     459  
     460  #if _GLIBCXX_HOSTED
     461    template<typename _ForwardIterator, typename _Size, typename _Tp,
     462  	   typename _Tp2>
     463      _GLIBCXX20_CONSTEXPR
     464      inline _ForwardIterator
     465      __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
     466  			     const _Tp& __x, allocator<_Tp2>&)
     467      {
     468  #ifdef __cpp_lib_is_constant_evaluated
     469        if (std::is_constant_evaluated())
     470  	return std::__do_uninit_fill_n(__first, __n, __x);
     471  #endif
     472        return std::uninitialized_fill_n(__first, __n, __x);
     473      }
     474  #endif
     475  
     476    // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
     477    // __uninitialized_fill_move, __uninitialized_move_fill.
     478    // All of these algorithms take a user-supplied allocator, which is used
     479    // for construction and destruction.
     480  
     481    // __uninitialized_copy_move
     482    // Copies [first1, last1) into [result, result + (last1 - first1)), and
     483    //  move [first2, last2) into
     484    //  [result, result + (last1 - first1) + (last2 - first2)).
     485    template<typename _InputIterator1, typename _InputIterator2,
     486  	   typename _ForwardIterator, typename _Allocator>
     487      inline _ForwardIterator
     488      __uninitialized_copy_move(_InputIterator1 __first1,
     489  			      _InputIterator1 __last1,
     490  			      _InputIterator2 __first2,
     491  			      _InputIterator2 __last2,
     492  			      _ForwardIterator __result,
     493  			      _Allocator& __alloc)
     494      {
     495        _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
     496  							   __result,
     497  							   __alloc);
     498        __try
     499  	{
     500  	  return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
     501  	}
     502        __catch(...)
     503  	{
     504  	  std::_Destroy(__result, __mid, __alloc);
     505  	  __throw_exception_again;
     506  	}
     507      }
     508  
     509    // __uninitialized_move_copy
     510    // Moves [first1, last1) into [result, result + (last1 - first1)), and
     511    //  copies [first2, last2) into
     512    //  [result, result + (last1 - first1) + (last2 - first2)).
     513    template<typename _InputIterator1, typename _InputIterator2,
     514  	   typename _ForwardIterator, typename _Allocator>
     515      inline _ForwardIterator
     516      __uninitialized_move_copy(_InputIterator1 __first1,
     517  			      _InputIterator1 __last1,
     518  			      _InputIterator2 __first2,
     519  			      _InputIterator2 __last2,
     520  			      _ForwardIterator __result,
     521  			      _Allocator& __alloc)
     522      {
     523        _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
     524  							   __result,
     525  							   __alloc);
     526        __try
     527  	{
     528  	  return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
     529  	}
     530        __catch(...)
     531  	{
     532  	  std::_Destroy(__result, __mid, __alloc);
     533  	  __throw_exception_again;
     534  	}
     535      }
     536  
     537    // __uninitialized_fill_move
     538    // Fills [result, mid) with x, and moves [first, last) into
     539    //  [mid, mid + (last - first)).
     540    template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
     541  	   typename _Allocator>
     542      inline _ForwardIterator
     543      __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
     544  			      const _Tp& __x, _InputIterator __first,
     545  			      _InputIterator __last, _Allocator& __alloc)
     546      {
     547        std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
     548        __try
     549  	{
     550  	  return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
     551  	}
     552        __catch(...)
     553  	{
     554  	  std::_Destroy(__result, __mid, __alloc);
     555  	  __throw_exception_again;
     556  	}
     557      }
     558  
     559    // __uninitialized_move_fill
     560    // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
     561    //  fills [first2 + (last1 - first1), last2) with x.
     562    template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
     563  	   typename _Allocator>
     564      inline void
     565      __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
     566  			      _ForwardIterator __first2,
     567  			      _ForwardIterator __last2, const _Tp& __x,
     568  			      _Allocator& __alloc)
     569      {
     570        _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
     571  							    __first2,
     572  							    __alloc);
     573        __try
     574  	{
     575  	  std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
     576  	}
     577        __catch(...)
     578  	{
     579  	  std::_Destroy(__first2, __mid2, __alloc);
     580  	  __throw_exception_again;
     581  	}
     582      }
     583  
     584    /// @endcond
     585  
     586  #if __cplusplus >= 201103L
     587    /// @cond undocumented
     588  
     589    // Extensions: __uninitialized_default, __uninitialized_default_n,
     590    // __uninitialized_default_a, __uninitialized_default_n_a.
     591  
     592    template<bool _TrivialValueType>
     593      struct __uninitialized_default_1
     594      {
     595        template<typename _ForwardIterator>
     596          static void
     597          __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
     598          {
     599  	  _ForwardIterator __cur = __first;
     600  	  __try
     601  	    {
     602  	      for (; __cur != __last; ++__cur)
     603  		std::_Construct(std::__addressof(*__cur));
     604  	    }
     605  	  __catch(...)
     606  	    {
     607  	      std::_Destroy(__first, __cur);
     608  	      __throw_exception_again;
     609  	    }
     610  	}
     611      };
     612  
     613    template<>
     614      struct __uninitialized_default_1<true>
     615      {
     616        template<typename _ForwardIterator>
     617          static void
     618          __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
     619          {
     620  	  if (__first == __last)
     621  	    return;
     622  
     623  	  typename iterator_traits<_ForwardIterator>::value_type* __val
     624  	    = std::__addressof(*__first);
     625  	  std::_Construct(__val);
     626  	  if (++__first != __last)
     627  	    std::fill(__first, __last, *__val);
     628  	}
     629      };
     630  
     631    template<bool _TrivialValueType>
     632      struct __uninitialized_default_n_1
     633      {
     634        template<typename _ForwardIterator, typename _Size>
     635  	_GLIBCXX20_CONSTEXPR
     636          static _ForwardIterator
     637          __uninit_default_n(_ForwardIterator __first, _Size __n)
     638          {
     639  	  _ForwardIterator __cur = __first;
     640  	  __try
     641  	    {
     642  	      for (; __n > 0; --__n, (void) ++__cur)
     643  		std::_Construct(std::__addressof(*__cur));
     644  	      return __cur;
     645  	    }
     646  	  __catch(...)
     647  	    {
     648  	      std::_Destroy(__first, __cur);
     649  	      __throw_exception_again;
     650  	    }
     651  	}
     652      };
     653  
     654    template<>
     655      struct __uninitialized_default_n_1<true>
     656      {
     657        template<typename _ForwardIterator, typename _Size>
     658  	_GLIBCXX20_CONSTEXPR
     659          static _ForwardIterator
     660          __uninit_default_n(_ForwardIterator __first, _Size __n)
     661          {
     662  	  if (__n > 0)
     663  	    {
     664  	      typename iterator_traits<_ForwardIterator>::value_type* __val
     665  		= std::__addressof(*__first);
     666  	      std::_Construct(__val);
     667  	      ++__first;
     668  	      __first = std::fill_n(__first, __n - 1, *__val);
     669  	    }
     670  	  return __first;
     671  	}
     672      };
     673  
     674    // __uninitialized_default
     675    // Fills [first, last) with value-initialized value_types.
     676    template<typename _ForwardIterator>
     677      inline void
     678      __uninitialized_default(_ForwardIterator __first,
     679  			    _ForwardIterator __last)
     680      {
     681        typedef typename iterator_traits<_ForwardIterator>::value_type
     682  	_ValueType;
     683        // trivial types can have deleted assignment
     684        const bool __assignable = is_copy_assignable<_ValueType>::value;
     685  
     686        std::__uninitialized_default_1<__is_trivial(_ValueType)
     687  				     && __assignable>::
     688  	__uninit_default(__first, __last);
     689      }
     690  
     691    // __uninitialized_default_n
     692    // Fills [first, first + n) with value-initialized value_types.
     693    template<typename _ForwardIterator, typename _Size>
     694      _GLIBCXX20_CONSTEXPR
     695      inline _ForwardIterator
     696      __uninitialized_default_n(_ForwardIterator __first, _Size __n)
     697      {
     698  #ifdef __cpp_lib_is_constant_evaluated
     699        if (std::is_constant_evaluated())
     700  	return __uninitialized_default_n_1<false>::
     701  		 __uninit_default_n(__first, __n);
     702  #endif
     703  
     704        typedef typename iterator_traits<_ForwardIterator>::value_type
     705  	_ValueType;
     706        // See uninitialized_fill_n for the conditions for using std::fill_n.
     707        constexpr bool __can_fill
     708  	= __and_<is_integral<_Size>, is_copy_assignable<_ValueType>>::value;
     709  
     710        return __uninitialized_default_n_1<__is_trivial(_ValueType)
     711  					 && __can_fill>::
     712  	__uninit_default_n(__first, __n);
     713      }
     714  
     715  
     716    // __uninitialized_default_a
     717    // Fills [first, last) with value_types constructed by the allocator
     718    // alloc, with no arguments passed to the construct call.
     719    template<typename _ForwardIterator, typename _Allocator>
     720      void
     721      __uninitialized_default_a(_ForwardIterator __first,
     722  			      _ForwardIterator __last,
     723  			      _Allocator& __alloc)
     724      {
     725        _ForwardIterator __cur = __first;
     726        __try
     727  	{
     728  	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
     729  	  for (; __cur != __last; ++__cur)
     730  	    __traits::construct(__alloc, std::__addressof(*__cur));
     731  	}
     732        __catch(...)
     733  	{
     734  	  std::_Destroy(__first, __cur, __alloc);
     735  	  __throw_exception_again;
     736  	}
     737      }
     738  
     739  #if _GLIBCXX_HOSTED
     740    template<typename _ForwardIterator, typename _Tp>
     741      inline void
     742      __uninitialized_default_a(_ForwardIterator __first,
     743  			      _ForwardIterator __last,
     744  			      allocator<_Tp>&)
     745      { std::__uninitialized_default(__first, __last); }
     746  #endif
     747  
     748    // __uninitialized_default_n_a
     749    // Fills [first, first + n) with value_types constructed by the allocator
     750    // alloc, with no arguments passed to the construct call.
     751    template<typename _ForwardIterator, typename _Size, typename _Allocator>
     752      _GLIBCXX20_CONSTEXPR _ForwardIterator
     753      __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
     754  				_Allocator& __alloc)
     755      {
     756        _ForwardIterator __cur = __first;
     757        __try
     758  	{
     759  	  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
     760  	  for (; __n > 0; --__n, (void) ++__cur)
     761  	    __traits::construct(__alloc, std::__addressof(*__cur));
     762  	  return __cur;
     763  	}
     764        __catch(...)
     765  	{
     766  	  std::_Destroy(__first, __cur, __alloc);
     767  	  __throw_exception_again;
     768  	}
     769      }
     770  
     771  #if _GLIBCXX_HOSTED
     772    // __uninitialized_default_n_a specialization for std::allocator,
     773    // which ignores the allocator and value-initializes the elements.
     774    template<typename _ForwardIterator, typename _Size, typename _Tp>
     775      _GLIBCXX20_CONSTEXPR
     776      inline _ForwardIterator
     777      __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
     778  				allocator<_Tp>&)
     779      { return std::__uninitialized_default_n(__first, __n); }
     780  #endif
     781  
     782    template<bool _TrivialValueType>
     783      struct __uninitialized_default_novalue_1
     784      {
     785        template<typename _ForwardIterator>
     786  	static void
     787  	__uninit_default_novalue(_ForwardIterator __first,
     788  				 _ForwardIterator __last)
     789  	{
     790  	  _ForwardIterator __cur = __first;
     791  	  __try
     792  	    {
     793  	      for (; __cur != __last; ++__cur)
     794  		std::_Construct_novalue(std::__addressof(*__cur));
     795  	    }
     796  	  __catch(...)
     797  	    {
     798  	      std::_Destroy(__first, __cur);
     799  	      __throw_exception_again;
     800  	    }
     801  	}
     802      };
     803  
     804    template<>
     805      struct __uninitialized_default_novalue_1<true>
     806      {
     807        template<typename _ForwardIterator>
     808          static void
     809          __uninit_default_novalue(_ForwardIterator __first,
     810  				 _ForwardIterator __last)
     811  	{
     812  	}
     813      };
     814  
     815    template<bool _TrivialValueType>
     816      struct __uninitialized_default_novalue_n_1
     817      {
     818        template<typename _ForwardIterator, typename _Size>
     819  	static _ForwardIterator
     820  	__uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
     821  	{
     822  	  _ForwardIterator __cur = __first;
     823  	  __try
     824  	    {
     825  	      for (; __n > 0; --__n, (void) ++__cur)
     826  		std::_Construct_novalue(std::__addressof(*__cur));
     827  	      return __cur;
     828  	    }
     829  	  __catch(...)
     830  	    {
     831  	      std::_Destroy(__first, __cur);
     832  	      __throw_exception_again;
     833  	    }
     834  	}
     835      };
     836  
     837    template<>
     838      struct __uninitialized_default_novalue_n_1<true>
     839      {
     840        template<typename _ForwardIterator, typename _Size>
     841  	static _ForwardIterator
     842  	__uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
     843  	{ return std::next(__first, __n); }
     844      };
     845  
     846    // __uninitialized_default_novalue
     847    // Fills [first, last) with default-initialized value_types.
     848    template<typename _ForwardIterator>
     849      inline void
     850      __uninitialized_default_novalue(_ForwardIterator __first,
     851  				    _ForwardIterator __last)
     852      {
     853        typedef typename iterator_traits<_ForwardIterator>::value_type
     854  	_ValueType;
     855  
     856        std::__uninitialized_default_novalue_1<
     857  	is_trivially_default_constructible<_ValueType>::value>::
     858  	__uninit_default_novalue(__first, __last);
     859      }
     860  
     861    // __uninitialized_default_novalue_n
     862    // Fills [first, first + n) with default-initialized value_types.
     863    template<typename _ForwardIterator, typename _Size>
     864      inline _ForwardIterator
     865      __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
     866      {
     867        typedef typename iterator_traits<_ForwardIterator>::value_type
     868  	_ValueType;
     869  
     870        return __uninitialized_default_novalue_n_1<
     871  	is_trivially_default_constructible<_ValueType>::value>::
     872  	__uninit_default_novalue_n(__first, __n);
     873      }
     874  
     875    template<typename _InputIterator, typename _Size,
     876  	   typename _ForwardIterator>
     877      _ForwardIterator
     878      __uninitialized_copy_n(_InputIterator __first, _Size __n,
     879  			   _ForwardIterator __result, input_iterator_tag)
     880      {
     881        _ForwardIterator __cur = __result;
     882        __try
     883  	{
     884  	  for (; __n > 0; --__n, (void) ++__first, ++__cur)
     885  	    std::_Construct(std::__addressof(*__cur), *__first);
     886  	  return __cur;
     887  	}
     888        __catch(...)
     889  	{
     890  	  std::_Destroy(__result, __cur);
     891  	  __throw_exception_again;
     892  	}
     893      }
     894  
     895    template<typename _RandomAccessIterator, typename _Size,
     896  	   typename _ForwardIterator>
     897      inline _ForwardIterator
     898      __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
     899  			   _ForwardIterator __result,
     900  			   random_access_iterator_tag)
     901      { return std::uninitialized_copy(__first, __first + __n, __result); }
     902  
     903    template<typename _InputIterator, typename _Size,
     904  	   typename _ForwardIterator>
     905      pair<_InputIterator, _ForwardIterator>
     906      __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
     907  			   _ForwardIterator __result, input_iterator_tag)
     908      {
     909        _ForwardIterator __cur = __result;
     910        __try
     911  	{
     912  	  for (; __n > 0; --__n, (void) ++__first, ++__cur)
     913  	    std::_Construct(std::__addressof(*__cur), *__first);
     914  	  return {__first, __cur};
     915  	}
     916        __catch(...)
     917  	{
     918  	  std::_Destroy(__result, __cur);
     919  	  __throw_exception_again;
     920  	}
     921      }
     922  
     923    template<typename _RandomAccessIterator, typename _Size,
     924  	   typename _ForwardIterator>
     925      inline pair<_RandomAccessIterator, _ForwardIterator>
     926      __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
     927  			   _ForwardIterator __result,
     928  			   random_access_iterator_tag)
     929      {
     930        auto __second_res = uninitialized_copy(__first, __first + __n, __result);
     931        auto __first_res = std::next(__first, __n);
     932        return {__first_res, __second_res};
     933      }
     934  
     935    /// @endcond
     936  
     937    /**
     938     *  @brief Copies the range [first,first+n) into result.
     939     *  @param  __first  An input iterator.
     940     *  @param  __n      The number of elements to copy.
     941     *  @param  __result An output iterator.
     942     *  @return  __result + __n
     943     *  @since C++11
     944     *
     945     *  Like copy_n(), but does not require an initialized output range.
     946    */
     947    template<typename _InputIterator, typename _Size, typename _ForwardIterator>
     948      inline _ForwardIterator
     949      uninitialized_copy_n(_InputIterator __first, _Size __n,
     950  			 _ForwardIterator __result)
     951      { return std::__uninitialized_copy_n(__first, __n, __result,
     952  					 std::__iterator_category(__first)); }
     953  
     954    /// @cond undocumented
     955    template<typename _InputIterator, typename _Size, typename _ForwardIterator>
     956      inline pair<_InputIterator, _ForwardIterator>
     957      __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
     958  			      _ForwardIterator __result)
     959      {
     960        return
     961  	std::__uninitialized_copy_n_pair(__first, __n, __result,
     962  					 std::__iterator_category(__first));
     963      }
     964    /// @endcond
     965  #endif
     966  
     967  #if __cplusplus >= 201703L
     968  # define __cpp_lib_raw_memory_algorithms 201606L
     969  
     970    /**
     971     *  @brief Default-initializes objects in the range [first,last).
     972     *  @param  __first  A forward iterator.
     973     *  @param  __last   A forward iterator.
     974     *  @since C++17
     975    */
     976    template <typename _ForwardIterator>
     977      inline void
     978      uninitialized_default_construct(_ForwardIterator __first,
     979  				    _ForwardIterator __last)
     980      {
     981        __uninitialized_default_novalue(__first, __last);
     982      }
     983  
     984    /**
     985     *  @brief Default-initializes objects in the range [first,first+count).
     986     *  @param  __first  A forward iterator.
     987     *  @param  __count  The number of objects to construct.
     988     *  @return   __first + __count
     989     *  @since C++17
     990    */
     991    template <typename _ForwardIterator, typename _Size>
     992      inline _ForwardIterator
     993      uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
     994      {
     995        return __uninitialized_default_novalue_n(__first, __count);
     996      }
     997  
     998    /**
     999     *  @brief Value-initializes objects in the range [first,last).
    1000     *  @param  __first  A forward iterator.
    1001     *  @param  __last   A forward iterator.
    1002     *  @since C++17
    1003    */
    1004    template <typename _ForwardIterator>
    1005      inline void
    1006      uninitialized_value_construct(_ForwardIterator __first,
    1007  				  _ForwardIterator __last)
    1008      {
    1009        return __uninitialized_default(__first, __last);
    1010      }
    1011  
    1012    /**
    1013     *  @brief Value-initializes objects in the range [first,first+count).
    1014     *  @param  __first  A forward iterator.
    1015     *  @param  __count  The number of objects to construct.
    1016     *  @return   __result + __count
    1017     *  @since C++17
    1018    */
    1019    template <typename _ForwardIterator, typename _Size>
    1020      inline _ForwardIterator
    1021      uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
    1022      {
    1023        return __uninitialized_default_n(__first, __count);
    1024      }
    1025  
    1026    /**
    1027     *  @brief Move-construct from the range [first,last) into result.
    1028     *  @param  __first  An input iterator.
    1029     *  @param  __last   An input iterator.
    1030     *  @param  __result An output iterator.
    1031     *  @return   __result + (__first - __last)
    1032     *  @since C++17
    1033    */
    1034    template <typename _InputIterator, typename _ForwardIterator>
    1035      inline _ForwardIterator
    1036      uninitialized_move(_InputIterator __first, _InputIterator __last,
    1037  		       _ForwardIterator __result)
    1038      {
    1039        return std::uninitialized_copy
    1040  	(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
    1041  	 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
    1042      }
    1043  
    1044    /**
    1045     *  @brief Move-construct from the range [first,first+count) into result.
    1046     *  @param  __first  An input iterator.
    1047     *  @param  __count  The number of objects to initialize.
    1048     *  @param  __result An output iterator.
    1049     *  @return  __result + __count
    1050     *  @since C++17
    1051    */
    1052    template <typename _InputIterator, typename _Size, typename _ForwardIterator>
    1053      inline pair<_InputIterator, _ForwardIterator>
    1054      uninitialized_move_n(_InputIterator __first, _Size __count,
    1055  			 _ForwardIterator __result)
    1056      {
    1057        auto __res = std::__uninitialized_copy_n_pair
    1058  	(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
    1059  	 __count, __result);
    1060        return {__res.first.base(), __res.second};
    1061      }
    1062  #endif // C++17
    1063  
    1064  #if __cplusplus >= 201103L
    1065    /// @cond undocumented
    1066  
    1067    template<typename _Tp, typename _Up, typename _Allocator>
    1068      _GLIBCXX20_CONSTEXPR
    1069      inline void
    1070      __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig,
    1071  			_Allocator& __alloc)
    1072      noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc,
    1073  			 __dest, std::move(*__orig)))
    1074  	     && noexcept(std::allocator_traits<_Allocator>::destroy(
    1075  			    __alloc, std::__addressof(*__orig))))
    1076      {
    1077        typedef std::allocator_traits<_Allocator> __traits;
    1078        __traits::construct(__alloc, __dest, std::move(*__orig));
    1079        __traits::destroy(__alloc, std::__addressof(*__orig));
    1080      }
    1081  
    1082    // This class may be specialized for specific types.
    1083    // Also known as is_trivially_relocatable.
    1084    template<typename _Tp, typename = void>
    1085      struct __is_bitwise_relocatable
    1086      : is_trivial<_Tp> { };
    1087  
    1088    template <typename _InputIterator, typename _ForwardIterator,
    1089  	    typename _Allocator>
    1090      _GLIBCXX20_CONSTEXPR
    1091      inline _ForwardIterator
    1092      __relocate_a_1(_InputIterator __first, _InputIterator __last,
    1093  		   _ForwardIterator __result, _Allocator& __alloc)
    1094      noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result),
    1095  					       std::addressof(*__first),
    1096  					       __alloc)))
    1097      {
    1098        typedef typename iterator_traits<_InputIterator>::value_type
    1099  	_ValueType;
    1100        typedef typename iterator_traits<_ForwardIterator>::value_type
    1101  	_ValueType2;
    1102        static_assert(std::is_same<_ValueType, _ValueType2>::value,
    1103  	  "relocation is only possible for values of the same type");
    1104        _ForwardIterator __cur = __result;
    1105        for (; __first != __last; ++__first, (void)++__cur)
    1106  	std::__relocate_object_a(std::__addressof(*__cur),
    1107  				 std::__addressof(*__first), __alloc);
    1108        return __cur;
    1109      }
    1110  
    1111  #if _GLIBCXX_HOSTED
    1112    template <typename _Tp, typename _Up>
    1113      _GLIBCXX20_CONSTEXPR
    1114      inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*>
    1115      __relocate_a_1(_Tp* __first, _Tp* __last,
    1116  		   _Tp* __result,
    1117  		   [[__maybe_unused__]] allocator<_Up>& __alloc) noexcept
    1118      {
    1119        ptrdiff_t __count = __last - __first;
    1120        if (__count > 0)
    1121  	{
    1122  #ifdef __cpp_lib_is_constant_evaluated
    1123  	  if (std::is_constant_evaluated())
    1124  	    {
    1125  	      // Can't use memmove. Wrap the pointer so that __relocate_a_1
    1126  	      // resolves to the non-trivial overload above.
    1127  	      __gnu_cxx::__normal_iterator<_Tp*, void> __out(__result);
    1128  	      __out = std::__relocate_a_1(__first, __last, __out, __alloc);
    1129  	      return __out.base();
    1130  	    }
    1131  #endif
    1132  	  __builtin_memmove(__result, __first, __count * sizeof(_Tp));
    1133  	}
    1134        return __result + __count;
    1135      }
    1136  #endif
    1137  
    1138    template <typename _InputIterator, typename _ForwardIterator,
    1139  	    typename _Allocator>
    1140      _GLIBCXX20_CONSTEXPR
    1141      inline _ForwardIterator
    1142      __relocate_a(_InputIterator __first, _InputIterator __last,
    1143  		 _ForwardIterator __result, _Allocator& __alloc)
    1144      noexcept(noexcept(__relocate_a_1(std::__niter_base(__first),
    1145  				     std::__niter_base(__last),
    1146  				     std::__niter_base(__result), __alloc)))
    1147      {
    1148        return std::__relocate_a_1(std::__niter_base(__first),
    1149  				 std::__niter_base(__last),
    1150  				 std::__niter_base(__result), __alloc);
    1151      }
    1152  
    1153    /// @endcond
    1154  #endif // C++11
    1155  
    1156    /// @} group memory
    1157  
    1158  _GLIBCXX_END_NAMESPACE_VERSION
    1159  } // namespace
    1160  
    1161  #endif /* _STL_UNINITIALIZED_H */