xref: /openbsd-src/gnu/llvm/libcxx/include/experimental/memory_resource (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
146035553Spatrick// -*- C++ -*-
2*4bdff4beSrobert//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick#ifndef _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE
1146035553Spatrick#define _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE
1246035553Spatrick
1346035553Spatrick/**
1446035553Spatrick    experimental/memory_resource synopsis
1546035553Spatrick
1646035553Spatrick// C++1y
1746035553Spatrick
1846035553Spatricknamespace std {
1946035553Spatricknamespace experimental {
2046035553Spatrickinline namespace fundamentals_v1 {
2146035553Spatricknamespace pmr {
2246035553Spatrick
2346035553Spatrick  class memory_resource;
2446035553Spatrick
2546035553Spatrick  bool operator==(const memory_resource& a,
2646035553Spatrick                  const memory_resource& b) noexcept;
2746035553Spatrick  bool operator!=(const memory_resource& a,
2846035553Spatrick                  const memory_resource& b) noexcept;
2946035553Spatrick
3046035553Spatrick  template <class Tp> class polymorphic_allocator;
3146035553Spatrick
3246035553Spatrick  template <class T1, class T2>
3346035553Spatrick  bool operator==(const polymorphic_allocator<T1>& a,
3446035553Spatrick                  const polymorphic_allocator<T2>& b) noexcept;
3546035553Spatrick  template <class T1, class T2>
3646035553Spatrick  bool operator!=(const polymorphic_allocator<T1>& a,
3746035553Spatrick                  const polymorphic_allocator<T2>& b) noexcept;
3846035553Spatrick
3946035553Spatrick  // The name resource_adaptor_imp is for exposition only.
4046035553Spatrick  template <class Allocator> class resource_adaptor_imp;
4146035553Spatrick
4246035553Spatrick  template <class Allocator>
4346035553Spatrick    using resource_adaptor = resource_adaptor_imp<
4446035553Spatrick      allocator_traits<Allocator>::rebind_alloc<char>>;
4546035553Spatrick
4646035553Spatrick  // Global memory resources
4746035553Spatrick  memory_resource* new_delete_resource() noexcept;
4846035553Spatrick  memory_resource* null_memory_resource() noexcept;
4946035553Spatrick
5046035553Spatrick  // The default memory resource
5146035553Spatrick  memory_resource* set_default_resource(memory_resource* r) noexcept;
5246035553Spatrick  memory_resource* get_default_resource() noexcept;
5346035553Spatrick
5446035553Spatrick  // Standard memory resources
5546035553Spatrick  struct pool_options;
5646035553Spatrick  class synchronized_pool_resource;
5746035553Spatrick  class unsynchronized_pool_resource;
5846035553Spatrick  class monotonic_buffer_resource;
5946035553Spatrick
6046035553Spatrick} // namespace pmr
6146035553Spatrick} // namespace fundamentals_v1
6246035553Spatrick} // namespace experimental
6346035553Spatrick} // namespace std
6446035553Spatrick
6546035553Spatrick */
6646035553Spatrick
67*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler
68*4bdff4beSrobert#include <__memory/allocator_traits.h>
69*4bdff4beSrobert#include <__utility/move.h>
70*4bdff4beSrobert#include <cstddef>
71*4bdff4beSrobert#include <cstdlib>
7246035553Spatrick#include <experimental/__config>
7346035553Spatrick#include <experimental/__memory>
7446035553Spatrick#include <limits>
7546035553Spatrick#include <new>
7646035553Spatrick#include <stdexcept>
77*4bdff4beSrobert#include <tuple>
7846035553Spatrick#include <type_traits>
7946035553Spatrick
8046035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
8146035553Spatrick#  pragma GCC system_header
8246035553Spatrick#endif
8346035553Spatrick
8446035553Spatrick_LIBCPP_PUSH_MACROS
8546035553Spatrick#include <__undef_macros>
8646035553Spatrick
8746035553Spatrick_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR
8846035553Spatrick
89*4bdff4beSrobert#define _LIBCPP_DEPCREATED_MEMORY_RESOURCE(name)                                                                       \
90*4bdff4beSrobert  _LIBCPP_DEPRECATED_("'std::experimental::pmr::" name                                                                 \
91*4bdff4beSrobert                      "' is deprecated and will be removed in LLVM 18. Use 'std::pmr::" name "' instead.")
92*4bdff4beSrobert
93*4bdff4beSrobert#ifndef _LIBCPP_CXX03_LANG
94*4bdff4beSrobert
9546035553Spatrick// Round __s up to next multiple of __a.
9646035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
9746035553Spatricksize_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT
9846035553Spatrick{
9946035553Spatrick    _LIBCPP_ASSERT(__s + __a > __s, "aligned allocation size overflows");
10046035553Spatrick    return (__s + __a - 1) & ~(__a - 1);
10146035553Spatrick}
10246035553Spatrick
10346035553Spatrick// 8.5, memory.resource
104*4bdff4beSrobertclass _LIBCPP_DEPCREATED_MEMORY_RESOURCE("memory_resource") _LIBCPP_TYPE_VIS memory_resource
10546035553Spatrick{
10646035553Spatrick    static const size_t __max_align = _LIBCPP_ALIGNOF(max_align_t);
10746035553Spatrick
10846035553Spatrick// 8.5.2, memory.resource.public
10946035553Spatrickpublic:
11046035553Spatrick    virtual ~memory_resource() = default;
11146035553Spatrick
11246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
11346035553Spatrick    void* allocate(size_t __bytes, size_t __align = __max_align)
11446035553Spatrick        { return do_allocate(__bytes, __align); }
11546035553Spatrick
11646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
11746035553Spatrick    void deallocate(void * __p, size_t __bytes, size_t __align = __max_align)
11846035553Spatrick        { do_deallocate(__p, __bytes, __align); }
11946035553Spatrick
12046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
12146035553Spatrick    bool is_equal(memory_resource const & __other) const _NOEXCEPT
12246035553Spatrick        { return do_is_equal(__other); }
12346035553Spatrick
12446035553Spatrick// 8.5.3, memory.resource.priv
12576d0caaeSpatrickprivate:
12646035553Spatrick    virtual void* do_allocate(size_t, size_t) = 0;
12746035553Spatrick    virtual void do_deallocate(void*, size_t, size_t) = 0;
12846035553Spatrick    virtual bool do_is_equal(memory_resource const &) const _NOEXCEPT = 0;
12946035553Spatrick};
13046035553Spatrick
13146035553Spatrick// 8.5.4, memory.resource.eq
132*4bdff4beSrobert_LIBCPP_DEPCREATED_MEMORY_RESOURCE("operator==(memory_resource, memory_resource)") inline _LIBCPP_INLINE_VISIBILITY
13346035553Spatrickbool operator==(memory_resource const & __lhs,
13446035553Spatrick                memory_resource const & __rhs) _NOEXCEPT
13546035553Spatrick{
13646035553Spatrick    return &__lhs == &__rhs || __lhs.is_equal(__rhs);
13746035553Spatrick}
13846035553Spatrick
139*4bdff4beSrobert_LIBCPP_DEPCREATED_MEMORY_RESOURCE("operator!=(memory_resource, memory_resource)") inline _LIBCPP_INLINE_VISIBILITY
14046035553Spatrickbool operator!=(memory_resource const & __lhs,
14146035553Spatrick                memory_resource const & __rhs) _NOEXCEPT
14246035553Spatrick{
14346035553Spatrick    return !(__lhs == __rhs);
14446035553Spatrick}
14546035553Spatrick
146*4bdff4beSrobert_LIBCPP_DEPCREATED_MEMORY_RESOURCE("new_delete_resource()") _LIBCPP_FUNC_VIS
14746035553Spatrickmemory_resource * new_delete_resource() _NOEXCEPT;
14846035553Spatrick
149*4bdff4beSrobert_LIBCPP_DEPCREATED_MEMORY_RESOURCE("null_memory_resource()") _LIBCPP_FUNC_VIS
15046035553Spatrickmemory_resource * null_memory_resource() _NOEXCEPT;
15146035553Spatrick
152*4bdff4beSrobert_LIBCPP_DEPCREATED_MEMORY_RESOURCE("get_default_resource()") _LIBCPP_FUNC_VIS
15346035553Spatrickmemory_resource * get_default_resource() _NOEXCEPT;
15446035553Spatrick
155*4bdff4beSrobert_LIBCPP_DEPCREATED_MEMORY_RESOURCE("set_default_resource()") _LIBCPP_FUNC_VIS
15646035553Spatrickmemory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT;
15746035553Spatrick
15846035553Spatrick// 8.6, memory.polymorphic.allocator.class
15946035553Spatrick
16046035553Spatrick// 8.6.1, memory.polymorphic.allocator.overview
16146035553Spatricktemplate <class _ValueType>
162*4bdff4beSrobertclass _LIBCPP_DEPCREATED_MEMORY_RESOURCE("polymorphic_allocator") _LIBCPP_TEMPLATE_VIS polymorphic_allocator
16346035553Spatrick{
16446035553Spatrickpublic:
16546035553Spatrick    typedef _ValueType value_type;
16646035553Spatrick
16746035553Spatrick    // 8.6.2, memory.polymorphic.allocator.ctor
16846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
16946035553Spatrick    polymorphic_allocator() _NOEXCEPT
17046035553Spatrick      : __res_(_VSTD_LFTS_PMR::get_default_resource())
17146035553Spatrick    {}
17246035553Spatrick
17346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
17446035553Spatrick    polymorphic_allocator(memory_resource * __r) _NOEXCEPT
17546035553Spatrick      : __res_(__r)
17646035553Spatrick    {}
17746035553Spatrick
17846035553Spatrick    polymorphic_allocator(polymorphic_allocator const &) = default;
17946035553Spatrick
18046035553Spatrick    template <class _Tp>
18146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
18246035553Spatrick    polymorphic_allocator(polymorphic_allocator<_Tp> const & __other) _NOEXCEPT
18346035553Spatrick      : __res_(__other.resource())
18446035553Spatrick    {}
18546035553Spatrick
18646035553Spatrick    polymorphic_allocator &
18746035553Spatrick    operator=(polymorphic_allocator const &) = delete;
18846035553Spatrick
18946035553Spatrick    // 8.6.3, memory.polymorphic.allocator.mem
19046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
19146035553Spatrick    _ValueType* allocate(size_t __n) {
192*4bdff4beSrobert        if (__n > __max_size())
193*4bdff4beSrobert            __throw_bad_array_new_length();
19446035553Spatrick        return static_cast<_ValueType*>(
19546035553Spatrick            __res_->allocate(__n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType))
19646035553Spatrick        );
19746035553Spatrick    }
19846035553Spatrick
19946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
20046035553Spatrick    void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT {
20146035553Spatrick        _LIBCPP_ASSERT(__n <= __max_size(),
20246035553Spatrick                       "deallocate called for size which exceeds max_size()");
20346035553Spatrick        __res_->deallocate(__p, __n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType));
20446035553Spatrick    }
20546035553Spatrick
20646035553Spatrick    template <class _Tp, class ..._Ts>
20746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
20846035553Spatrick    void construct(_Tp* __p, _Ts &&... __args)
20946035553Spatrick    {
21046035553Spatrick        _VSTD_LFTS::__lfts_user_alloc_construct(
21146035553Spatrick            __p, *this, _VSTD::forward<_Ts>(__args)...
21246035553Spatrick          );
21346035553Spatrick    }
21446035553Spatrick
21546035553Spatrick    template <class _T1, class _T2, class ..._Args1, class ..._Args2>
21646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
21746035553Spatrick    void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
21846035553Spatrick                   tuple<_Args1...> __x, tuple<_Args2...> __y)
21946035553Spatrick    {
22046035553Spatrick        ::new ((void*)__p) pair<_T1, _T2>(piecewise_construct
22146035553Spatrick          , __transform_tuple(
22246035553Spatrick              typename __lfts_uses_alloc_ctor<
22346035553Spatrick                  _T1, polymorphic_allocator&, _Args1...
22446035553Spatrick              >::type()
22546035553Spatrick            , _VSTD::move(__x)
22646035553Spatrick            , typename __make_tuple_indices<sizeof...(_Args1)>::type{}
22746035553Spatrick          )
22846035553Spatrick          , __transform_tuple(
22946035553Spatrick              typename __lfts_uses_alloc_ctor<
23046035553Spatrick                  _T2, polymorphic_allocator&, _Args2...
23146035553Spatrick              >::type()
23246035553Spatrick            , _VSTD::move(__y)
23346035553Spatrick            , typename __make_tuple_indices<sizeof...(_Args2)>::type{}
23446035553Spatrick          )
23546035553Spatrick        );
23646035553Spatrick    }
23746035553Spatrick
23846035553Spatrick    template <class _T1, class _T2>
23946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
24046035553Spatrick    void construct(pair<_T1, _T2>* __p) {
24146035553Spatrick        construct(__p, piecewise_construct, tuple<>(), tuple<>());
24246035553Spatrick    }
24346035553Spatrick
24446035553Spatrick    template <class _T1, class _T2, class _Up, class _Vp>
24546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
24646035553Spatrick    void construct(pair<_T1, _T2> * __p, _Up && __u, _Vp && __v) {
24746035553Spatrick        construct(__p, piecewise_construct
24846035553Spatrick          , _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__u))
24946035553Spatrick          , _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__v)));
25046035553Spatrick    }
25146035553Spatrick
25246035553Spatrick    template <class _T1, class _T2, class _U1, class _U2>
25346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
25446035553Spatrick    void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> const & __pr) {
25546035553Spatrick        construct(__p, piecewise_construct
25646035553Spatrick            , _VSTD::forward_as_tuple(__pr.first)
25746035553Spatrick            , _VSTD::forward_as_tuple(__pr.second));
25846035553Spatrick    }
25946035553Spatrick
26046035553Spatrick    template <class _T1, class _T2, class _U1, class _U2>
26146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
26246035553Spatrick    void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> && __pr){
26346035553Spatrick        construct(__p, piecewise_construct
26446035553Spatrick            , _VSTD::forward_as_tuple(_VSTD::forward<_U1>(__pr.first))
26546035553Spatrick            , _VSTD::forward_as_tuple(_VSTD::forward<_U2>(__pr.second)));
26646035553Spatrick    }
26746035553Spatrick
26846035553Spatrick    template <class _Tp>
26946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
27046035553Spatrick    void destroy(_Tp * __p) _NOEXCEPT
27146035553Spatrick        { __p->~_Tp(); }
27246035553Spatrick
27346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
27446035553Spatrick    polymorphic_allocator
27546035553Spatrick    select_on_container_copy_construction() const _NOEXCEPT
27646035553Spatrick        { return polymorphic_allocator(); }
27746035553Spatrick
27846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
27946035553Spatrick    memory_resource * resource() const _NOEXCEPT
28046035553Spatrick        { return __res_; }
28146035553Spatrick
28246035553Spatrickprivate:
28346035553Spatrick    template <class ..._Args, size_t ..._Idx>
28446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
28546035553Spatrick    tuple<_Args&&...>
28646035553Spatrick    __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t,
28746035553Spatrick                      __tuple_indices<_Idx...>) const
28846035553Spatrick    {
28946035553Spatrick        return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...);
29046035553Spatrick    }
29146035553Spatrick
29246035553Spatrick    template <class ..._Args, size_t ..._Idx>
29346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
29446035553Spatrick    tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...>
29546035553Spatrick    __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t,
29646035553Spatrick                      __tuple_indices<_Idx...>)
29746035553Spatrick    {
29846035553Spatrick        using _Tup = tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...>;
29946035553Spatrick        return _Tup(allocator_arg, *this,
30046035553Spatrick                    _VSTD::get<_Idx>(_VSTD::move(__t))...);
30146035553Spatrick    }
30246035553Spatrick
30346035553Spatrick    template <class ..._Args, size_t ..._Idx>
30446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
30546035553Spatrick    tuple<_Args&&..., polymorphic_allocator&>
30646035553Spatrick    __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t,
30746035553Spatrick                      __tuple_indices<_Idx...>)
30846035553Spatrick    {
30946035553Spatrick        using _Tup = tuple<_Args&&..., polymorphic_allocator&>;
31046035553Spatrick        return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., *this);
31146035553Spatrick    }
31246035553Spatrick
31346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
31446035553Spatrick    size_t __max_size() const _NOEXCEPT
31546035553Spatrick        { return numeric_limits<size_t>::max() / sizeof(value_type); }
31646035553Spatrick
31746035553Spatrick    memory_resource * __res_;
31846035553Spatrick};
31946035553Spatrick
32046035553Spatrick// 8.6.4, memory.polymorphic.allocator.eq
32146035553Spatrick
32246035553Spatricktemplate <class _Tp, class _Up>
323*4bdff4beSrobert_LIBCPP_DEPCREATED_MEMORY_RESOURCE("operator==(const polymorphic_allocator&, const polymorphic_allocator&)")
32446035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
32546035553Spatrickbool operator==(polymorphic_allocator<_Tp> const & __lhs,
32646035553Spatrick                polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT
32746035553Spatrick{
32846035553Spatrick    return *__lhs.resource() == *__rhs.resource();
32946035553Spatrick}
33046035553Spatrick
33146035553Spatricktemplate <class _Tp, class _Up>
332*4bdff4beSrobert_LIBCPP_DEPCREATED_MEMORY_RESOURCE("operator!=(const polymorphic_allocator&, const polymorphic_allocator&)")
33346035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
33446035553Spatrickbool operator!=(polymorphic_allocator<_Tp> const & __lhs,
33546035553Spatrick                polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT
33646035553Spatrick{
33746035553Spatrick    return !(__lhs == __rhs);
33846035553Spatrick}
33946035553Spatrick
34046035553Spatrick// 8.7, memory.resource.adaptor
34146035553Spatrick
342*4bdff4beSrobert_LIBCPP_SUPPRESS_DEPRECATED_PUSH
34346035553Spatrick// 8.7.1, memory.resource.adaptor.overview
34446035553Spatricktemplate <class _CharAlloc>
34546035553Spatrickclass _LIBCPP_TEMPLATE_VIS __resource_adaptor_imp
34646035553Spatrick  : public memory_resource
34746035553Spatrick{
34846035553Spatrick    using _CTraits = allocator_traits<_CharAlloc>;
34946035553Spatrick    static_assert(is_same<typename _CTraits::value_type, char>::value
35046035553Spatrick               && is_same<typename _CTraits::pointer, char*>::value
35146035553Spatrick               && is_same<typename _CTraits::void_pointer, void*>::value, "");
35246035553Spatrick
35346035553Spatrick    static const size_t _MaxAlign = _LIBCPP_ALIGNOF(max_align_t);
35446035553Spatrick
35546035553Spatrick    using _Alloc = typename _CTraits::template rebind_alloc<
35646035553Spatrick            typename aligned_storage<_MaxAlign, _MaxAlign>::type
35746035553Spatrick        >;
35846035553Spatrick
35946035553Spatrick    using _ValueType = typename _Alloc::value_type;
36046035553Spatrick
36146035553Spatrick    _Alloc __alloc_;
36246035553Spatrick
36346035553Spatrickpublic:
36446035553Spatrick    typedef _CharAlloc allocator_type;
36546035553Spatrick
36646035553Spatrick    __resource_adaptor_imp() = default;
36746035553Spatrick    __resource_adaptor_imp(__resource_adaptor_imp const &) = default;
36846035553Spatrick    __resource_adaptor_imp(__resource_adaptor_imp &&) = default;
36946035553Spatrick
37046035553Spatrick    // 8.7.2, memory.resource.adaptor.ctor
37146035553Spatrick
37246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
37346035553Spatrick    explicit __resource_adaptor_imp(allocator_type const & __a)
37446035553Spatrick      : __alloc_(__a)
37546035553Spatrick    {}
37646035553Spatrick
37746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
37846035553Spatrick    explicit __resource_adaptor_imp(allocator_type && __a)
37946035553Spatrick      : __alloc_(_VSTD::move(__a))
38046035553Spatrick    {}
38146035553Spatrick
38246035553Spatrick    __resource_adaptor_imp &
38346035553Spatrick    operator=(__resource_adaptor_imp const &) = default;
38446035553Spatrick
38546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
38646035553Spatrick    allocator_type get_allocator() const
38746035553Spatrick    { return __alloc_; }
38846035553Spatrick
38946035553Spatrick// 8.7.3, memory.resource.adaptor.mem
39076d0caaeSpatrickprivate:
391*4bdff4beSrobert    void * do_allocate(size_t __bytes, size_t) override
39246035553Spatrick    {
393*4bdff4beSrobert        if (__bytes > __max_size())
394*4bdff4beSrobert            __throw_bad_array_new_length();
39546035553Spatrick        size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign;
39646035553Spatrick        return __alloc_.allocate(__s);
39746035553Spatrick    }
39846035553Spatrick
399*4bdff4beSrobert    void do_deallocate(void * __p, size_t __bytes, size_t) override
40046035553Spatrick    {
40146035553Spatrick        _LIBCPP_ASSERT(__bytes <= __max_size(),
40246035553Spatrick            "do_deallocate called for size which exceeds the maximum allocation size");
40346035553Spatrick        size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign;
40446035553Spatrick        __alloc_.deallocate((_ValueType*)__p, __s);
40546035553Spatrick    }
40646035553Spatrick
407*4bdff4beSrobert    bool do_is_equal(memory_resource const & __other) const _NOEXCEPT override {
40846035553Spatrick        __resource_adaptor_imp const * __p
40946035553Spatrick          = dynamic_cast<__resource_adaptor_imp const *>(&__other);
41046035553Spatrick        return __p  ? __alloc_ == __p->__alloc_ : false;
41146035553Spatrick    }
41246035553Spatrick
41346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
41446035553Spatrick    size_t __max_size() const _NOEXCEPT {
41546035553Spatrick        return numeric_limits<size_t>::max() - _MaxAlign;
41646035553Spatrick    }
41746035553Spatrick};
41846035553Spatrick
41946035553Spatricktemplate <class _Alloc>
42046035553Spatrickusing resource_adaptor = __resource_adaptor_imp<
42146035553Spatrick    typename allocator_traits<_Alloc>::template rebind_alloc<char>
42246035553Spatrick  >;
423*4bdff4beSrobert_LIBCPP_SUPPRESS_DEPRECATED_POP
424*4bdff4beSrobert
425*4bdff4beSrobert#endif // _LIBCPP_CXX03_LANG
42646035553Spatrick
42746035553Spatrick_LIBCPP_END_NAMESPACE_LFTS_PMR
42846035553Spatrick
42946035553Spatrick_LIBCPP_POP_MACROS
43046035553Spatrick
431*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
432*4bdff4beSrobert#  include <atomic>
433*4bdff4beSrobert#  include <climits>
434*4bdff4beSrobert#  include <concepts>
435*4bdff4beSrobert#  include <cstring>
436*4bdff4beSrobert#  include <ctime>
437*4bdff4beSrobert#  include <iterator>
438*4bdff4beSrobert#  include <memory>
439*4bdff4beSrobert#  include <ratio>
440*4bdff4beSrobert#  include <variant>
441*4bdff4beSrobert#endif
442*4bdff4beSrobert
44346035553Spatrick#endif /* _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE */
444