115551efdSEric Fiselier// -*- C++ -*- 2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===// 315551efdSEric Fiselier// 42946cd70SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 52946cd70SChandler Carruth// See https://llvm.org/LICENSE.txt for license information. 62946cd70SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 715551efdSEric Fiselier// 815551efdSEric Fiselier//===----------------------------------------------------------------------===// 915551efdSEric Fiselier 1015551efdSEric Fiselier#ifndef _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE 1115551efdSEric Fiselier#define _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE 1215551efdSEric Fiselier 1315551efdSEric Fiselier/** 1415551efdSEric Fiselier experimental/memory_resource synopsis 1515551efdSEric Fiselier 1615551efdSEric Fiselier// C++1y 1715551efdSEric Fiselier 1815551efdSEric Fiseliernamespace std { 1915551efdSEric Fiseliernamespace experimental { 2015551efdSEric Fiselierinline namespace fundamentals_v1 { 2115551efdSEric Fiseliernamespace pmr { 2215551efdSEric Fiselier 2315551efdSEric Fiselier class memory_resource; 2415551efdSEric Fiselier 2515551efdSEric Fiselier bool operator==(const memory_resource& a, 2615551efdSEric Fiselier const memory_resource& b) noexcept; 2715551efdSEric Fiselier bool operator!=(const memory_resource& a, 2815551efdSEric Fiselier const memory_resource& b) noexcept; 2915551efdSEric Fiselier 3015551efdSEric Fiselier template <class Tp> class polymorphic_allocator; 3115551efdSEric Fiselier 3215551efdSEric Fiselier template <class T1, class T2> 3315551efdSEric Fiselier bool operator==(const polymorphic_allocator<T1>& a, 3415551efdSEric Fiselier const polymorphic_allocator<T2>& b) noexcept; 3515551efdSEric Fiselier template <class T1, class T2> 3615551efdSEric Fiselier bool operator!=(const polymorphic_allocator<T1>& a, 3715551efdSEric Fiselier const polymorphic_allocator<T2>& b) noexcept; 3815551efdSEric Fiselier 3915551efdSEric Fiselier // The name resource_adaptor_imp is for exposition only. 4015551efdSEric Fiselier template <class Allocator> class resource_adaptor_imp; 4115551efdSEric Fiselier 4215551efdSEric Fiselier template <class Allocator> 4315551efdSEric Fiselier using resource_adaptor = resource_adaptor_imp< 4415551efdSEric Fiselier allocator_traits<Allocator>::rebind_alloc<char>>; 4515551efdSEric Fiselier 4615551efdSEric Fiselier // Global memory resources 4715551efdSEric Fiselier memory_resource* new_delete_resource() noexcept; 4815551efdSEric Fiselier memory_resource* null_memory_resource() noexcept; 4915551efdSEric Fiselier 5015551efdSEric Fiselier // The default memory resource 5115551efdSEric Fiselier memory_resource* set_default_resource(memory_resource* r) noexcept; 5215551efdSEric Fiselier memory_resource* get_default_resource() noexcept; 5315551efdSEric Fiselier 5415551efdSEric Fiselier // Standard memory resources 5515551efdSEric Fiselier struct pool_options; 5615551efdSEric Fiselier class synchronized_pool_resource; 5715551efdSEric Fiselier class unsynchronized_pool_resource; 5815551efdSEric Fiselier class monotonic_buffer_resource; 5915551efdSEric Fiselier 6015551efdSEric Fiselier} // namespace pmr 6115551efdSEric Fiselier} // namespace fundamentals_v1 6215551efdSEric Fiselier} // namespace experimental 6315551efdSEric Fiselier} // namespace std 6415551efdSEric Fiselier 6515551efdSEric Fiselier */ 6615551efdSEric Fiselier 67*385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler 684d81a46fSArthur O'Dwyer#include <__tuple> 6952915d78SNikolas Klauser#include <__utility/move.h> 704d81a46fSArthur O'Dwyer#include <cstddef> 714d81a46fSArthur O'Dwyer#include <cstdlib> 7215551efdSEric Fiselier#include <experimental/__config> 7315551efdSEric Fiselier#include <experimental/__memory> 7415551efdSEric Fiselier#include <limits> 7515551efdSEric Fiselier#include <memory> 7615551efdSEric Fiselier#include <new> 7715551efdSEric Fiselier#include <stdexcept> 7815551efdSEric Fiselier#include <type_traits> 7952915d78SNikolas Klauser 8015551efdSEric Fiselier#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 8115551efdSEric Fiselier# pragma GCC system_header 8215551efdSEric Fiselier#endif 8315551efdSEric Fiselier 84a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS 85a016efb1SEric Fiselier#include <__undef_macros> 86a016efb1SEric Fiselier 8715551efdSEric Fiselier_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR 8815551efdSEric Fiselier 89b66754a2SBrian Gesiak// Round __s up to next multiple of __a. 90b66754a2SBrian Gesiakinline _LIBCPP_INLINE_VISIBILITY 91b66754a2SBrian Gesiaksize_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT 92b66754a2SBrian Gesiak{ 93b66754a2SBrian Gesiak _LIBCPP_ASSERT(__s + __a > __s, "aligned allocation size overflows"); 94b66754a2SBrian Gesiak return (__s + __a - 1) & ~(__a - 1); 95b66754a2SBrian Gesiak} 96b66754a2SBrian Gesiak 9715551efdSEric Fiselier// 8.5, memory.resource 98cb5b004aSEric Fiselierclass _LIBCPP_TYPE_VIS memory_resource 9915551efdSEric Fiselier{ 100d108bf85SEric Fiselier static const size_t __max_align = _LIBCPP_ALIGNOF(max_align_t); 10115551efdSEric Fiselier 10215551efdSEric Fiselier// 8.5.2, memory.resource.public 10315551efdSEric Fiselierpublic: 10415551efdSEric Fiselier virtual ~memory_resource() = default; 10515551efdSEric Fiselier 10615551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 10715551efdSEric Fiselier void* allocate(size_t __bytes, size_t __align = __max_align) 10815551efdSEric Fiselier { return do_allocate(__bytes, __align); } 10915551efdSEric Fiselier 11015551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 11115551efdSEric Fiselier void deallocate(void * __p, size_t __bytes, size_t __align = __max_align) 11215551efdSEric Fiselier { do_deallocate(__p, __bytes, __align); } 11315551efdSEric Fiselier 11415551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 11515551efdSEric Fiselier bool is_equal(memory_resource const & __other) const _NOEXCEPT 11615551efdSEric Fiselier { return do_is_equal(__other); } 11715551efdSEric Fiselier 11815551efdSEric Fiselier// 8.5.3, memory.resource.priv 1190a20660cSzoecarverprivate: 12015551efdSEric Fiselier virtual void* do_allocate(size_t, size_t) = 0; 12115551efdSEric Fiselier virtual void do_deallocate(void*, size_t, size_t) = 0; 12215551efdSEric Fiselier virtual bool do_is_equal(memory_resource const &) const _NOEXCEPT = 0; 12315551efdSEric Fiselier}; 12415551efdSEric Fiselier 12515551efdSEric Fiselier// 8.5.4, memory.resource.eq 12615551efdSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 12715551efdSEric Fiselierbool operator==(memory_resource const & __lhs, 12815551efdSEric Fiselier memory_resource const & __rhs) _NOEXCEPT 12915551efdSEric Fiselier{ 13015551efdSEric Fiselier return &__lhs == &__rhs || __lhs.is_equal(__rhs); 13115551efdSEric Fiselier} 13215551efdSEric Fiselier 13315551efdSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 13415551efdSEric Fiselierbool operator!=(memory_resource const & __lhs, 13515551efdSEric Fiselier memory_resource const & __rhs) _NOEXCEPT 13615551efdSEric Fiselier{ 13715551efdSEric Fiselier return !(__lhs == __rhs); 13815551efdSEric Fiselier} 13915551efdSEric Fiselier 14015551efdSEric Fiselier_LIBCPP_FUNC_VIS 14115551efdSEric Fiseliermemory_resource * new_delete_resource() _NOEXCEPT; 14215551efdSEric Fiselier 14315551efdSEric Fiselier_LIBCPP_FUNC_VIS 14415551efdSEric Fiseliermemory_resource * null_memory_resource() _NOEXCEPT; 14515551efdSEric Fiselier 14615551efdSEric Fiselier_LIBCPP_FUNC_VIS 14715551efdSEric Fiseliermemory_resource * get_default_resource() _NOEXCEPT; 14815551efdSEric Fiselier 14915551efdSEric Fiselier_LIBCPP_FUNC_VIS 15015551efdSEric Fiseliermemory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT; 15115551efdSEric Fiselier 15215551efdSEric Fiselier// 8.6, memory.polymorphic.allocator.class 15315551efdSEric Fiselier 15415551efdSEric Fiselier// 8.6.1, memory.polymorphic.allocator.overview 15515551efdSEric Fiseliertemplate <class _ValueType> 156e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS polymorphic_allocator 15715551efdSEric Fiselier{ 15815551efdSEric Fiselierpublic: 15915551efdSEric Fiselier typedef _ValueType value_type; 16015551efdSEric Fiselier 16115551efdSEric Fiselier // 8.6.2, memory.polymorphic.allocator.ctor 16215551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 16315551efdSEric Fiselier polymorphic_allocator() _NOEXCEPT 16415551efdSEric Fiselier : __res_(_VSTD_LFTS_PMR::get_default_resource()) 16515551efdSEric Fiselier {} 16615551efdSEric Fiselier 16715551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 16815551efdSEric Fiselier polymorphic_allocator(memory_resource * __r) _NOEXCEPT 16915551efdSEric Fiselier : __res_(__r) 17015551efdSEric Fiselier {} 17115551efdSEric Fiselier 17215551efdSEric Fiselier polymorphic_allocator(polymorphic_allocator const &) = default; 17315551efdSEric Fiselier 17415551efdSEric Fiselier template <class _Tp> 17515551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 17615551efdSEric Fiselier polymorphic_allocator(polymorphic_allocator<_Tp> const & __other) _NOEXCEPT 17715551efdSEric Fiselier : __res_(__other.resource()) 17815551efdSEric Fiselier {} 17915551efdSEric Fiselier 18015551efdSEric Fiselier polymorphic_allocator & 1818b7faa68SEric Fiselier operator=(polymorphic_allocator const &) = delete; 18215551efdSEric Fiselier 18315551efdSEric Fiselier // 8.6.3, memory.polymorphic.allocator.mem 18415551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 18515551efdSEric Fiselier _ValueType* allocate(size_t __n) { 186be10b1f1SMikhail Maltsev if (__n > __max_size()) 187be10b1f1SMikhail Maltsev __throw_bad_array_new_length(); 18815551efdSEric Fiselier return static_cast<_ValueType*>( 189d108bf85SEric Fiselier __res_->allocate(__n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType)) 19015551efdSEric Fiselier ); 19115551efdSEric Fiselier } 19215551efdSEric Fiselier 19315551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 19415551efdSEric Fiselier void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT { 19525f9f927SEric Fiselier _LIBCPP_ASSERT(__n <= __max_size(), 19615551efdSEric Fiselier "deallocate called for size which exceeds max_size()"); 197d108bf85SEric Fiselier __res_->deallocate(__p, __n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType)); 19815551efdSEric Fiselier } 19915551efdSEric Fiselier 20015551efdSEric Fiselier template <class _Tp, class ..._Ts> 20115551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 20215551efdSEric Fiselier void construct(_Tp* __p, _Ts &&... __args) 20315551efdSEric Fiselier { 20415551efdSEric Fiselier _VSTD_LFTS::__lfts_user_alloc_construct( 205bd2e9498SEric Fiselier __p, *this, _VSTD::forward<_Ts>(__args)... 20615551efdSEric Fiselier ); 20715551efdSEric Fiselier } 20815551efdSEric Fiselier 20915551efdSEric Fiselier template <class _T1, class _T2, class ..._Args1, class ..._Args2> 21015551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 21115551efdSEric Fiselier void construct(pair<_T1, _T2>* __p, piecewise_construct_t, 21215551efdSEric Fiselier tuple<_Args1...> __x, tuple<_Args2...> __y) 21315551efdSEric Fiselier { 21415551efdSEric Fiselier ::new ((void*)__p) pair<_T1, _T2>(piecewise_construct 21515551efdSEric Fiselier , __transform_tuple( 21615551efdSEric Fiselier typename __lfts_uses_alloc_ctor< 217bd2e9498SEric Fiselier _T1, polymorphic_allocator&, _Args1... 21815551efdSEric Fiselier >::type() 21915551efdSEric Fiselier , _VSTD::move(__x) 22015551efdSEric Fiselier , typename __make_tuple_indices<sizeof...(_Args1)>::type{} 22115551efdSEric Fiselier ) 22215551efdSEric Fiselier , __transform_tuple( 22315551efdSEric Fiselier typename __lfts_uses_alloc_ctor< 224bd2e9498SEric Fiselier _T2, polymorphic_allocator&, _Args2... 22515551efdSEric Fiselier >::type() 22615551efdSEric Fiselier , _VSTD::move(__y) 22715551efdSEric Fiselier , typename __make_tuple_indices<sizeof...(_Args2)>::type{} 22815551efdSEric Fiselier ) 22915551efdSEric Fiselier ); 23015551efdSEric Fiselier } 23115551efdSEric Fiselier 23215551efdSEric Fiselier template <class _T1, class _T2> 23315551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 23415551efdSEric Fiselier void construct(pair<_T1, _T2>* __p) { 23515551efdSEric Fiselier construct(__p, piecewise_construct, tuple<>(), tuple<>()); 23615551efdSEric Fiselier } 23715551efdSEric Fiselier 23815551efdSEric Fiselier template <class _T1, class _T2, class _Up, class _Vp> 23915551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 24015551efdSEric Fiselier void construct(pair<_T1, _T2> * __p, _Up && __u, _Vp && __v) { 24115551efdSEric Fiselier construct(__p, piecewise_construct 24215551efdSEric Fiselier , _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__u)) 24315551efdSEric Fiselier , _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__v))); 24415551efdSEric Fiselier } 24515551efdSEric Fiselier 24615551efdSEric Fiselier template <class _T1, class _T2, class _U1, class _U2> 24715551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 24815551efdSEric Fiselier void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> const & __pr) { 24915551efdSEric Fiselier construct(__p, piecewise_construct 25015551efdSEric Fiselier , _VSTD::forward_as_tuple(__pr.first) 25115551efdSEric Fiselier , _VSTD::forward_as_tuple(__pr.second)); 25215551efdSEric Fiselier } 25315551efdSEric Fiselier 25415551efdSEric Fiselier template <class _T1, class _T2, class _U1, class _U2> 25515551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 25615551efdSEric Fiselier void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> && __pr){ 25715551efdSEric Fiselier construct(__p, piecewise_construct 25815551efdSEric Fiselier , _VSTD::forward_as_tuple(_VSTD::forward<_U1>(__pr.first)) 25915551efdSEric Fiselier , _VSTD::forward_as_tuple(_VSTD::forward<_U2>(__pr.second))); 26015551efdSEric Fiselier } 26115551efdSEric Fiselier 26215551efdSEric Fiselier template <class _Tp> 26315551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 26415551efdSEric Fiselier void destroy(_Tp * __p) _NOEXCEPT 26515551efdSEric Fiselier { __p->~_Tp(); } 26615551efdSEric Fiselier 26715551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 26815551efdSEric Fiselier polymorphic_allocator 26915551efdSEric Fiselier select_on_container_copy_construction() const _NOEXCEPT 27015551efdSEric Fiselier { return polymorphic_allocator(); } 27115551efdSEric Fiselier 27215551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 27315551efdSEric Fiselier memory_resource * resource() const _NOEXCEPT 27415551efdSEric Fiselier { return __res_; } 27515551efdSEric Fiselier 27615551efdSEric Fiselierprivate: 27715551efdSEric Fiselier template <class ..._Args, size_t ..._Idx> 27815551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 27915551efdSEric Fiselier tuple<_Args&&...> 28015551efdSEric Fiselier __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, 28115551efdSEric Fiselier __tuple_indices<_Idx...>) const 28215551efdSEric Fiselier { 28315551efdSEric Fiselier return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...); 28415551efdSEric Fiselier } 28515551efdSEric Fiselier 28615551efdSEric Fiselier template <class ..._Args, size_t ..._Idx> 28715551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 288bd2e9498SEric Fiselier tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...> 28915551efdSEric Fiselier __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t, 290bd2e9498SEric Fiselier __tuple_indices<_Idx...>) 29115551efdSEric Fiselier { 292bd2e9498SEric Fiselier using _Tup = tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...>; 293bd2e9498SEric Fiselier return _Tup(allocator_arg, *this, 29415551efdSEric Fiselier _VSTD::get<_Idx>(_VSTD::move(__t))...); 29515551efdSEric Fiselier } 29615551efdSEric Fiselier 29715551efdSEric Fiselier template <class ..._Args, size_t ..._Idx> 29815551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 299bd2e9498SEric Fiselier tuple<_Args&&..., polymorphic_allocator&> 30015551efdSEric Fiselier __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t, 301bd2e9498SEric Fiselier __tuple_indices<_Idx...>) 30215551efdSEric Fiselier { 303bd2e9498SEric Fiselier using _Tup = tuple<_Args&&..., polymorphic_allocator&>; 304bd2e9498SEric Fiselier return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., *this); 30515551efdSEric Fiselier } 30615551efdSEric Fiselier 30725f9f927SEric Fiselier _LIBCPP_INLINE_VISIBILITY 30825f9f927SEric Fiselier size_t __max_size() const _NOEXCEPT 30925f9f927SEric Fiselier { return numeric_limits<size_t>::max() / sizeof(value_type); } 31025f9f927SEric Fiselier 31115551efdSEric Fiselier memory_resource * __res_; 31215551efdSEric Fiselier}; 31315551efdSEric Fiselier 31415551efdSEric Fiselier// 8.6.4, memory.polymorphic.allocator.eq 31515551efdSEric Fiselier 31615551efdSEric Fiseliertemplate <class _Tp, class _Up> 31715551efdSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 31815551efdSEric Fiselierbool operator==(polymorphic_allocator<_Tp> const & __lhs, 31915551efdSEric Fiselier polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT 32015551efdSEric Fiselier{ 32115551efdSEric Fiselier return *__lhs.resource() == *__rhs.resource(); 32215551efdSEric Fiselier} 32315551efdSEric Fiselier 32415551efdSEric Fiseliertemplate <class _Tp, class _Up> 32515551efdSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 32615551efdSEric Fiselierbool operator!=(polymorphic_allocator<_Tp> const & __lhs, 32715551efdSEric Fiselier polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT 32815551efdSEric Fiselier{ 32915551efdSEric Fiselier return !(__lhs == __rhs); 33015551efdSEric Fiselier} 33115551efdSEric Fiselier 33215551efdSEric Fiselier// 8.7, memory.resource.adaptor 33315551efdSEric Fiselier 33415551efdSEric Fiselier// 8.7.1, memory.resource.adaptor.overview 33515551efdSEric Fiseliertemplate <class _CharAlloc> 336e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __resource_adaptor_imp 33715551efdSEric Fiselier : public memory_resource 33815551efdSEric Fiselier{ 33915551efdSEric Fiselier using _CTraits = allocator_traits<_CharAlloc>; 34015551efdSEric Fiselier static_assert(is_same<typename _CTraits::value_type, char>::value 34115551efdSEric Fiselier && is_same<typename _CTraits::pointer, char*>::value 34215551efdSEric Fiselier && is_same<typename _CTraits::void_pointer, void*>::value, ""); 34315551efdSEric Fiselier 344d108bf85SEric Fiselier static const size_t _MaxAlign = _LIBCPP_ALIGNOF(max_align_t); 34515551efdSEric Fiselier 34615551efdSEric Fiselier using _Alloc = typename _CTraits::template rebind_alloc< 34715551efdSEric Fiselier typename aligned_storage<_MaxAlign, _MaxAlign>::type 34815551efdSEric Fiselier >; 34915551efdSEric Fiselier 35015551efdSEric Fiselier using _ValueType = typename _Alloc::value_type; 35115551efdSEric Fiselier 35215551efdSEric Fiselier _Alloc __alloc_; 35315551efdSEric Fiselier 35415551efdSEric Fiselierpublic: 35515551efdSEric Fiselier typedef _CharAlloc allocator_type; 35615551efdSEric Fiselier 35715551efdSEric Fiselier __resource_adaptor_imp() = default; 35815551efdSEric Fiselier __resource_adaptor_imp(__resource_adaptor_imp const &) = default; 35915551efdSEric Fiselier __resource_adaptor_imp(__resource_adaptor_imp &&) = default; 36015551efdSEric Fiselier 36115551efdSEric Fiselier // 8.7.2, memory.resource.adaptor.ctor 36215551efdSEric Fiselier 36315551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 36415551efdSEric Fiselier explicit __resource_adaptor_imp(allocator_type const & __a) 36515551efdSEric Fiselier : __alloc_(__a) 36615551efdSEric Fiselier {} 36715551efdSEric Fiselier 36815551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 36915551efdSEric Fiselier explicit __resource_adaptor_imp(allocator_type && __a) 37015551efdSEric Fiselier : __alloc_(_VSTD::move(__a)) 37115551efdSEric Fiselier {} 37215551efdSEric Fiselier 37315551efdSEric Fiselier __resource_adaptor_imp & 37415551efdSEric Fiselier operator=(__resource_adaptor_imp const &) = default; 37515551efdSEric Fiselier 37615551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 37715551efdSEric Fiselier allocator_type get_allocator() const 37815551efdSEric Fiselier { return __alloc_; } 37915551efdSEric Fiselier 38015551efdSEric Fiselier// 8.7.3, memory.resource.adaptor.mem 3810a20660cSzoecarverprivate: 38215551efdSEric Fiselier virtual void * do_allocate(size_t __bytes, size_t) 38315551efdSEric Fiselier { 384be10b1f1SMikhail Maltsev if (__bytes > __max_size()) 385be10b1f1SMikhail Maltsev __throw_bad_array_new_length(); 38615551efdSEric Fiselier size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign; 38715551efdSEric Fiselier return __alloc_.allocate(__s); 38815551efdSEric Fiselier } 38915551efdSEric Fiselier 39015551efdSEric Fiselier virtual void do_deallocate(void * __p, size_t __bytes, size_t) 39115551efdSEric Fiselier { 39215551efdSEric Fiselier _LIBCPP_ASSERT(__bytes <= __max_size(), 39315551efdSEric Fiselier "do_deallocate called for size which exceeds the maximum allocation size"); 39415551efdSEric Fiselier size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign; 39515551efdSEric Fiselier __alloc_.deallocate((_ValueType*)__p, __s); 39615551efdSEric Fiselier } 39715551efdSEric Fiselier 39815551efdSEric Fiselier virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT { 39915551efdSEric Fiselier __resource_adaptor_imp const * __p 40015551efdSEric Fiselier = dynamic_cast<__resource_adaptor_imp const *>(&__other); 40115551efdSEric Fiselier return __p ? __alloc_ == __p->__alloc_ : false; 40215551efdSEric Fiselier } 40315551efdSEric Fiselier 40415551efdSEric Fiselier _LIBCPP_INLINE_VISIBILITY 40515551efdSEric Fiselier size_t __max_size() const _NOEXCEPT { 40615551efdSEric Fiselier return numeric_limits<size_t>::max() - _MaxAlign; 40715551efdSEric Fiselier } 40815551efdSEric Fiselier}; 40915551efdSEric Fiselier 41015551efdSEric Fiseliertemplate <class _Alloc> 41115551efdSEric Fiselierusing resource_adaptor = __resource_adaptor_imp< 41215551efdSEric Fiselier typename allocator_traits<_Alloc>::template rebind_alloc<char> 41315551efdSEric Fiselier >; 41415551efdSEric Fiselier 41515551efdSEric Fiselier_LIBCPP_END_NAMESPACE_LFTS_PMR 41615551efdSEric Fiselier 417a016efb1SEric Fiselier_LIBCPP_POP_MACROS 418a016efb1SEric Fiselier 41915551efdSEric Fiselier#endif /* _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE */ 420