// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE
#define _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE

/**
    experimental/memory_resource synopsis

// C++1y

namespace std {
namespace experimental {
inline namespace fundamentals_v1 {
namespace pmr {

  class memory_resource;

  bool operator==(const memory_resource& a,
                  const memory_resource& b) noexcept;
  bool operator!=(const memory_resource& a,
                  const memory_resource& b) noexcept;

  template <class Tp> class polymorphic_allocator;

  template <class T1, class T2>
  bool operator==(const polymorphic_allocator<T1>& a,
                  const polymorphic_allocator<T2>& b) noexcept;
  template <class T1, class T2>
  bool operator!=(const polymorphic_allocator<T1>& a,
                  const polymorphic_allocator<T2>& b) noexcept;

  // The name resource_adaptor_imp is for exposition only.
  template <class Allocator> class resource_adaptor_imp;

  template <class Allocator>
    using resource_adaptor = resource_adaptor_imp<
      allocator_traits<Allocator>::rebind_alloc<char>>;

  // Global memory resources
  memory_resource* new_delete_resource() noexcept;
  memory_resource* null_memory_resource() noexcept;

  // The default memory resource
  memory_resource* set_default_resource(memory_resource* r) noexcept;
  memory_resource* get_default_resource() noexcept;

  // Standard memory resources
  struct pool_options;
  class synchronized_pool_resource;
  class unsynchronized_pool_resource;
  class monotonic_buffer_resource;

} // namespace pmr
} // namespace fundamentals_v1
} // namespace experimental
} // namespace std

 */

#include <__assert> // all public C++ headers provide the assertion handler
#include <__memory/allocator_traits.h>
#include <__utility/move.h>
#include <cstddef>
#include <cstdlib>
#include <experimental/__config>
#include <experimental/__memory>
#include <limits>
#include <new>
#include <stdexcept>
#include <tuple>
#include <type_traits>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR

#define _LIBCPP_DEPCREATED_MEMORY_RESOURCE(name)                                                                       \
  _LIBCPP_DEPRECATED_("'std::experimental::pmr::" name                                                                 \
                      "' is deprecated and will be removed in LLVM 18. Use 'std::pmr::" name "' instead.")

#ifndef _LIBCPP_CXX03_LANG

// Round __s up to next multiple of __a.
inline _LIBCPP_INLINE_VISIBILITY
size_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT
{
    _LIBCPP_ASSERT(__s + __a > __s, "aligned allocation size overflows");
    return (__s + __a - 1) & ~(__a - 1);
}

// 8.5, memory.resource
class _LIBCPP_DEPCREATED_MEMORY_RESOURCE("memory_resource") _LIBCPP_TYPE_VIS memory_resource
{
    static const size_t __max_align = _LIBCPP_ALIGNOF(max_align_t);

// 8.5.2, memory.resource.public
public:
    virtual ~memory_resource() = default;

    _LIBCPP_INLINE_VISIBILITY
    void* allocate(size_t __bytes, size_t __align = __max_align)
        { return do_allocate(__bytes, __align); }

    _LIBCPP_INLINE_VISIBILITY
    void deallocate(void * __p, size_t __bytes, size_t __align = __max_align)
        { do_deallocate(__p, __bytes, __align); }

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

// 8.5.3, memory.resource.priv
private:
    virtual void* do_allocate(size_t, size_t) = 0;
    virtual void do_deallocate(void*, size_t, size_t) = 0;
    virtual bool do_is_equal(memory_resource const &) const _NOEXCEPT = 0;
};

// 8.5.4, memory.resource.eq
_LIBCPP_DEPCREATED_MEMORY_RESOURCE("operator==(memory_resource, memory_resource)") inline _LIBCPP_INLINE_VISIBILITY
bool operator==(memory_resource const & __lhs,
                memory_resource const & __rhs) _NOEXCEPT
{
    return &__lhs == &__rhs || __lhs.is_equal(__rhs);
}

_LIBCPP_DEPCREATED_MEMORY_RESOURCE("operator!=(memory_resource, memory_resource)") inline _LIBCPP_INLINE_VISIBILITY
bool operator!=(memory_resource const & __lhs,
                memory_resource const & __rhs) _NOEXCEPT
{
    return !(__lhs == __rhs);
}

_LIBCPP_DEPCREATED_MEMORY_RESOURCE("new_delete_resource()") _LIBCPP_FUNC_VIS
memory_resource * new_delete_resource() _NOEXCEPT;

_LIBCPP_DEPCREATED_MEMORY_RESOURCE("null_memory_resource()") _LIBCPP_FUNC_VIS
memory_resource * null_memory_resource() _NOEXCEPT;

_LIBCPP_DEPCREATED_MEMORY_RESOURCE("get_default_resource()") _LIBCPP_FUNC_VIS
memory_resource * get_default_resource() _NOEXCEPT;

_LIBCPP_DEPCREATED_MEMORY_RESOURCE("set_default_resource()") _LIBCPP_FUNC_VIS
memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT;

// 8.6, memory.polymorphic.allocator.class

// 8.6.1, memory.polymorphic.allocator.overview
template <class _ValueType>
class _LIBCPP_DEPCREATED_MEMORY_RESOURCE("polymorphic_allocator") _LIBCPP_TEMPLATE_VIS polymorphic_allocator
{
public:
    typedef _ValueType value_type;

    // 8.6.2, memory.polymorphic.allocator.ctor
    _LIBCPP_INLINE_VISIBILITY
    polymorphic_allocator() _NOEXCEPT
      : __res_(_VSTD_LFTS_PMR::get_default_resource())
    {}

    _LIBCPP_INLINE_VISIBILITY
    polymorphic_allocator(memory_resource * __r) _NOEXCEPT
      : __res_(__r)
    {}

    polymorphic_allocator(polymorphic_allocator const &) = default;

    template <class _Tp>
    _LIBCPP_INLINE_VISIBILITY
    polymorphic_allocator(polymorphic_allocator<_Tp> const & __other) _NOEXCEPT
      : __res_(__other.resource())
    {}

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

    // 8.6.3, memory.polymorphic.allocator.mem
    _LIBCPP_INLINE_VISIBILITY
    _ValueType* allocate(size_t __n) {
        if (__n > __max_size())
            __throw_bad_array_new_length();
        return static_cast<_ValueType*>(
            __res_->allocate(__n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType))
        );
    }

    _LIBCPP_INLINE_VISIBILITY
    void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT {
        _LIBCPP_ASSERT(__n <= __max_size(),
                       "deallocate called for size which exceeds max_size()");
        __res_->deallocate(__p, __n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType));
    }

    template <class _Tp, class ..._Ts>
    _LIBCPP_INLINE_VISIBILITY
    void construct(_Tp* __p, _Ts &&... __args)
    {
        _VSTD_LFTS::__lfts_user_alloc_construct(
            __p, *this, _VSTD::forward<_Ts>(__args)...
          );
    }

    template <class _T1, class _T2, class ..._Args1, class ..._Args2>
    _LIBCPP_INLINE_VISIBILITY
    void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
                   tuple<_Args1...> __x, tuple<_Args2...> __y)
    {
        ::new ((void*)__p) pair<_T1, _T2>(piecewise_construct
          , __transform_tuple(
              typename __lfts_uses_alloc_ctor<
                  _T1, polymorphic_allocator&, _Args1...
              >::type()
            , _VSTD::move(__x)
            , typename __make_tuple_indices<sizeof...(_Args1)>::type{}
          )
          , __transform_tuple(
              typename __lfts_uses_alloc_ctor<
                  _T2, polymorphic_allocator&, _Args2...
              >::type()
            , _VSTD::move(__y)
            , typename __make_tuple_indices<sizeof...(_Args2)>::type{}
          )
        );
    }

    template <class _T1, class _T2>
    _LIBCPP_INLINE_VISIBILITY
    void construct(pair<_T1, _T2>* __p) {
        construct(__p, piecewise_construct, tuple<>(), tuple<>());
    }

    template <class _T1, class _T2, class _Up, class _Vp>
    _LIBCPP_INLINE_VISIBILITY
    void construct(pair<_T1, _T2> * __p, _Up && __u, _Vp && __v) {
        construct(__p, piecewise_construct
          , _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__u))
          , _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__v)));
    }

    template <class _T1, class _T2, class _U1, class _U2>
    _LIBCPP_INLINE_VISIBILITY
    void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> const & __pr) {
        construct(__p, piecewise_construct
            , _VSTD::forward_as_tuple(__pr.first)
            , _VSTD::forward_as_tuple(__pr.second));
    }

    template <class _T1, class _T2, class _U1, class _U2>
    _LIBCPP_INLINE_VISIBILITY
    void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> && __pr){
        construct(__p, piecewise_construct
            , _VSTD::forward_as_tuple(_VSTD::forward<_U1>(__pr.first))
            , _VSTD::forward_as_tuple(_VSTD::forward<_U2>(__pr.second)));
    }

    template <class _Tp>
    _LIBCPP_INLINE_VISIBILITY
    void destroy(_Tp * __p) _NOEXCEPT
        { __p->~_Tp(); }

    _LIBCPP_INLINE_VISIBILITY
    polymorphic_allocator
    select_on_container_copy_construction() const _NOEXCEPT
        { return polymorphic_allocator(); }

    _LIBCPP_INLINE_VISIBILITY
    memory_resource * resource() const _NOEXCEPT
        { return __res_; }

private:
    template <class ..._Args, size_t ..._Idx>
    _LIBCPP_INLINE_VISIBILITY
    tuple<_Args&&...>
    __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t,
                      __tuple_indices<_Idx...>) const
    {
        return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...);
    }

    template <class ..._Args, size_t ..._Idx>
    _LIBCPP_INLINE_VISIBILITY
    tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...>
    __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t,
                      __tuple_indices<_Idx...>)
    {
        using _Tup = tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...>;
        return _Tup(allocator_arg, *this,
                    _VSTD::get<_Idx>(_VSTD::move(__t))...);
    }

    template <class ..._Args, size_t ..._Idx>
    _LIBCPP_INLINE_VISIBILITY
    tuple<_Args&&..., polymorphic_allocator&>
    __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t,
                      __tuple_indices<_Idx...>)
    {
        using _Tup = tuple<_Args&&..., polymorphic_allocator&>;
        return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., *this);
    }

    _LIBCPP_INLINE_VISIBILITY
    size_t __max_size() const _NOEXCEPT
        { return numeric_limits<size_t>::max() / sizeof(value_type); }

    memory_resource * __res_;
};

// 8.6.4, memory.polymorphic.allocator.eq

template <class _Tp, class _Up>
_LIBCPP_DEPCREATED_MEMORY_RESOURCE("operator==(const polymorphic_allocator&, const polymorphic_allocator&)")
inline _LIBCPP_INLINE_VISIBILITY
bool operator==(polymorphic_allocator<_Tp> const & __lhs,
                polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT
{
    return *__lhs.resource() == *__rhs.resource();
}

template <class _Tp, class _Up>
_LIBCPP_DEPCREATED_MEMORY_RESOURCE("operator!=(const polymorphic_allocator&, const polymorphic_allocator&)")
inline _LIBCPP_INLINE_VISIBILITY
bool operator!=(polymorphic_allocator<_Tp> const & __lhs,
                polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT
{
    return !(__lhs == __rhs);
}

// 8.7, memory.resource.adaptor

_LIBCPP_SUPPRESS_DEPRECATED_PUSH
// 8.7.1, memory.resource.adaptor.overview
template <class _CharAlloc>
class _LIBCPP_TEMPLATE_VIS __resource_adaptor_imp
  : public memory_resource
{
    using _CTraits = allocator_traits<_CharAlloc>;
    static_assert(is_same<typename _CTraits::value_type, char>::value
               && is_same<typename _CTraits::pointer, char*>::value
               && is_same<typename _CTraits::void_pointer, void*>::value, "");

    static const size_t _MaxAlign = _LIBCPP_ALIGNOF(max_align_t);

    using _Alloc = typename _CTraits::template rebind_alloc<
            typename aligned_storage<_MaxAlign, _MaxAlign>::type
        >;

    using _ValueType = typename _Alloc::value_type;

    _Alloc __alloc_;

public:
    typedef _CharAlloc allocator_type;

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

    // 8.7.2, memory.resource.adaptor.ctor

    _LIBCPP_INLINE_VISIBILITY
    explicit __resource_adaptor_imp(allocator_type const & __a)
      : __alloc_(__a)
    {}

    _LIBCPP_INLINE_VISIBILITY
    explicit __resource_adaptor_imp(allocator_type && __a)
      : __alloc_(_VSTD::move(__a))
    {}

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

    _LIBCPP_INLINE_VISIBILITY
    allocator_type get_allocator() const
    { return __alloc_; }

// 8.7.3, memory.resource.adaptor.mem
private:
    void * do_allocate(size_t __bytes, size_t) override
    {
        if (__bytes > __max_size())
            __throw_bad_array_new_length();
        size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign;
        return __alloc_.allocate(__s);
    }

    void do_deallocate(void * __p, size_t __bytes, size_t) override
    {
        _LIBCPP_ASSERT(__bytes <= __max_size(),
            "do_deallocate called for size which exceeds the maximum allocation size");
        size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign;
        __alloc_.deallocate((_ValueType*)__p, __s);
    }

    bool do_is_equal(memory_resource const & __other) const _NOEXCEPT override {
        __resource_adaptor_imp const * __p
          = dynamic_cast<__resource_adaptor_imp const *>(&__other);
        return __p  ? __alloc_ == __p->__alloc_ : false;
    }

    _LIBCPP_INLINE_VISIBILITY
    size_t __max_size() const _NOEXCEPT {
        return numeric_limits<size_t>::max() - _MaxAlign;
    }
};

template <class _Alloc>
using resource_adaptor = __resource_adaptor_imp<
    typename allocator_traits<_Alloc>::template rebind_alloc<char>
  >;
_LIBCPP_SUPPRESS_DEPRECATED_POP

#endif // _LIBCPP_CXX03_LANG

_LIBCPP_END_NAMESPACE_LFTS_PMR

_LIBCPP_POP_MACROS

#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
#  include <atomic>
#  include <climits>
#  include <concepts>
#  include <cstring>
#  include <ctime>
#  include <iterator>
#  include <memory>
#  include <ratio>
#  include <variant>
#endif

#endif /* _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE */
