// -*- 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 <__type_traits/aligned_storage.h>
#include <__utility/move.h>
#include <cstddef>
#include <experimental/__config>
#include <experimental/__memory>
#include <limits>
#include <new>
#include <stdexcept>
#include <tuple>

#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 <cstdlib>
#  include <cstring>
#  include <ctime>
#  include <iterator>
#  include <memory>
#  include <ratio>
#  include <type_traits>
#  include <variant>
#endif

#endif /* _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE */
