// -*- C++ -*-
//===------------------------ memory_resource -----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#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 <experimental/__config>
#include <experimental/__memory>
#include <limits>
#include <memory>
#include <new>
#include <stdexcept>
#include <tuple>
#include <type_traits>
#include <utility>
#include <cstddef>
#include <cstdlib>
#include <__debug>

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

_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR

// 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_TEMPLATE_VIS memory_resource
{
    static const size_t __max_align = 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
protected:
    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
inline _LIBCPP_INLINE_VISIBILITY
bool operator==(memory_resource const & __lhs,
                memory_resource const & __rhs) _NOEXCEPT
{
    return &__lhs == &__rhs || __lhs.is_equal(__rhs);
}

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

_LIBCPP_FUNC_VIS
memory_resource * new_delete_resource() _NOEXCEPT;

_LIBCPP_FUNC_VIS
memory_resource * null_memory_resource() _NOEXCEPT;

_LIBCPP_FUNC_VIS
memory_resource * get_default_resource() _NOEXCEPT;

_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_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_length_error(
                "std::experimental::pmr::polymorphic_allocator<T>::allocate(size_t n)"
                " 'n' exceeds maximum supported size");
        }
        return static_cast<_ValueType*>(
            __res_->allocate(__n * sizeof(_ValueType), 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), alignof(_ValueType));
    }

    template <class _Tp, class ..._Ts>
    _LIBCPP_INLINE_VISIBILITY
    void construct(_Tp* __p, _Ts &&... __args)
    {
        _VSTD_LFTS::__lfts_user_alloc_construct(
            __p, resource(), _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, memory_resource*, _Args1...
              >::type()
            , _VSTD::move(__x)
            , typename __make_tuple_indices<sizeof...(_Args1)>::type{}
          )
          , __transform_tuple(
              typename __lfts_uses_alloc_ctor<
                  _T2, memory_resource*, _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&, memory_resource*, _Args&&...>
    __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t,
                      __tuple_indices<_Idx...>) const
    {
        using _Tup = tuple<allocator_arg_t const&, memory_resource*, _Args&&...>;
        return _Tup(allocator_arg, resource(),
                    _VSTD::get<_Idx>(_VSTD::move(__t))...);
    }

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

    _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>
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>
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

// 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 = 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
protected:
    virtual void * do_allocate(size_t __bytes, size_t)
    {
        if (__bytes > __max_size()) {
            __throw_length_error(
                "std::experimental::pmr::resource_adaptor<T>::do_allocate(size_t bytes, size_t align)"
                " 'bytes' exceeds maximum supported size");
        }
        size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign;
        return __alloc_.allocate(__s);
    }

    virtual void do_deallocate(void * __p, size_t __bytes, size_t)
    {
        _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);
    }

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

private:
    _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_END_NAMESPACE_LFTS_PMR

#endif /* _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE */
