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

// Copyright (C) 2020-2021 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:
	explicit
	_DestroyGuard(const _Iter& __iter)
	  : _M_first(__iter), _M_cur(std::__addressof(__iter))
	{ }

	void
	release() noexcept
	{ _M_cur = nullptr; }

	~_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>
      {
	explicit
	_DestroyGuard(const _Iter&)
	{ }

	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>>
      _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>>
      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>>
      _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>>
      _Iter
      operator()(_Iter __first, _Sent __last) const
      {
	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
	if constexpr (is_trivial_v<_ValueType>
		      && is_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>>
      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>>
      _Iter
      operator()(_Iter __first, iter_difference_t<_Iter> __n) const
      {
	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
	if constexpr (is_trivial_v<_ValueType>
		      && is_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>>
      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_trivial_v<_OutType>
		      && is_nothrow_assignable_v<_OutType&,
						 iter_reference_t<_Iter>>)
	  {
	    auto __d1 = __ilast - __ifirst;
	    auto __d2 = __olast - __ofirst;
	    return ranges::copy_n(std::move(__ifirst), std::min(__d1, __d2),
				  __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>>
      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>>
      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_trivial_v<_OutType>
		      && is_nothrow_assignable_v<_OutType&,
						 iter_reference_t<_Iter>>)
	  {
	    auto __d = __olast - __ofirst;
	    return ranges::copy_n(std::move(__ifirst), std::min(__n, __d),
				  __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>>
      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_trivial_v<_OutType>
		      && is_nothrow_assignable_v<_OutType&,
						 iter_rvalue_reference_t<_Iter>>)
	  {
	    auto __d1 = __ilast - __ifirst;
	    auto __d2 = __olast - __ofirst;
	    auto [__in, __out]
	      = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
			       std::min(__d1, __d2), __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>>
      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>>
      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_trivial_v<_OutType>
		      && is_nothrow_assignable_v<_OutType&,
						 iter_rvalue_reference_t<_Iter>>)
	  {
	    auto __d = __olast - __ofirst;
	    auto [__in, __out]
	      = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
			       std::min(__n, __d), __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&>
      _Iter
      operator()(_Iter __first, _Sent __last, const _Tp& __x) const
      {
	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
	if constexpr (is_trivial_v<_ValueType>
		      && is_nothrow_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&>
      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&>
      _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_trivial_v<_ValueType>
		      && is_nothrow_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
