// Raw memory manipulators -*- C++ -*-

// Copyright (C) 2020-2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file bits/ranges_uninitialized.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{memory}
 */

#ifndef _RANGES_UNINITIALIZED_H
#define _RANGES_UNINITIALIZED_H 1

#if __cplusplus > 201703L
#if __cpp_lib_concepts

#include <bits/ranges_algobase.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges
{
  namespace __detail
  {
    template<typename _Tp>
      constexpr void*
      __voidify(_Tp& __obj) noexcept
      {
	return const_cast<void*>
		 (static_cast<const volatile void*>(std::__addressof(__obj)));
      }

    template<typename _Iter>
      concept __nothrow_input_iterator
	= (input_iterator<_Iter>
	   && is_lvalue_reference_v<iter_reference_t<_Iter>>
	   && same_as<remove_cvref_t<iter_reference_t<_Iter>>,
		      iter_value_t<_Iter>>);

    template<typename _Sent, typename _Iter>
      concept __nothrow_sentinel = sentinel_for<_Sent, _Iter>;

    template<typename _Range>
      concept __nothrow_input_range
	= (range<_Range>
	   && __nothrow_input_iterator<iterator_t<_Range>>
	   && __nothrow_sentinel<sentinel_t<_Range>, iterator_t<_Range>>);

    template<typename _Iter>
      concept __nothrow_forward_iterator
	= (__nothrow_input_iterator<_Iter>
	   && forward_iterator<_Iter>
	   && __nothrow_sentinel<_Iter, _Iter>);

    template<typename _Range>
      concept __nothrow_forward_range
	= (__nothrow_input_range<_Range>
	   && __nothrow_forward_iterator<iterator_t<_Range>>);
  } // namespace __detail

  struct __destroy_fn
  {
    template<__detail::__nothrow_input_iterator _Iter,
	     __detail::__nothrow_sentinel<_Iter> _Sent>
      requires destructible<iter_value_t<_Iter>>
      constexpr _Iter
      operator()(_Iter __first, _Sent __last) const noexcept;

    template<__detail::__nothrow_input_range _Range>
      requires destructible<range_value_t<_Range>>
      constexpr borrowed_iterator_t<_Range>
      operator()(_Range&& __r) const noexcept;
  };

  inline constexpr __destroy_fn destroy{};

  namespace __detail
  {
    template<typename _Iter>
      requires destructible<iter_value_t<_Iter>>
      struct _DestroyGuard
      {
      private:
	_Iter _M_first;
	const _Iter* _M_cur;

      public:
	constexpr
	explicit
	_DestroyGuard(const _Iter& __iter)
	  : _M_first(__iter), _M_cur(std::__addressof(__iter))
	{ }

	constexpr
	void
	release() noexcept
	{ _M_cur = nullptr; }

	constexpr
	~_DestroyGuard()
	{
	  if (_M_cur != nullptr)
	    ranges::destroy(std::move(_M_first), *_M_cur);
	}
      };

    template<typename _Iter>
      requires destructible<iter_value_t<_Iter>>
	&& is_trivially_destructible_v<iter_value_t<_Iter>>
      struct _DestroyGuard<_Iter>
      {
	constexpr
	explicit
	_DestroyGuard(const _Iter&)
	{ }

	constexpr
	void
	release() noexcept
	{ }
      };
  } // namespace __detail

  struct __uninitialized_default_construct_fn
  {
    template<__detail::__nothrow_forward_iterator _Iter,
	     __detail::__nothrow_sentinel<_Iter> _Sent>
      requires default_initializable<iter_value_t<_Iter>>
      _GLIBCXX26_CONSTEXPR
      _Iter
      operator()(_Iter __first, _Sent __last) const
      {
	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
	if constexpr (is_trivially_default_constructible_v<_ValueType>)
	  return ranges::next(__first, __last);
	else
	  {
	    auto __guard = __detail::_DestroyGuard(__first);
	    for (; __first != __last; ++__first)
	      ::new (__detail::__voidify(*__first)) _ValueType;
	    __guard.release();
	    return __first;
	  }
      }

    template<__detail::__nothrow_forward_range _Range>
      requires default_initializable<range_value_t<_Range>>
      _GLIBCXX26_CONSTEXPR
      borrowed_iterator_t<_Range>
      operator()(_Range&& __r) const
      {
	return (*this)(ranges::begin(__r), ranges::end(__r));
      }
  };

  inline constexpr __uninitialized_default_construct_fn
    uninitialized_default_construct{};

  struct __uninitialized_default_construct_n_fn
  {
    template<__detail::__nothrow_forward_iterator _Iter>
      requires default_initializable<iter_value_t<_Iter>>
      _GLIBCXX26_CONSTEXPR
      _Iter
      operator()(_Iter __first, iter_difference_t<_Iter> __n) const
      {
	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
	if constexpr (is_trivially_default_constructible_v<_ValueType>)
	  return ranges::next(__first, __n);
	else
	  {
	    auto __guard = __detail::_DestroyGuard(__first);
	    for (; __n > 0; ++__first, (void) --__n)
	      ::new (__detail::__voidify(*__first)) _ValueType;
	    __guard.release();
	    return __first;
	  }
      }
  };

  inline constexpr __uninitialized_default_construct_n_fn
    uninitialized_default_construct_n;

  struct __uninitialized_value_construct_fn
  {
    template<__detail::__nothrow_forward_iterator _Iter,
	     __detail::__nothrow_sentinel<_Iter> _Sent>
      requires default_initializable<iter_value_t<_Iter>>
      _GLIBCXX26_CONSTEXPR
      _Iter
      operator()(_Iter __first, _Sent __last) const
      {
	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
	if constexpr (is_trivially_default_constructible_v<_ValueType>
		      && is_trivially_copy_assignable_v<_ValueType>)
	  return ranges::fill(__first, __last, _ValueType());
	else
	  {
	    auto __guard = __detail::_DestroyGuard(__first);
	    for (; __first != __last; ++__first)
	      ::new (__detail::__voidify(*__first)) _ValueType();
	    __guard.release();
	    return __first;
	  }
      }

    template<__detail::__nothrow_forward_range _Range>
      requires default_initializable<range_value_t<_Range>>
      _GLIBCXX26_CONSTEXPR
      borrowed_iterator_t<_Range>
      operator()(_Range&& __r) const
      {
	return (*this)(ranges::begin(__r), ranges::end(__r));
      }
  };

  inline constexpr __uninitialized_value_construct_fn
    uninitialized_value_construct{};

  struct __uninitialized_value_construct_n_fn
  {
    template<__detail::__nothrow_forward_iterator _Iter>
      requires default_initializable<iter_value_t<_Iter>>
      _GLIBCXX26_CONSTEXPR
      _Iter
      operator()(_Iter __first, iter_difference_t<_Iter> __n) const
      {
	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
	if constexpr (is_trivially_default_constructible_v<_ValueType>
		      && is_trivially_copy_assignable_v<_ValueType>)
	  return ranges::fill_n(__first, __n, _ValueType());
	else
	  {
	    auto __guard = __detail::_DestroyGuard(__first);
	    for (; __n > 0; ++__first, (void) --__n)
	      ::new (__detail::__voidify(*__first)) _ValueType();
	    __guard.release();
	    return __first;
	  }
      }
  };

  inline constexpr __uninitialized_value_construct_n_fn
    uninitialized_value_construct_n;

  template<typename _Iter, typename _Out>
    using uninitialized_copy_result = in_out_result<_Iter, _Out>;

  struct __uninitialized_copy_fn
  {
    template<input_iterator _Iter, sentinel_for<_Iter> _ISent,
	     __detail::__nothrow_forward_iterator _Out,
	     __detail::__nothrow_sentinel<_Out> _OSent>
      requires constructible_from<iter_value_t<_Out>, iter_reference_t<_Iter>>
      _GLIBCXX26_CONSTEXPR
      uninitialized_copy_result<_Iter, _Out>
      operator()(_Iter __ifirst, _ISent __ilast,
		 _Out __ofirst, _OSent __olast) const
      {
	using _OutType = remove_reference_t<iter_reference_t<_Out>>;
	if constexpr (sized_sentinel_for<_ISent, _Iter>
		      && sized_sentinel_for<_OSent, _Out>
		      && is_trivially_constructible_v<_OutType, iter_reference_t<_Iter>>
		      && is_trivially_default_constructible_v<_OutType>
		      && is_trivially_assignable_v<_OutType&,
						 iter_reference_t<_Iter>>)
	  {
	    auto __d = __ilast - __ifirst;
	    if (auto __d2 = __olast - __ofirst; __d2 < __d)
	      __d = static_cast<iter_difference_t<_Iter>>(__d2);
	    return ranges::copy_n(std::move(__ifirst), __d, __ofirst);
	  }
	else
	  {
	    auto __guard = __detail::_DestroyGuard(__ofirst);
	    for (; __ifirst != __ilast && __ofirst != __olast;
		 ++__ofirst, (void)++__ifirst)
	      ::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst);
	    __guard.release();
	    return {std::move(__ifirst), __ofirst};
	  }
      }

    template<input_range _IRange, __detail::__nothrow_forward_range _ORange>
      requires constructible_from<range_value_t<_ORange>,
				  range_reference_t<_IRange>>
      _GLIBCXX26_CONSTEXPR
      uninitialized_copy_result<borrowed_iterator_t<_IRange>,
				borrowed_iterator_t<_ORange>>
      operator()(_IRange&& __inr, _ORange&& __outr) const
      {
	return (*this)(ranges::begin(__inr), ranges::end(__inr),
		       ranges::begin(__outr), ranges::end(__outr));
      }
  };

  inline constexpr __uninitialized_copy_fn uninitialized_copy{};

  template<typename _Iter, typename _Out>
    using uninitialized_copy_n_result = in_out_result<_Iter, _Out>;

  struct __uninitialized_copy_n_fn
  {
    template<input_iterator _Iter, __detail::__nothrow_forward_iterator _Out,
	     __detail::__nothrow_sentinel<_Out> _Sent>
      requires constructible_from<iter_value_t<_Out>, iter_reference_t<_Iter>>
      _GLIBCXX26_CONSTEXPR
      uninitialized_copy_n_result<_Iter, _Out>
      operator()(_Iter __ifirst, iter_difference_t<_Iter> __n,
		 _Out __ofirst, _Sent __olast) const
      {
	using _OutType = remove_reference_t<iter_reference_t<_Out>>;
	if constexpr (sized_sentinel_for<_Sent, _Out>
		      && is_trivially_constructible_v<_OutType, iter_reference_t<_Iter>>
		      && is_trivially_default_constructible_v<_OutType>
		      && is_trivially_assignable_v<_OutType&,
						 iter_reference_t<_Iter>>)
	  {
	    if (auto __d = __olast - __ofirst; __d < __n)
	      __n = static_cast<iter_difference_t<_Iter>>(__d);
	    return ranges::copy_n(std::move(__ifirst), __n, __ofirst);
	  }
	else
	  {
	    auto __guard = __detail::_DestroyGuard(__ofirst);
	    for (; __n > 0 && __ofirst != __olast;
		 ++__ofirst, (void)++__ifirst, (void)--__n)
	      ::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst);
	    __guard.release();
	    return {std::move(__ifirst), __ofirst};
	  }
      }
  };

  inline constexpr __uninitialized_copy_n_fn uninitialized_copy_n{};

  template<typename _Iter, typename _Out>
    using uninitialized_move_result = in_out_result<_Iter, _Out>;

  struct __uninitialized_move_fn
  {
    template<input_iterator _Iter, sentinel_for<_Iter> _ISent,
	     __detail::__nothrow_forward_iterator _Out,
	     __detail::__nothrow_sentinel<_Out> _OSent>
      requires constructible_from<iter_value_t<_Out>,
				  iter_rvalue_reference_t<_Iter>>
      _GLIBCXX26_CONSTEXPR
      uninitialized_move_result<_Iter, _Out>
      operator()(_Iter __ifirst, _ISent __ilast,
		 _Out __ofirst, _OSent __olast) const
      {
	using _OutType = remove_reference_t<iter_reference_t<_Out>>;
	if constexpr (sized_sentinel_for<_ISent, _Iter>
		      && sized_sentinel_for<_OSent, _Out>
		      && is_trivially_constructible_v<_OutType, iter_rvalue_reference_t<_Iter>>
		      && is_trivially_default_constructible_v<_OutType>
		      && is_trivially_assignable_v<_OutType&,
						 iter_rvalue_reference_t<_Iter>>)
	  {
	    auto __d = __ilast - __ifirst;
	    if (auto __d2 = __olast - __ofirst; __d2 < __d)
	      __d = static_cast<iter_difference_t<_Iter>>(__d2);
	    auto [__in, __out]
	      = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
			       __d, __ofirst);
	    return {std::move(__in).base(), __out};
	  }
	else
	  {
	    auto __guard = __detail::_DestroyGuard(__ofirst);
	    for (; __ifirst != __ilast && __ofirst != __olast;
		 ++__ofirst, (void)++__ifirst)
	      ::new (__detail::__voidify(*__ofirst))
		    _OutType(ranges::iter_move(__ifirst));
	    __guard.release();
	    return {std::move(__ifirst), __ofirst};
	  }
      }

    template<input_range _IRange, __detail::__nothrow_forward_range _ORange>
      requires constructible_from<range_value_t<_ORange>,
	       range_rvalue_reference_t<_IRange>>
      _GLIBCXX26_CONSTEXPR
      uninitialized_move_result<borrowed_iterator_t<_IRange>,
				borrowed_iterator_t<_ORange>>
      operator()(_IRange&& __inr, _ORange&& __outr) const
      {
	return (*this)(ranges::begin(__inr), ranges::end(__inr),
		       ranges::begin(__outr), ranges::end(__outr));
      }
  };

  inline constexpr __uninitialized_move_fn uninitialized_move{};

  template<typename _Iter, typename _Out>
    using uninitialized_move_n_result = in_out_result<_Iter, _Out>;

  struct __uninitialized_move_n_fn
  {
    template<input_iterator _Iter, __detail::__nothrow_forward_iterator _Out,
      __detail::__nothrow_sentinel<_Out> _Sent>
	requires constructible_from<iter_value_t<_Out>,
				    iter_rvalue_reference_t<_Iter>>
      _GLIBCXX26_CONSTEXPR
      uninitialized_move_n_result<_Iter, _Out>
      operator()(_Iter __ifirst, iter_difference_t<_Iter> __n,
		 _Out __ofirst, _Sent __olast) const
      {
	using _OutType = remove_reference_t<iter_reference_t<_Out>>;
	if constexpr (sized_sentinel_for<_Sent, _Out>
		      && is_trivially_constructible_v<_OutType, iter_rvalue_reference_t<_Iter>>
		      && is_trivially_default_constructible_v<_OutType>
		      && is_trivially_assignable_v<_OutType&,
						 iter_rvalue_reference_t<_Iter>>)
	  {
	    if (auto __d = __olast - __ofirst; __d < __n)
	      __n = static_cast<iter_difference_t<_Iter>>(__d);
	    auto [__in, __out]
	      = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
			       __n, __ofirst);
	    return {std::move(__in).base(), __out};
	  }
	else
	  {
	    auto __guard = __detail::_DestroyGuard(__ofirst);
	    for (; __n > 0 && __ofirst != __olast;
		 ++__ofirst, (void)++__ifirst, (void)--__n)
	      ::new (__detail::__voidify(*__ofirst))
		    _OutType(ranges::iter_move(__ifirst));
	    __guard.release();
	    return {std::move(__ifirst), __ofirst};
	  }
      }
  };

  inline constexpr __uninitialized_move_n_fn uninitialized_move_n{};

  struct __uninitialized_fill_fn
  {
    template<__detail::__nothrow_forward_iterator _Iter,
	     __detail::__nothrow_sentinel<_Iter> _Sent, typename _Tp>
      requires constructible_from<iter_value_t<_Iter>, const _Tp&>
      _GLIBCXX26_CONSTEXPR
      _Iter
      operator()(_Iter __first, _Sent __last, const _Tp& __x) const
      {
	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
	if constexpr (is_trivially_constructible_v<_ValueType, const _Tp&>
		      && is_trivially_assignable_v<_ValueType&, const _Tp&>)
	  return ranges::fill(__first, __last, __x);
	else
	  {
	    auto __guard = __detail::_DestroyGuard(__first);
	    for (; __first != __last; ++__first)
	      ::new (__detail::__voidify(*__first)) _ValueType(__x);
	    __guard.release();
	    return __first;
	  }
      }

    template<__detail::__nothrow_forward_range _Range, typename _Tp>
      requires constructible_from<range_value_t<_Range>, const _Tp&>
      _GLIBCXX26_CONSTEXPR
      borrowed_iterator_t<_Range>
      operator()(_Range&& __r, const _Tp& __x) const
      {
	return (*this)(ranges::begin(__r), ranges::end(__r), __x);
      }
  };

  inline constexpr __uninitialized_fill_fn uninitialized_fill{};

  struct __uninitialized_fill_n_fn
  {
    template<__detail::__nothrow_forward_iterator _Iter, typename _Tp>
      requires constructible_from<iter_value_t<_Iter>, const _Tp&>
      _GLIBCXX26_CONSTEXPR
      _Iter
      operator()(_Iter __first, iter_difference_t<_Iter> __n,
		 const _Tp& __x) const
      {
	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
	if constexpr (is_trivially_constructible_v<_ValueType, const _Tp&>
		      && is_trivially_assignable_v<_ValueType&, const _Tp&>)
	  return ranges::fill_n(__first, __n, __x);
	else
	  {
	    auto __guard = __detail::_DestroyGuard(__first);
	    for (; __n > 0; ++__first, (void)--__n)
	      ::new (__detail::__voidify(*__first)) _ValueType(__x);
	    __guard.release();
	    return __first;
	  }
      }
  };

  inline constexpr __uninitialized_fill_n_fn uninitialized_fill_n{};

  struct __construct_at_fn
  {
    template<typename _Tp, typename... _Args>
      requires requires {
	::new (std::declval<void*>()) _Tp(std::declval<_Args>()...);
      }
      constexpr _Tp*
      operator()(_Tp* __location, _Args&&... __args) const
      noexcept(noexcept(std::construct_at(__location,
					  std::forward<_Args>(__args)...)))
      {
	return std::construct_at(__location,
				 std::forward<_Args>(__args)...);
      }
  };

  inline constexpr __construct_at_fn construct_at{};

  struct __destroy_at_fn
  {
    template<destructible _Tp>
      constexpr void
      operator()(_Tp* __location) const noexcept
      {
	if constexpr (is_array_v<_Tp>)
	  ranges::destroy(ranges::begin(*__location), ranges::end(*__location));
	else
	  __location->~_Tp();
      }
  };

  inline constexpr __destroy_at_fn destroy_at{};

  template<__detail::__nothrow_input_iterator _Iter,
	   __detail::__nothrow_sentinel<_Iter> _Sent>
    requires destructible<iter_value_t<_Iter>>
    constexpr _Iter
    __destroy_fn::operator()(_Iter __first, _Sent __last) const noexcept
    {
      if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>)
	return ranges::next(std::move(__first), __last);
      else
	{
	  for (; __first != __last; ++__first)
	    ranges::destroy_at(std::__addressof(*__first));
	  return __first;
	}
    }

  template<__detail::__nothrow_input_range _Range>
    requires destructible<range_value_t<_Range>>
    constexpr borrowed_iterator_t<_Range>
    __destroy_fn::operator()(_Range&& __r) const noexcept
    {
      return (*this)(ranges::begin(__r), ranges::end(__r));
    }

  struct __destroy_n_fn
  {
    template<__detail::__nothrow_input_iterator _Iter>
      requires destructible<iter_value_t<_Iter>>
      constexpr _Iter
      operator()(_Iter __first, iter_difference_t<_Iter> __n) const noexcept
      {
	if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>)
	  return ranges::next(std::move(__first), __n);
	else
	  {
	    for (; __n > 0; ++__first, (void)--__n)
	      ranges::destroy_at(std::__addressof(*__first));
	    return __first;
	  }
      }
  };

  inline constexpr __destroy_n_fn destroy_n{};
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // concepts
#endif // C++20
#endif // _RANGES_UNINITIALIZED_H
