// <experimental/scope> -*- C++ -*-

// Copyright The GNU Toolchain Authors.
//
// 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 experimental/scope
 *  This is a TS C++ Library header.
 *  @ingroup libfund-ts
 */

#ifndef _GLIBCXX_EXPERIMENTAL_SCOPE
#define _GLIBCXX_EXPERIMENTAL_SCOPE 1

#pragma GCC system_header

#include <bits/requires_hosted.h> // experimental is currently omitted

#if __cplusplus >= 202002L

#include <concepts>
#include <exception> // uncaught_exceptions
#include <bits/refwrap.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace experimental::inline fundamentals_v3
{
#define __cpp_lib_experimental_scope 201902

  template<typename _Tp, typename _Up>
    concept __not_same_as = !same_as<_Tp, _Up>;

  template<typename _Tp>
    concept __not_lvalue_ref = !is_lvalue_reference_v<_Tp>;

  template<typename _Ef>
    class [[nodiscard]] scope_exit
    {
    public:
      template<typename _Efp>
	requires __not_same_as<remove_cvref_t<_Efp>, scope_exit>
	      && constructible_from<_Ef, _Efp>
	[[nodiscard]] explicit
	scope_exit(_Efp&& __f) noexcept(is_nothrow_constructible_v<_Ef, _Efp&>)
#ifdef __cpp_exceptions
	try
#endif
	: _M_exit_function(__f)
	{ }
#ifdef __cpp_exceptions
	catch (...) { __f(); }
#endif

      template<typename _Efp>
	requires __not_same_as<remove_cvref_t<_Efp>, scope_exit>
	      && constructible_from<_Ef, _Efp>
	      && __not_lvalue_ref<_Efp>
	      && is_nothrow_constructible_v<_Ef, _Efp>
	explicit
	scope_exit(_Efp&& __f) noexcept
	: _M_exit_function(std::forward<_Efp>(__f))
	{ }

      scope_exit(scope_exit&& __rhs) noexcept
      requires is_nothrow_move_constructible_v<_Ef>
      : _M_exit_function(std::forward<_Ef>(__rhs._M_exit_function))
      { __rhs.release(); }

      scope_exit(scope_exit&& __rhs)
      noexcept(is_nothrow_copy_constructible_v<_Ef>)
      requires (!is_nothrow_move_constructible_v<_Ef>)
	    && is_copy_constructible_v<_Ef>
      : _M_exit_function(__rhs._M_exit_function)
      { __rhs.release(); }

      scope_exit(const scope_exit&) = delete;
      scope_exit& operator=(const scope_exit&) = delete;
      scope_exit& operator=(scope_exit&&) = delete;

      ~scope_exit() noexcept(noexcept(this->_M_exit_function))
      {
	if (_M_execute_on_destruction)
	  _M_exit_function();
      }

      void release() noexcept { _M_execute_on_destruction = false; }

    private:
      [[no_unique_address]] _Ef _M_exit_function;
      bool _M_execute_on_destruction = true;
    };

  template<typename _Ef>
    scope_exit(_Ef) -> scope_exit<_Ef>;

  template<typename _Ef>
    class [[nodiscard]] scope_fail
    {
    public:
      template<typename _Efp>
	requires __not_same_as<remove_cvref_t<_Efp>, scope_fail>
	      && constructible_from<_Ef, _Efp>
	explicit
	scope_fail(_Efp&& __f) noexcept(is_nothrow_constructible_v<_Ef, _Efp&>)
#ifdef __cpp_exceptions
	try
#endif
	: _M_exit_function(__f)
	{ }
#ifdef __cpp_exceptions
	catch (...) { __f(); }
#endif

      template<typename _Efp>
	requires __not_same_as<remove_cvref_t<_Efp>, scope_fail>
	      && constructible_from<_Ef, _Efp>
	      && __not_lvalue_ref<_Efp>
	      && is_nothrow_constructible_v<_Ef, _Efp>
	explicit
	scope_fail(_Efp&& __f) noexcept
	: _M_exit_function(std::forward<_Efp>(__f))
	{ }

      scope_fail(scope_fail&& __rhs) noexcept
      requires is_nothrow_move_constructible_v<_Ef>
      : _M_exit_function(std::forward<_Ef>(__rhs._M_exit_function))
      { __rhs.release(); }

      scope_fail(scope_fail&& __rhs)
      noexcept(is_nothrow_copy_constructible_v<_Ef>)
      requires (!is_nothrow_move_constructible_v<_Ef>)
	    && is_copy_constructible_v<_Ef>
      : _M_exit_function(__rhs._M_exit_function)
      { __rhs.release(); }

      scope_fail(const scope_fail&) = delete;
      scope_fail& operator=(const scope_fail&) = delete;
      scope_fail& operator=(scope_fail&&) = delete;

      ~scope_fail() noexcept(noexcept(this->_M_exit_function))
      {
	if (std::uncaught_exceptions() > _M_uncaught_init)
	  _M_exit_function();
      }

      void release() noexcept { _M_uncaught_init = __INT_MAX__; }

    private:
      [[no_unique_address]] _Ef _M_exit_function;
      int _M_uncaught_init = std::uncaught_exceptions();
    };

  template<typename _Ef>
    scope_fail(_Ef) -> scope_fail<_Ef>;

  template<typename _Ef>
    class [[nodiscard]] scope_success
    {
    public:
      template<typename _Efp>
	requires __not_same_as<remove_cvref_t<_Efp>, scope_success>
	      && constructible_from<_Ef, _Efp>
	explicit
	scope_success(_Efp&& __f) noexcept(is_nothrow_constructible_v<_Ef, _Efp&>)
	: _M_exit_function(__f)
	{ }

      template<typename _Efp>
	requires __not_same_as<remove_cvref_t<_Efp>, scope_success>
	      && constructible_from<_Ef, _Efp>
	      && __not_lvalue_ref<_Efp>
	      && is_nothrow_constructible_v<_Ef, _Efp>
	explicit
	scope_success(_Efp&& __f) noexcept
	: _M_exit_function(std::forward<_Efp>(__f))
	{ }

      scope_success(scope_success&& __rhs) noexcept
      requires is_nothrow_move_constructible_v<_Ef>
      : _M_exit_function(std::forward<_Ef>(__rhs._M_exit_function))
      { __rhs.release(); }

      scope_success(scope_success&& __rhs)
      noexcept(is_nothrow_copy_constructible_v<_Ef>)
      requires (!is_nothrow_move_constructible_v<_Ef>)
	    && is_copy_constructible_v<_Ef>
      : _M_exit_function(__rhs._M_exit_function)
      { __rhs.release(); }

      scope_success(const scope_success&) = delete;
      scope_success& operator=(const scope_success&) = delete;
      scope_success& operator=(scope_success&&) = delete;

      ~scope_success() noexcept(noexcept(this->_M_exit_function))
      {
	if (std::uncaught_exceptions() <= _M_uncaught_init)
	  _M_exit_function();
      }

      void release() noexcept { _M_uncaught_init = -__INT_MAX__; }

    private:
      [[no_unique_address]] _Ef _M_exit_function;
      int _M_uncaught_init = std::uncaught_exceptions();
    };

  template<typename _Ef>
    scope_success(_Ef) -> scope_success<_Ef>;

  template<typename _Resrc, typename _Del>
    class [[nodiscard]] unique_resource
    {
      static_assert(!is_rvalue_reference_v<_Resrc>);
      static_assert(!is_reference_v<_Del>);

      struct _Dummy { constexpr void release() { } };

      template<typename _Tp>
	struct _Wrap
	{
	  template<typename _Up>
	    requires is_constructible_v<_Tp, _Up>
	    _Wrap(_Up&&)
	    noexcept(is_nothrow_constructible_v<_Tp, _Up>);

	  template<typename _Up, typename _Del2>
	    requires is_constructible_v<_Tp, _Up>
	    _Wrap(_Up&& __r, _Del2&& __d)
	    noexcept(is_nothrow_constructible_v<_Tp, _Up>)
	    : _M_t(std::forward<_Up>(__r))
	    { __d.release(); }

	  _Wrap() = default;

	  _Wrap(_Wrap&&) = default;

	  _Wrap(_Wrap&& __rhs) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>)
	  requires (!is_nothrow_move_constructible_v<_Tp>)
	  : _M_t(__rhs._M_t)
	  { }

	  _Wrap& operator=(const _Wrap&) = default;

	  _Wrap& operator=(_Wrap&&) = default;

	  constexpr _Tp& get() noexcept { return _M_t; }
	  constexpr const _Tp& get() const noexcept { return _M_t; }

	  [[no_unique_address]] _Tp _M_t{};
	};

      template<typename _Tp>
	struct _Wrap<_Tp&>
	{
	  template<typename _Up>
	    requires is_constructible_v<reference_wrapper<_Tp>, _Up>
	    _Wrap(_Up&&)
	    noexcept(is_nothrow_constructible_v<reference_wrapper<_Tp>, _Up>);

	  template<typename _Up, typename _Del2>
	    _Wrap(_Up&& __r, _Del2&& __d)
	    noexcept(is_nothrow_constructible_v<reference_wrapper<_Tp>, _Up>)
	    : _M_p(__builtin_addressof(static_cast<_Tp&>(__r)))
	    { __d.release(); }

	  _Wrap() = delete;

	  _Wrap(const _Wrap&) = default;

	  _Wrap& operator=(const _Wrap&) = default;

	  _Tp& get() noexcept { return *_M_p; }
	  const _Tp& get() const noexcept { return *_M_p; }

	  _Tp* _M_p = nullptr;
	};

      using _Res1 = _Wrap<_Resrc>;

      template<typename _Tp, typename _Up>
	requires is_constructible_v<_Tp, _Up>
	  && (is_nothrow_constructible_v<_Tp, _Up>
		|| is_constructible_v<_Tp, _Up&>)
	using _Fwd_t
	  = __conditional_t<is_nothrow_constructible_v<_Tp, _Up>, _Up, _Up&>;

      template<typename _Tp, typename _Up>
	static constexpr _Fwd_t<_Tp, _Up>
	_S_fwd(_Up& __u)
	{ return static_cast<_Fwd_t<_Tp, _Up>&&>(__u); }

      template<typename _Tp, typename _Up, typename _Del2, typename _Res2>
	static constexpr auto
	_S_guard(_Del2& __d, _Res2& __r)
	{
	  if constexpr (is_nothrow_constructible_v<_Tp, _Up>)
	    return _Dummy{};
	  else
	    return scope_fail{[&] { __d(__r); }};
	}

    public:
      unique_resource() = default;

      template<typename _Res2, typename _Del2>
	requires requires {
	  typename _Fwd_t<_Res1, _Res2>;
	  typename _Fwd_t<_Del, _Del2>;
	}
	unique_resource(_Res2&& __r, _Del2&& __d)
	noexcept((is_nothrow_constructible_v<_Res1, _Res2>
		    || is_nothrow_constructible_v<_Res1, _Res2&>)
		  &&
		 (is_nothrow_constructible_v<_Del, _Del2>
		    || is_nothrow_constructible_v<_Del, _Del2&>))
	: _M_res(_S_fwd<_Res1, _Res2>(__r),
		 _S_guard<_Res1, _Res2>(__d, __r)),
	  _M_del(_S_fwd<_Del, _Del2>(__d),
		 _S_guard<_Del, _Del2>(__d, _M_res.get())),
	  _M_exec_on_reset(true)
	{ }

      unique_resource(unique_resource&& __rhs) noexcept
      requires is_nothrow_move_constructible_v<_Res1>
	    && is_nothrow_move_constructible_v<_Del>
      : _M_res(std::move(__rhs._M_res)),
	_M_del(std::move(__rhs._M_del)),
	_M_exec_on_reset(std::__exchange(__rhs._M_exec_on_reset, false))
      { }

      unique_resource(unique_resource&& __rhs)
      requires is_nothrow_move_constructible_v<_Res1>
	    && (!is_nothrow_move_constructible_v<_Del>)
      : _M_res(std::move(__rhs._M_res)),
	_M_del(_S_fwd<_Del, _Del>(__rhs._M_del.get()),
	       scope_fail([&]{
		 if (__rhs._M_exec_on_reset)
		   {
		     __rhs._M_del.get()(_M_res.get());
		     __rhs.release();
		   }
	       })),
	_M_exec_on_reset(std::__exchange(__rhs._M_exec_on_reset, false))
      { }

      unique_resource(unique_resource&& __rhs)
      requires (!is_nothrow_move_constructible_v<_Res1>)
      : unique_resource(__rhs._M_res.get(), __rhs._M_del.get(), _Dummy{})
      {
	if (__rhs._M_exec_on_reset)
	  {
	    _M_exec_on_reset = true;
	    __rhs._M_exec_on_reset = false;
	  }
      }

      // 3.3.3.3, Destructor
      ~unique_resource() { reset(); }

      // 3.3.3.4, Assignment
      unique_resource&
      operator=(unique_resource&& __rhs)
      noexcept(is_nothrow_move_assignable_v<_Res1>
		&& is_nothrow_move_assignable_v<_Del>)
      {
	reset();
	if constexpr (is_nothrow_move_assignable_v<_Res1>)
	  {
	    if constexpr (is_nothrow_move_assignable_v<_Del>)
	      {
		_M_res = std::move(__rhs._M_res);
		_M_del = std::move(__rhs._M_del);
	      }
	    else
	      {
		_M_del = __rhs._M_del;
		_M_res = std::move(__rhs._M_res);
	      }
	  }
	else
	  {
	    if constexpr (is_nothrow_move_assignable_v<_Del>)
	      {
		_M_res = __rhs._M_res;
		_M_del = std::move(__rhs._M_del);
	      }
	    else
	      {
		_M_res = __rhs._M_res;
		_M_del = __rhs._M_del;
	      }
	  }
	_M_exec_on_reset = std::__exchange(__rhs._M_exec_on_reset, false);
	return *this;
      }

      // 3.3.3.5, Other member functions
      void
      reset() noexcept
      {
	if (_M_exec_on_reset)
	  {
	    _M_exec_on_reset = false;
	    _M_del.get()(_M_res.get());
	  }
      }

      template<typename _Res2>
	void
	reset(_Res2&& __r)
	{
	  reset();
	  if constexpr (is_nothrow_assignable_v<_Res1&, _Res2>)
	    _M_res.get() = std::forward<_Res2>(__r);
	  else
	    _M_res.get() = const_cast<const remove_reference_t<_Res2>&>(__r);
	  _M_exec_on_reset = true;
	}

      void
      release() noexcept
      { _M_exec_on_reset = false; }

      const _Resrc&
      get() const noexcept
      { return _M_res.get(); }

      add_lvalue_reference_t<remove_pointer_t<_Resrc>>
      operator*() const noexcept
      requires is_pointer_v<_Resrc> && (!is_void_v<remove_pointer_t<_Resrc>>)
      { return *get(); }

      _Resrc operator->() const noexcept
      requires is_pointer_v<_Resrc>
      { return _M_res.get(); }

      const _Del&
      get_deleter() const noexcept
      { return _M_del.get(); }

    private:
      [[no_unique_address]] _Res1 _M_res{};
      [[no_unique_address]] _Wrap<_Del> _M_del{};
      bool _M_exec_on_reset = false;

      template<typename _Res2, typename _Del2, typename _St>
	friend unique_resource<decay_t<_Res2>, decay_t<_Del2>>
	make_unique_resource_checked(_Res2&&, const _St&, _Del2&&)
	noexcept(is_nothrow_constructible_v<decay_t<_Res2>, _Res2>
		  && is_nothrow_constructible_v<decay_t<_Del2>, _Del2>);

      template<typename _Res2, typename _Del2>
	unique_resource(_Res2&& __r, _Del2&& __d, _Dummy __noop)
	noexcept(is_nothrow_constructible_v<_Resrc, _Res2>
		  && is_nothrow_constructible_v<_Del, _Del2>)
	: _M_res(std::forward<_Res2>(__r), __noop),
	  _M_del(std::forward<_Del>(__d), __noop)
	{ }
    };

  template<typename _Resrc, typename _Del>
    unique_resource(_Resrc, _Del) -> unique_resource<_Resrc, _Del>;

  template<typename _Resrc, typename _Del, typename _St = decay_t<_Resrc>>
    unique_resource<decay_t<_Resrc>, decay_t<_Del>>
    make_unique_resource_checked(_Resrc&& __r, const _St& __invalid, _Del&& __d)
    noexcept(is_nothrow_constructible_v<decay_t<_Resrc>, _Resrc>
	      && is_nothrow_constructible_v<decay_t<_Del>, _Del>)
    {
      if (__r == __invalid)
	return { std::forward<_Resrc>(__r), std::forward<_Del>(__d), {} };
      return { std::forward<_Resrc>(__r), std::forward<_Del>(__d) };
    }

} // namespace experimental::fundamentals_v3
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++20
#endif // _GLIBCXX_EXPERIMENTAL_SCOPE
