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

// Copyright (C) 2015-2026 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 experimental/memory_resource
 *  This is a TS C++ Library header.
 *  @ingroup libfund-ts
 */

#ifndef _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE
#define _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

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

#if __cplusplus >= 201402L

#include <memory>			// align, uses_allocator, __uses_alloc
#include <experimental/utility>		// pair, experimental::erased_type
#include <tuple>			// tuple, forward_as_tuple
#include <atomic>			// atomic
#include <new>				// placement new
#include <cstddef>			// max_align_t
#include <bits/new_allocator.h>
#include <debug/assertions.h>

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
  template<typename _Tp> class malloc_allocator;
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __gnu_cxx

namespace std {
_GLIBCXX_BEGIN_NAMESPACE_VERSION

namespace experimental {
inline namespace fundamentals_v2 {
namespace pmr {
#define __cpp_lib_experimental_memory_resources 201402L

  // Standard memory resources

  // 8.5 Class memory_resource
  class memory_resource;

  // 8.6 Class template polymorphic_allocator
  template<typename _Tp>
    class polymorphic_allocator;

  template<typename _Alloc, typename _Resource = memory_resource>
    class __resource_adaptor_imp;

  // 8.7 Alias template resource_adaptor
  template<typename _Alloc>
    using resource_adaptor = __resource_adaptor_imp<
      typename allocator_traits<_Alloc>::template rebind_alloc<char>>;

  // 8.8 Global memory resources
  memory_resource* new_delete_resource() noexcept;
  memory_resource* null_memory_resource() noexcept;
  memory_resource* get_default_resource() noexcept;
  memory_resource* set_default_resource(memory_resource* __r) noexcept;

  // TODO 8.9 Pool resource classes

  class memory_resource
  {
    static constexpr size_t _S_max_align = alignof(max_align_t);

  public:
    memory_resource() = default;
    memory_resource(const memory_resource&) = default;
    virtual ~memory_resource() = default;

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

    _GLIBCXX_NODISCARD void*
    allocate(size_t __bytes, size_t __alignment = _S_max_align)
    { return do_allocate(__bytes, __alignment); }

    void
    deallocate(void* __p, size_t __bytes, size_t __alignment = _S_max_align)
    { return do_deallocate(__p, __bytes, __alignment); }

    bool
    is_equal(const memory_resource& __other) const noexcept
    { return do_is_equal(__other); }

  protected:
    virtual void*
    do_allocate(size_t __bytes, size_t __alignment) = 0;

    virtual void
    do_deallocate(void* __p, size_t __bytes, size_t __alignment) = 0;

    virtual bool
    do_is_equal(const memory_resource& __other) const noexcept = 0;
  };

  inline bool
  operator==(const memory_resource& __a, const memory_resource& __b) noexcept
  { return &__a == &__b || __a.is_equal(__b); }

  inline bool
  operator!=(const memory_resource& __a, const memory_resource& __b) noexcept
  { return !(__a == __b); }


  template<typename _Tp>
    class polymorphic_allocator
    {
    public:
      using value_type = _Tp;

      polymorphic_allocator() noexcept
      : _M_resource(get_default_resource())
      { }

      polymorphic_allocator(memory_resource* __r)
      : _M_resource(__r)
      { _GLIBCXX_DEBUG_ASSERT(__r); }

      polymorphic_allocator(const polymorphic_allocator& __other) = default;

      template <typename _Up>
	polymorphic_allocator(const polymorphic_allocator<_Up>&
			      __other) noexcept
	: _M_resource(__other.resource())
	{ }

      polymorphic_allocator&
	operator=(const polymorphic_allocator& __rhs) = default;

      _GLIBCXX_NODISCARD _Tp* allocate(size_t __n)
      { return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),
						       alignof(_Tp))); }

      void
      deallocate(_Tp* __p, size_t __n)
      { _M_resource->deallocate(__p, __n * sizeof(_Tp), alignof(_Tp)); }

      template <typename _Tp1, typename... _Args> //used here
	void
	construct(_Tp1* __p, _Args&&... __args)
	{
	  std::__uses_allocator_construct(this->resource(), __p,
					  std::forward<_Args>(__args)...);
	}

      // Specializations for pair using piecewise construction
      template <typename _Tp1, typename _Tp2,
	       typename... _Args1, typename... _Args2>
	void
	construct(pair<_Tp1, _Tp2>* __p, piecewise_construct_t,
		  tuple<_Args1...> __x, tuple<_Args2...> __y)
	{
	  memory_resource* const __resource = this->resource();
	  auto __x_use_tag =
	    std::__use_alloc<_Tp1, memory_resource*, _Args1...>(__resource);
	  auto __y_use_tag =
	    std::__use_alloc<_Tp2, memory_resource*, _Args2...>(__resource);

	  ::new(__p) std::pair<_Tp1, _Tp2>(piecewise_construct,
					   _M_construct_p(__x_use_tag, __x),
					   _M_construct_p(__y_use_tag, __y));
	}

      template <typename _Tp1, typename _Tp2>
	void
	construct(pair<_Tp1,_Tp2>* __p)
	{ this->construct(__p, piecewise_construct, tuple<>(), tuple<>()); }

      template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
	void
	construct(pair<_Tp1,_Tp2>* __p, _Up&& __x, _Vp&& __y)
	{
	  this->construct(__p, piecewise_construct,
	      std::forward_as_tuple(std::forward<_Up>(__x)),
	      std::forward_as_tuple(std::forward<_Vp>(__y)));
	}

      template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
	void
	construct(pair<_Tp1,_Tp2>* __p, const std::pair<_Up, _Vp>& __pr)
	{
	  this->construct(__p, piecewise_construct,
	      std::forward_as_tuple(__pr.first),
	      std::forward_as_tuple(__pr.second));
	}

      template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
	void
	construct(pair<_Tp1,_Tp2>* __p, pair<_Up, _Vp>&& __pr)
	{
	  this->construct(__p, piecewise_construct,
	      std::forward_as_tuple(std::forward<_Up>(__pr.first)),
	      std::forward_as_tuple(std::forward<_Vp>(__pr.second)));
	}

      template <typename _Up>
	void
	destroy(_Up* __p)
	{ __p->~_Up(); }

      // Return a default-constructed allocator (no allocator propagation)
      polymorphic_allocator
      select_on_container_copy_construction() const
      { return polymorphic_allocator(); }

      memory_resource* resource() const { return _M_resource; }

    private:
      using __uses_alloc1_ = __uses_alloc1<memory_resource*>;
      using __uses_alloc2_ = __uses_alloc2<memory_resource*>;

      template<typename _Tuple>
	_Tuple&&
	_M_construct_p(__uses_alloc0, _Tuple& __t)
	{ return std::move(__t); }

      template<typename... _Args>
	decltype(auto)
	_M_construct_p(__uses_alloc1_ __ua, tuple<_Args...>& __t)
	{ return tuple_cat(make_tuple(allocator_arg, *(__ua._M_a)),
			   std::move(__t)); }

      template<typename... _Args>
	decltype(auto)
	_M_construct_p(__uses_alloc2_ __ua, tuple<_Args...>& __t)
	{ return tuple_cat(std::move(__t), make_tuple(*(__ua._M_a))); }

      memory_resource* _M_resource;
    };

  template <class _Tp1, class _Tp2>
    bool
    operator==(const polymorphic_allocator<_Tp1>& __a,
	       const polymorphic_allocator<_Tp2>& __b) noexcept
    { return *__a.resource() == *__b.resource(); }

  template <class _Tp1, class _Tp2>
    bool
    operator!=(const polymorphic_allocator<_Tp1>& __a,
	       const polymorphic_allocator<_Tp2>& __b) noexcept
    { return !(__a == __b); }


  /// @cond undocumented
  class __resource_adaptor_common
  {
    template<typename, typename> friend class __resource_adaptor_imp;

    struct _AlignMgr
    {
      _AlignMgr(size_t __nbytes, size_t __align)
      : _M_nbytes(__nbytes), _M_align(__align)
      { }

      // Total size that needs to be allocated.
      size_t
      _M_alloc_size() const { return _M_buf_size() + _M_token_size(); }

      void*
      _M_adjust(void* __ptr) const
      {
	const auto __orig_ptr = static_cast<char*>(__ptr);
	size_t __space = _M_buf_size();
	// Align the pointer within the buffer:
	std::align(_M_align, _M_nbytes, __ptr, __space);
	const auto __aligned_ptr = static_cast<char*>(__ptr);
	const auto __token_size = _M_token_size();
	// Store token immediately after the aligned block:
	char* const __end = __aligned_ptr + _M_nbytes;
	if (__token_size == 1)
	  _S_write<unsigned char>(__end, __aligned_ptr - __orig_ptr);
	else if (__token_size == sizeof(short))
	  _S_write<unsigned short>(__end, __aligned_ptr - __orig_ptr);
	else if (__token_size == sizeof(int) && sizeof(int) < sizeof(char*))
	  _S_write<unsigned int>(__end, __aligned_ptr - __orig_ptr);
	else // (__token_size == sizeof(char*))
	  // Just store the original pointer:
	  _S_write<char*>(__end, __orig_ptr);
	return __aligned_ptr;
      }

