(root)/
gcc-13.2.0/
libstdc++-v3/
include/
bits/
ranges_uninitialized.h
       1  // Raw memory manipulators -*- C++ -*-
       2  
       3  // Copyright (C) 2020-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  /** @file bits/ranges_uninitialized.h
      26   *  This is an internal header file, included by other library headers.
      27   *  Do not attempt to use it directly. @headername{memory}
      28   */
      29  
      30  #ifndef _RANGES_UNINITIALIZED_H
      31  #define _RANGES_UNINITIALIZED_H 1
      32  
      33  #if __cplusplus > 201703L
      34  #if __cpp_lib_concepts
      35  
      36  #include <bits/ranges_algobase.h>
      37  
      38  namespace std _GLIBCXX_VISIBILITY(default)
      39  {
      40  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      41  namespace ranges
      42  {
      43    namespace __detail
      44    {
      45      template<typename _Tp>
      46        constexpr void*
      47        __voidify(_Tp& __obj) noexcept
      48        {
      49  	return const_cast<void*>
      50  		 (static_cast<const volatile void*>(std::__addressof(__obj)));
      51        }
      52  
      53      template<typename _Iter>
      54        concept __nothrow_input_iterator
      55  	= (input_iterator<_Iter>
      56  	   && is_lvalue_reference_v<iter_reference_t<_Iter>>
      57  	   && same_as<remove_cvref_t<iter_reference_t<_Iter>>,
      58  		      iter_value_t<_Iter>>);
      59  
      60      template<typename _Sent, typename _Iter>
      61        concept __nothrow_sentinel = sentinel_for<_Sent, _Iter>;
      62  
      63      template<typename _Range>
      64        concept __nothrow_input_range
      65  	= (range<_Range>
      66  	   && __nothrow_input_iterator<iterator_t<_Range>>
      67  	   && __nothrow_sentinel<sentinel_t<_Range>, iterator_t<_Range>>);
      68  
      69      template<typename _Iter>
      70        concept __nothrow_forward_iterator
      71  	= (__nothrow_input_iterator<_Iter>
      72  	   && forward_iterator<_Iter>
      73  	   && __nothrow_sentinel<_Iter, _Iter>);
      74  
      75      template<typename _Range>
      76        concept __nothrow_forward_range
      77  	= (__nothrow_input_range<_Range>
      78  	   && __nothrow_forward_iterator<iterator_t<_Range>>);
      79    } // namespace __detail
      80  
      81    struct __destroy_fn
      82    {
      83      template<__detail::__nothrow_input_iterator _Iter,
      84  	     __detail::__nothrow_sentinel<_Iter> _Sent>
      85        requires destructible<iter_value_t<_Iter>>
      86        constexpr _Iter
      87        operator()(_Iter __first, _Sent __last) const noexcept;
      88  
      89      template<__detail::__nothrow_input_range _Range>
      90        requires destructible<range_value_t<_Range>>
      91        constexpr borrowed_iterator_t<_Range>
      92        operator()(_Range&& __r) const noexcept;
      93    };
      94  
      95    inline constexpr __destroy_fn destroy{};
      96  
      97    namespace __detail
      98    {
      99      template<typename _Iter>
     100        requires destructible<iter_value_t<_Iter>>
     101        struct _DestroyGuard
     102        {
     103        private:
     104  	_Iter _M_first;
     105  	const _Iter* _M_cur;
     106  
     107        public:
     108  	explicit
     109  	_DestroyGuard(const _Iter& __iter)
     110  	  : _M_first(__iter), _M_cur(std::__addressof(__iter))
     111  	{ }
     112  
     113  	void
     114  	release() noexcept
     115  	{ _M_cur = nullptr; }
     116  
     117  	~_DestroyGuard()
     118  	{
     119  	  if (_M_cur != nullptr)
     120  	    ranges::destroy(std::move(_M_first), *_M_cur);
     121  	}
     122        };
     123  
     124      template<typename _Iter>
     125        requires destructible<iter_value_t<_Iter>>
     126  	&& is_trivially_destructible_v<iter_value_t<_Iter>>
     127        struct _DestroyGuard<_Iter>
     128        {
     129  	explicit
     130  	_DestroyGuard(const _Iter&)
     131  	{ }
     132  
     133  	void
     134  	release() noexcept
     135  	{ }
     136        };
     137    } // namespace __detail
     138  
     139    struct __uninitialized_default_construct_fn
     140    {
     141      template<__detail::__nothrow_forward_iterator _Iter,
     142  	     __detail::__nothrow_sentinel<_Iter> _Sent>
     143        requires default_initializable<iter_value_t<_Iter>>
     144        _Iter
     145        operator()(_Iter __first, _Sent __last) const
     146        {
     147  	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
     148  	if constexpr (is_trivially_default_constructible_v<_ValueType>)
     149  	  return ranges::next(__first, __last);
     150  	else
     151  	  {
     152  	    auto __guard = __detail::_DestroyGuard(__first);
     153  	    for (; __first != __last; ++__first)
     154  	      ::new (__detail::__voidify(*__first)) _ValueType;
     155  	    __guard.release();
     156  	    return __first;
     157  	  }
     158        }
     159  
     160      template<__detail::__nothrow_forward_range _Range>
     161        requires default_initializable<range_value_t<_Range>>
     162        borrowed_iterator_t<_Range>
     163        operator()(_Range&& __r) const
     164        {
     165  	return (*this)(ranges::begin(__r), ranges::end(__r));
     166        }
     167    };
     168  
     169    inline constexpr __uninitialized_default_construct_fn
     170      uninitialized_default_construct{};
     171  
     172    struct __uninitialized_default_construct_n_fn
     173    {
     174      template<__detail::__nothrow_forward_iterator _Iter>
     175        requires default_initializable<iter_value_t<_Iter>>
     176        _Iter
     177        operator()(_Iter __first, iter_difference_t<_Iter> __n) const
     178        {
     179  	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
     180  	if constexpr (is_trivially_default_constructible_v<_ValueType>)
     181  	  return ranges::next(__first, __n);
     182  	else
     183  	  {
     184  	    auto __guard = __detail::_DestroyGuard(__first);
     185  	    for (; __n > 0; ++__first, (void) --__n)
     186  	      ::new (__detail::__voidify(*__first)) _ValueType;
     187  	    __guard.release();
     188  	    return __first;
     189  	  }
     190        }
     191    };
     192  
     193    inline constexpr __uninitialized_default_construct_n_fn
     194      uninitialized_default_construct_n;
     195  
     196    struct __uninitialized_value_construct_fn
     197    {
     198      template<__detail::__nothrow_forward_iterator _Iter,
     199  	     __detail::__nothrow_sentinel<_Iter> _Sent>
     200        requires default_initializable<iter_value_t<_Iter>>
     201        _Iter
     202        operator()(_Iter __first, _Sent __last) const
     203        {
     204  	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
     205  	if constexpr (is_trivial_v<_ValueType>
     206  		      && is_copy_assignable_v<_ValueType>)
     207  	  return ranges::fill(__first, __last, _ValueType());
     208  	else
     209  	  {
     210  	    auto __guard = __detail::_DestroyGuard(__first);
     211  	    for (; __first != __last; ++__first)
     212  	      ::new (__detail::__voidify(*__first)) _ValueType();
     213  	    __guard.release();
     214  	    return __first;
     215  	  }
     216        }
     217  
     218      template<__detail::__nothrow_forward_range _Range>
     219        requires default_initializable<range_value_t<_Range>>
     220        borrowed_iterator_t<_Range>
     221        operator()(_Range&& __r) const
     222        {
     223  	return (*this)(ranges::begin(__r), ranges::end(__r));
     224        }
     225    };
     226  
     227    inline constexpr __uninitialized_value_construct_fn
     228      uninitialized_value_construct{};
     229  
     230    struct __uninitialized_value_construct_n_fn
     231    {
     232      template<__detail::__nothrow_forward_iterator _Iter>
     233        requires default_initializable<iter_value_t<_Iter>>
     234        _Iter
     235        operator()(_Iter __first, iter_difference_t<_Iter> __n) const
     236        {
     237  	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
     238  	if constexpr (is_trivial_v<_ValueType>
     239  		      && is_copy_assignable_v<_ValueType>)
     240  	  return ranges::fill_n(__first, __n, _ValueType());
     241  	else
     242  	  {
     243  	    auto __guard = __detail::_DestroyGuard(__first);
     244  	    for (; __n > 0; ++__first, (void) --__n)
     245  	      ::new (__detail::__voidify(*__first)) _ValueType();
     246  	    __guard.release();
     247  	    return __first;
     248  	  }
     249        }
     250    };
     251  
     252    inline constexpr __uninitialized_value_construct_n_fn
     253      uninitialized_value_construct_n;
     254  
     255    template<typename _Iter, typename _Out>
     256      using uninitialized_copy_result = in_out_result<_Iter, _Out>;
     257  
     258    struct __uninitialized_copy_fn
     259    {
     260      template<input_iterator _Iter, sentinel_for<_Iter> _ISent,
     261  	     __detail::__nothrow_forward_iterator _Out,
     262  	     __detail::__nothrow_sentinel<_Out> _OSent>
     263        requires constructible_from<iter_value_t<_Out>, iter_reference_t<_Iter>>
     264        uninitialized_copy_result<_Iter, _Out>
     265        operator()(_Iter __ifirst, _ISent __ilast,
     266  		 _Out __ofirst, _OSent __olast) const
     267        {
     268  	using _OutType = remove_reference_t<iter_reference_t<_Out>>;
     269  	if constexpr (sized_sentinel_for<_ISent, _Iter>
     270  		      && sized_sentinel_for<_OSent, _Out>
     271  		      && is_trivial_v<_OutType>
     272  		      && is_nothrow_assignable_v<_OutType&,
     273  						 iter_reference_t<_Iter>>)
     274  	  {
     275  	    auto __d1 = __ilast - __ifirst;
     276  	    auto __d2 = __olast - __ofirst;
     277  	    return ranges::copy_n(std::move(__ifirst), std::min(__d1, __d2),
     278  				  __ofirst);
     279  	  }
     280  	else
     281  	  {
     282  	    auto __guard = __detail::_DestroyGuard(__ofirst);
     283  	    for (; __ifirst != __ilast && __ofirst != __olast;
     284  		 ++__ofirst, (void)++__ifirst)
     285  	      ::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst);
     286  	    __guard.release();
     287  	    return {std::move(__ifirst), __ofirst};
     288  	  }
     289        }
     290  
     291      template<input_range _IRange, __detail::__nothrow_forward_range _ORange>
     292        requires constructible_from<range_value_t<_ORange>,
     293  				  range_reference_t<_IRange>>
     294        uninitialized_copy_result<borrowed_iterator_t<_IRange>,
     295  				borrowed_iterator_t<_ORange>>
     296        operator()(_IRange&& __inr, _ORange&& __outr) const
     297        {
     298  	return (*this)(ranges::begin(__inr), ranges::end(__inr),
     299  		       ranges::begin(__outr), ranges::end(__outr));
     300        }
     301    };
     302  
     303    inline constexpr __uninitialized_copy_fn uninitialized_copy{};
     304  
     305    template<typename _Iter, typename _Out>
     306      using uninitialized_copy_n_result = in_out_result<_Iter, _Out>;
     307  
     308    struct __uninitialized_copy_n_fn
     309    {
     310      template<input_iterator _Iter, __detail::__nothrow_forward_iterator _Out,
     311  	     __detail::__nothrow_sentinel<_Out> _Sent>
     312        requires constructible_from<iter_value_t<_Out>, iter_reference_t<_Iter>>
     313        uninitialized_copy_n_result<_Iter, _Out>
     314        operator()(_Iter __ifirst, iter_difference_t<_Iter> __n,
     315  		 _Out __ofirst, _Sent __olast) const
     316        {
     317  	using _OutType = remove_reference_t<iter_reference_t<_Out>>;
     318  	if constexpr (sized_sentinel_for<_Sent, _Out>
     319  		      && is_trivial_v<_OutType>
     320  		      && is_nothrow_assignable_v<_OutType&,
     321  						 iter_reference_t<_Iter>>)
     322  	  {
     323  	    auto __d = __olast - __ofirst;
     324  	    return ranges::copy_n(std::move(__ifirst), std::min(__n, __d),
     325  				  __ofirst);
     326  	  }
     327  	else
     328  	  {
     329  	    auto __guard = __detail::_DestroyGuard(__ofirst);
     330  	    for (; __n > 0 && __ofirst != __olast;
     331  		 ++__ofirst, (void)++__ifirst, (void)--__n)
     332  	      ::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst);
     333  	    __guard.release();
     334  	    return {std::move(__ifirst), __ofirst};
     335  	  }
     336        }
     337    };
     338  
     339    inline constexpr __uninitialized_copy_n_fn uninitialized_copy_n{};
     340  
     341    template<typename _Iter, typename _Out>
     342      using uninitialized_move_result = in_out_result<_Iter, _Out>;
     343  
     344    struct __uninitialized_move_fn
     345    {
     346      template<input_iterator _Iter, sentinel_for<_Iter> _ISent,
     347  	     __detail::__nothrow_forward_iterator _Out,
     348  	     __detail::__nothrow_sentinel<_Out> _OSent>
     349        requires constructible_from<iter_value_t<_Out>,
     350  				  iter_rvalue_reference_t<_Iter>>
     351        uninitialized_move_result<_Iter, _Out>
     352        operator()(_Iter __ifirst, _ISent __ilast,
     353  		 _Out __ofirst, _OSent __olast) const
     354        {
     355  	using _OutType = remove_reference_t<iter_reference_t<_Out>>;
     356  	if constexpr (sized_sentinel_for<_ISent, _Iter>
     357  		      && sized_sentinel_for<_OSent, _Out>
     358  		      && is_trivial_v<_OutType>
     359  		      && is_nothrow_assignable_v<_OutType&,
     360  						 iter_rvalue_reference_t<_Iter>>)
     361  	  {
     362  	    auto __d1 = __ilast - __ifirst;
     363  	    auto __d2 = __olast - __ofirst;
     364  	    auto [__in, __out]
     365  	      = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
     366  			       std::min(__d1, __d2), __ofirst);
     367  	    return {std::move(__in).base(), __out};
     368  	  }
     369  	else
     370  	  {
     371  	    auto __guard = __detail::_DestroyGuard(__ofirst);
     372  	    for (; __ifirst != __ilast && __ofirst != __olast;
     373  		 ++__ofirst, (void)++__ifirst)
     374  	      ::new (__detail::__voidify(*__ofirst))
     375  		    _OutType(ranges::iter_move(__ifirst));
     376  	    __guard.release();
     377  	    return {std::move(__ifirst), __ofirst};
     378  	  }
     379        }
     380  
     381      template<input_range _IRange, __detail::__nothrow_forward_range _ORange>
     382        requires constructible_from<range_value_t<_ORange>,
     383  	       range_rvalue_reference_t<_IRange>>
     384        uninitialized_move_result<borrowed_iterator_t<_IRange>,
     385  				borrowed_iterator_t<_ORange>>
     386        operator()(_IRange&& __inr, _ORange&& __outr) const
     387        {
     388  	return (*this)(ranges::begin(__inr), ranges::end(__inr),
     389  		       ranges::begin(__outr), ranges::end(__outr));
     390        }
     391    };
     392  
     393    inline constexpr __uninitialized_move_fn uninitialized_move{};
     394  
     395    template<typename _Iter, typename _Out>
     396      using uninitialized_move_n_result = in_out_result<_Iter, _Out>;
     397  
     398    struct __uninitialized_move_n_fn
     399    {
     400      template<input_iterator _Iter, __detail::__nothrow_forward_iterator _Out,
     401        __detail::__nothrow_sentinel<_Out> _Sent>
     402  	requires constructible_from<iter_value_t<_Out>,
     403  				    iter_rvalue_reference_t<_Iter>>
     404        uninitialized_move_n_result<_Iter, _Out>
     405        operator()(_Iter __ifirst, iter_difference_t<_Iter> __n,
     406  		 _Out __ofirst, _Sent __olast) const
     407        {
     408  	using _OutType = remove_reference_t<iter_reference_t<_Out>>;
     409  	if constexpr (sized_sentinel_for<_Sent, _Out>
     410  		      && is_trivial_v<_OutType>
     411  		      && is_nothrow_assignable_v<_OutType&,
     412  						 iter_rvalue_reference_t<_Iter>>)
     413  	  {
     414  	    auto __d = __olast - __ofirst;
     415  	    auto [__in, __out]
     416  	      = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
     417  			       std::min(__n, __d), __ofirst);
     418  	    return {std::move(__in).base(), __out};
     419  	  }
     420  	else
     421  	  {
     422  	    auto __guard = __detail::_DestroyGuard(__ofirst);
     423  	    for (; __n > 0 && __ofirst != __olast;
     424  		 ++__ofirst, (void)++__ifirst, (void)--__n)
     425  	      ::new (__detail::__voidify(*__ofirst))
     426  		    _OutType(ranges::iter_move(__ifirst));
     427  	    __guard.release();
     428  	    return {std::move(__ifirst), __ofirst};
     429  	  }
     430        }
     431    };
     432  
     433    inline constexpr __uninitialized_move_n_fn uninitialized_move_n{};
     434  
     435    struct __uninitialized_fill_fn
     436    {
     437      template<__detail::__nothrow_forward_iterator _Iter,
     438  	     __detail::__nothrow_sentinel<_Iter> _Sent, typename _Tp>
     439        requires constructible_from<iter_value_t<_Iter>, const _Tp&>
     440        _Iter
     441        operator()(_Iter __first, _Sent __last, const _Tp& __x) const
     442        {
     443  	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
     444  	if constexpr (is_trivial_v<_ValueType>
     445  		      && is_nothrow_assignable_v<_ValueType&, const _Tp&>)
     446  	  return ranges::fill(__first, __last, __x);
     447  	else
     448  	  {
     449  	    auto __guard = __detail::_DestroyGuard(__first);
     450  	    for (; __first != __last; ++__first)
     451  	      ::new (__detail::__voidify(*__first)) _ValueType(__x);
     452  	    __guard.release();
     453  	    return __first;
     454  	  }
     455        }
     456  
     457      template<__detail::__nothrow_forward_range _Range, typename _Tp>
     458        requires constructible_from<range_value_t<_Range>, const _Tp&>
     459        borrowed_iterator_t<_Range>
     460        operator()(_Range&& __r, const _Tp& __x) const
     461        {
     462  	return (*this)(ranges::begin(__r), ranges::end(__r), __x);
     463        }
     464    };
     465  
     466    inline constexpr __uninitialized_fill_fn uninitialized_fill{};
     467  
     468    struct __uninitialized_fill_n_fn
     469    {
     470      template<__detail::__nothrow_forward_iterator _Iter, typename _Tp>
     471        requires constructible_from<iter_value_t<_Iter>, const _Tp&>
     472        _Iter
     473        operator()(_Iter __first, iter_difference_t<_Iter> __n,
     474  		 const _Tp& __x) const
     475        {
     476  	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
     477  	if constexpr (is_trivial_v<_ValueType>
     478  		      && is_nothrow_assignable_v<_ValueType&, const _Tp&>)
     479  	  return ranges::fill_n(__first, __n, __x);
     480  	else
     481  	  {
     482  	    auto __guard = __detail::_DestroyGuard(__first);
     483  	    for (; __n > 0; ++__first, (void)--__n)
     484  	      ::new (__detail::__voidify(*__first)) _ValueType(__x);
     485  	    __guard.release();
     486  	    return __first;
     487  	  }
     488        }
     489    };
     490  
     491    inline constexpr __uninitialized_fill_n_fn uninitialized_fill_n{};
     492  
     493    struct __construct_at_fn
     494    {
     495      template<typename _Tp, typename... _Args>
     496        requires requires {
     497  	::new (std::declval<void*>()) _Tp(std::declval<_Args>()...);
     498        }
     499        constexpr _Tp*
     500        operator()(_Tp* __location, _Args&&... __args) const
     501        noexcept(noexcept(std::construct_at(__location,
     502  					  std::forward<_Args>(__args)...)))
     503        {
     504  	return std::construct_at(__location,
     505  				 std::forward<_Args>(__args)...);
     506        }
     507    };
     508  
     509    inline constexpr __construct_at_fn construct_at{};
     510  
     511    struct __destroy_at_fn
     512    {
     513      template<destructible _Tp>
     514        constexpr void
     515        operator()(_Tp* __location) const noexcept
     516        {
     517  	if constexpr (is_array_v<_Tp>)
     518  	  ranges::destroy(ranges::begin(*__location), ranges::end(*__location));
     519  	else
     520  	  __location->~_Tp();
     521        }
     522    };
     523  
     524    inline constexpr __destroy_at_fn destroy_at{};
     525  
     526    template<__detail::__nothrow_input_iterator _Iter,
     527  	   __detail::__nothrow_sentinel<_Iter> _Sent>
     528      requires destructible<iter_value_t<_Iter>>
     529      constexpr _Iter
     530      __destroy_fn::operator()(_Iter __first, _Sent __last) const noexcept
     531      {
     532        if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>)
     533  	return ranges::next(std::move(__first), __last);
     534        else
     535  	{
     536  	  for (; __first != __last; ++__first)
     537  	    ranges::destroy_at(std::__addressof(*__first));
     538  	  return __first;
     539  	}
     540      }
     541  
     542    template<__detail::__nothrow_input_range _Range>
     543      requires destructible<range_value_t<_Range>>
     544      constexpr borrowed_iterator_t<_Range>
     545      __destroy_fn::operator()(_Range&& __r) const noexcept
     546      {
     547        return (*this)(ranges::begin(__r), ranges::end(__r));
     548      }
     549  
     550    struct __destroy_n_fn
     551    {
     552      template<__detail::__nothrow_input_iterator _Iter>
     553        requires destructible<iter_value_t<_Iter>>
     554        constexpr _Iter
     555        operator()(_Iter __first, iter_difference_t<_Iter> __n) const noexcept
     556        {
     557  	if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>)
     558  	  return ranges::next(std::move(__first), __n);
     559  	else
     560  	  {
     561  	    for (; __n > 0; ++__first, (void)--__n)
     562  	      ranges::destroy_at(std::__addressof(*__first));
     563  	    return __first;
     564  	  }
     565        }
     566    };
     567  
     568    inline constexpr __destroy_n_fn destroy_n{};
     569  }
     570  _GLIBCXX_END_NAMESPACE_VERSION
     571  } // namespace std
     572  #endif // concepts
     573  #endif // C++20
     574  #endif // _RANGES_UNINITIALIZED_H