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

// Copyright (C) 2015-2020 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

#pragma GCC system_header

#if __cplusplus >= 201402L

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

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

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,
			  forward_as_tuple(std::forward<_Up>(__x)),
			  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,
			  forward_as_tuple(__pr.first),
			  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,
			  forward_as_tuple(std::forward<_Up>(__pr.first)),
			  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:
      virtual void*
      do_allocate(size_t __bytes, size_t __alignment) override
      {
	// Cannot use max_align_t on 32-bit Solaris x86, see PR libstdc++/77691
#if ! ((defined __sun__ || defined __VXWORKS__) && defined __i386__)
	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 ! ((defined __sun__ || defined __VXWORKS__) && defined __i386__)
	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 (auto __p = dynamic_cast<const __resource_adaptor_imp*>(&__other))
	  return _M_alloc == __p->_M_alloc;
	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<__gnu_cxx::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 std::atomic<memory_resource*>&
  __get_default_resource()
  {
    using type = atomic<memory_resource*>;
    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