      char*
      _M_unadjust(char* __ptr) const
      {
	const char* const __end = __ptr + _M_nbytes;
	char* __orig_ptr;
	const auto __token_size = _M_token_size();
	// Read the token and restore the original pointer:
	if (__token_size == 1)
	  __orig_ptr = __ptr - _S_read<unsigned char>(__end);
	else if (__token_size == sizeof(short))
	  __orig_ptr = __ptr - _S_read<unsigned short>(__end);
	else if (__token_size == sizeof(int)
	    && sizeof(int) < sizeof(char*))
	  __orig_ptr = __ptr - _S_read<unsigned int>(__end);
	else // (__token_size == sizeof(char*))
	  __orig_ptr = _S_read<char*>(__end);
	// The adjustment is always less than the requested alignment,
	// so if that isn't true now then either the wrong size was passed
	// to deallocate or the token was overwritten by a buffer overflow:
	__glibcxx_assert(static_cast<size_t>(__ptr - __orig_ptr) < _M_align);
	return __orig_ptr;
      }

    private:
      size_t _M_nbytes;
      size_t _M_align;

      // Number of bytes needed to fit block of given size and alignment.
      size_t
      _M_buf_size() const { return _M_nbytes + _M_align - 1; }

      // Number of additional bytes needed to write the token.
      int
      _M_token_size() const
      {
	if (_M_align <= (1ul << __CHAR_BIT__))
	  return 1;
	if (_M_align <= (1ul << (sizeof(short) * __CHAR_BIT__)))
	  return sizeof(short);
	if (_M_align <= (1ull << (sizeof(int) * __CHAR_BIT__)))
	  return sizeof(int);
	return sizeof(char*);
      }

      template<typename _Tp>
	static void
	_S_write(void* __to, _Tp __val)
	{ __builtin_memcpy(__to, &__val, sizeof(_Tp)); }

      template<typename _Tp>
	static _Tp
	_S_read(const void* __from)
	{
	  _Tp __val;
	  __builtin_memcpy(&__val, __from, sizeof(_Tp));
	  return __val;
	}
    };
  };
  /// @endcond

  // 8.7.1 __resource_adaptor_imp
  template<typename _Alloc, typename _Resource>
    class __resource_adaptor_imp
    : public _Resource, private __resource_adaptor_common
    {
      using memory_resource = _Resource;

      static_assert(is_same<char,
	  typename allocator_traits<_Alloc>::value_type>::value,
	  "Allocator's value_type is char");
      static_assert(is_same<char*,
	  typename allocator_traits<_Alloc>::pointer>::value,
	  "Allocator's pointer type is value_type*");
      static_assert(is_same<const char*,
	  typename allocator_traits<_Alloc>::const_pointer>::value,
	  "Allocator's const_pointer type is value_type const*");
      static_assert(is_same<void*,
	  typename allocator_traits<_Alloc>::void_pointer>::value,
	  "Allocator's void_pointer type is void*");
      static_assert(is_same<const void*,
	  typename allocator_traits<_Alloc>::const_void_pointer>::value,
	  "Allocator's const_void_pointer type is void const*");

    public:
      using allocator_type = _Alloc;

      __resource_adaptor_imp() = default;
      __resource_adaptor_imp(const __resource_adaptor_imp&) = default;
      __resource_adaptor_imp(__resource_adaptor_imp&&) = default;

      explicit __resource_adaptor_imp(const _Alloc& __a2)
      : _M_alloc(__a2)
      { }

      explicit __resource_adaptor_imp(_Alloc&& __a2)
      : _M_alloc(std::move(__a2))
      { }

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

      allocator_type get_allocator() const noexcept { return _M_alloc; }

    protected:
#if (defined __sun__ || defined __VXWORKS__) && defined __i386__
// Cannot use max_align_t on 32-bit Solaris x86, see PR libstdc++/77691
# define _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC 0
#elif defined __hpux__ && defined __hppa__ && defined __LP64__
// Ignore inconsistent long double and malloc alignment (libstdc++/77691)
# define _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC 0
#else
# define _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC 1
#endif

      virtual void*
      do_allocate(size_t __bytes, size_t __alignment) override
      {
#if _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC
	if (__alignment == alignof(max_align_t))
	  return _M_allocate<alignof(max_align_t)>(__bytes);
#endif
	switch (__alignment)
	  {
	  case 1:
	    return _M_alloc.allocate(__bytes);
	  case 2:
	    return _M_allocate<2>(__bytes);
	  case 4:
	    return _M_allocate<4>(__bytes);
	  case 8:
	    return _M_allocate<8>(__bytes);
	  }
	const _AlignMgr __mgr(__bytes, __alignment);
	// Assume _M_alloc returns 1-byte aligned memory, so allocate enough
	// space to fit a block of the right size and alignment, plus some
	// extra bytes to store a token for retrieving the original pointer.
	return __mgr._M_adjust(_M_alloc.allocate(__mgr._M_alloc_size()));
      }

      virtual void
      do_deallocate(void* __ptr, size_t __bytes, size_t __alignment) noexcept
      override
      {
#if _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC
	if (__alignment == alignof(max_align_t))
	  return (void) _M_deallocate<alignof(max_align_t)>(__ptr, __bytes);
#endif
	switch (__alignment)
	  {
	  case 1:
	    return (void) _M_alloc.deallocate((char*)__ptr, __bytes);
	  case 2:
	    return (void) _M_deallocate<2>(__ptr, __bytes);
	  case 4:
	    return (void) _M_deallocate<4>(__ptr, __bytes);
	  case 8:
	    return (void) _M_deallocate<8>(__ptr, __bytes);
	  }
	const _AlignMgr __mgr(__bytes, __alignment);
	// Use the stored token to retrieve the original pointer.
	_M_alloc.deallocate(__mgr._M_unadjust((char*)__ptr),
	    __mgr._M_alloc_size());
      }

      virtual bool
      do_is_equal(const memory_resource& __other) const noexcept override
      {
#if __cpp_rtti
	if (auto __p = dynamic_cast<const __resource_adaptor_imp*>(&__other))
	  return _M_alloc == __p->_M_alloc;
#else
	if (this == &__other) // Need RTTI to do better than this.
	  return true;
#endif
	return false;
      }

    private:
      template<size_t _Num>
	struct _Aligned_type { alignas(_Num) char __c[_Num]; };

      // Rebind the allocator to the specified type and use it to allocate.
      template<size_t _Num, typename _Tp = _Aligned_type<_Num>>
	void*
	_M_allocate(size_t __bytes)
	{
	  typename allocator_traits<_Alloc>::template
	    rebind_alloc<_Tp> __a2(_M_alloc);
	  const size_t __n = (__bytes + _Num - 1) / _Num;
	  return __a2.allocate(__n);
	}

      // Rebind the allocator to the specified type and use it to deallocate.
      template<size_t _Num, typename _Tp = _Aligned_type<_Num>>
	void
	_M_deallocate(void* __ptr, size_t __bytes) noexcept
	{
	  typename allocator_traits<_Alloc>::template
	    rebind_alloc<_Tp> __a2(_M_alloc);
	  const size_t __n = (__bytes + _Num - 1) / _Num;
	  __a2.deallocate((_Tp*)__ptr, __n);
	}

      _Alloc _M_alloc{};
    };

  // Global memory resources

  inline memory_resource*
  new_delete_resource() noexcept
  {
    using type = resource_adaptor<std::__new_allocator<char>>;
    alignas(type) static unsigned char __buf[sizeof(type)];
    static type* __r = new(__buf) type;
    return __r;
  }

  inline memory_resource*
  null_memory_resource() noexcept
  {
    class type final : public memory_resource
    {
      void*
      do_allocate(size_t, size_t) override
      { std::__throw_bad_alloc(); }

      void
      do_deallocate(void*, size_t, size_t) noexcept override
      { }

      bool
      do_is_equal(const memory_resource& __other) const noexcept override
      { return this == &__other; }
    };

    alignas(type) static unsigned char __buf[sizeof(type)];
    static type* __r = new(__buf) type;
    return __r;
  }

  // The default memory resource

  /// @cond undocumented
  inline auto&
  __get_default_resource()
  {
#ifndef _GLIBCXX_HAS_GTHREADS
    struct type {
      using value_type = memory_resource*;
      explicit type(value_type __r) : _M_r(__r) { }
      value_type _M_r;
      value_type load() const { return _M_r; }
      value_type exchange(value_type __r) { return std::__exchange(_M_r, __r); }
    };
#else
    using type = atomic<memory_resource*>;
#endif
    alignas(type) static unsigned char __buf[sizeof(type)];
    static type* __r = new(__buf) type(new_delete_resource());
    return *__r;
  }
  /// @endcond

  /// Get the current default resource.
  inline memory_resource*
  get_default_resource() noexcept
  { return __get_default_resource().load(); }

  /// Change the default resource and return the previous one.
  inline memory_resource*
  set_default_resource(memory_resource* __r) noexcept
  {
    if (__r == nullptr)
      __r = new_delete_resource();
    return __get_default_resource().exchange(__r);
  }

} // namespace pmr
} // namespace fundamentals_v2
} // namespace experimental

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++14
#endif // _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE
