1*4d6fc14bSjoerg// -*- C++ -*- 2*4d6fc14bSjoerg//===------------------------ memory_resource -----------------------------===// 3*4d6fc14bSjoerg// 4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information. 6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*4d6fc14bSjoerg// 8*4d6fc14bSjoerg//===----------------------------------------------------------------------===// 9*4d6fc14bSjoerg 10*4d6fc14bSjoerg#ifndef _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE 11*4d6fc14bSjoerg#define _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE 12*4d6fc14bSjoerg 13*4d6fc14bSjoerg/** 14*4d6fc14bSjoerg experimental/memory_resource synopsis 15*4d6fc14bSjoerg 16*4d6fc14bSjoerg// C++1y 17*4d6fc14bSjoerg 18*4d6fc14bSjoergnamespace std { 19*4d6fc14bSjoergnamespace experimental { 20*4d6fc14bSjoerginline namespace fundamentals_v1 { 21*4d6fc14bSjoergnamespace pmr { 22*4d6fc14bSjoerg 23*4d6fc14bSjoerg class memory_resource; 24*4d6fc14bSjoerg 25*4d6fc14bSjoerg bool operator==(const memory_resource& a, 26*4d6fc14bSjoerg const memory_resource& b) noexcept; 27*4d6fc14bSjoerg bool operator!=(const memory_resource& a, 28*4d6fc14bSjoerg const memory_resource& b) noexcept; 29*4d6fc14bSjoerg 30*4d6fc14bSjoerg template <class Tp> class polymorphic_allocator; 31*4d6fc14bSjoerg 32*4d6fc14bSjoerg template <class T1, class T2> 33*4d6fc14bSjoerg bool operator==(const polymorphic_allocator<T1>& a, 34*4d6fc14bSjoerg const polymorphic_allocator<T2>& b) noexcept; 35*4d6fc14bSjoerg template <class T1, class T2> 36*4d6fc14bSjoerg bool operator!=(const polymorphic_allocator<T1>& a, 37*4d6fc14bSjoerg const polymorphic_allocator<T2>& b) noexcept; 38*4d6fc14bSjoerg 39*4d6fc14bSjoerg // The name resource_adaptor_imp is for exposition only. 40*4d6fc14bSjoerg template <class Allocator> class resource_adaptor_imp; 41*4d6fc14bSjoerg 42*4d6fc14bSjoerg template <class Allocator> 43*4d6fc14bSjoerg using resource_adaptor = resource_adaptor_imp< 44*4d6fc14bSjoerg allocator_traits<Allocator>::rebind_alloc<char>>; 45*4d6fc14bSjoerg 46*4d6fc14bSjoerg // Global memory resources 47*4d6fc14bSjoerg memory_resource* new_delete_resource() noexcept; 48*4d6fc14bSjoerg memory_resource* null_memory_resource() noexcept; 49*4d6fc14bSjoerg 50*4d6fc14bSjoerg // The default memory resource 51*4d6fc14bSjoerg memory_resource* set_default_resource(memory_resource* r) noexcept; 52*4d6fc14bSjoerg memory_resource* get_default_resource() noexcept; 53*4d6fc14bSjoerg 54*4d6fc14bSjoerg // Standard memory resources 55*4d6fc14bSjoerg struct pool_options; 56*4d6fc14bSjoerg class synchronized_pool_resource; 57*4d6fc14bSjoerg class unsynchronized_pool_resource; 58*4d6fc14bSjoerg class monotonic_buffer_resource; 59*4d6fc14bSjoerg 60*4d6fc14bSjoerg} // namespace pmr 61*4d6fc14bSjoerg} // namespace fundamentals_v1 62*4d6fc14bSjoerg} // namespace experimental 63*4d6fc14bSjoerg} // namespace std 64*4d6fc14bSjoerg 65*4d6fc14bSjoerg */ 66*4d6fc14bSjoerg 67*4d6fc14bSjoerg#include <experimental/__config> 68*4d6fc14bSjoerg#include <experimental/__memory> 69*4d6fc14bSjoerg#include <limits> 70*4d6fc14bSjoerg#include <memory> 71*4d6fc14bSjoerg#include <new> 72*4d6fc14bSjoerg#include <stdexcept> 73*4d6fc14bSjoerg#include <__tuple> 74*4d6fc14bSjoerg#include <type_traits> 75*4d6fc14bSjoerg#include <utility> 76*4d6fc14bSjoerg#include <cstddef> 77*4d6fc14bSjoerg#include <cstdlib> 78*4d6fc14bSjoerg#include <__debug> 79*4d6fc14bSjoerg 80*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 81*4d6fc14bSjoerg#pragma GCC system_header 82*4d6fc14bSjoerg#endif 83*4d6fc14bSjoerg 84*4d6fc14bSjoerg_LIBCPP_PUSH_MACROS 85*4d6fc14bSjoerg#include <__undef_macros> 86*4d6fc14bSjoerg 87*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR 88*4d6fc14bSjoerg 89*4d6fc14bSjoerg// Round __s up to next multiple of __a. 90*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 91*4d6fc14bSjoergsize_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT 92*4d6fc14bSjoerg{ 93*4d6fc14bSjoerg _LIBCPP_ASSERT(__s + __a > __s, "aligned allocation size overflows"); 94*4d6fc14bSjoerg return (__s + __a - 1) & ~(__a - 1); 95*4d6fc14bSjoerg} 96*4d6fc14bSjoerg 97*4d6fc14bSjoerg// 8.5, memory.resource 98*4d6fc14bSjoergclass _LIBCPP_TYPE_VIS memory_resource 99*4d6fc14bSjoerg{ 100*4d6fc14bSjoerg static const size_t __max_align = _LIBCPP_ALIGNOF(max_align_t); 101*4d6fc14bSjoerg 102*4d6fc14bSjoerg// 8.5.2, memory.resource.public 103*4d6fc14bSjoergpublic: 104*4d6fc14bSjoerg virtual ~memory_resource() = default; 105*4d6fc14bSjoerg 106*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 107*4d6fc14bSjoerg void* allocate(size_t __bytes, size_t __align = __max_align) 108*4d6fc14bSjoerg { return do_allocate(__bytes, __align); } 109*4d6fc14bSjoerg 110*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 111*4d6fc14bSjoerg void deallocate(void * __p, size_t __bytes, size_t __align = __max_align) 112*4d6fc14bSjoerg { do_deallocate(__p, __bytes, __align); } 113*4d6fc14bSjoerg 114*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 115*4d6fc14bSjoerg bool is_equal(memory_resource const & __other) const _NOEXCEPT 116*4d6fc14bSjoerg { return do_is_equal(__other); } 117*4d6fc14bSjoerg 118*4d6fc14bSjoerg// 8.5.3, memory.resource.priv 119*4d6fc14bSjoergprivate: 120*4d6fc14bSjoerg virtual void* do_allocate(size_t, size_t) = 0; 121*4d6fc14bSjoerg virtual void do_deallocate(void*, size_t, size_t) = 0; 122*4d6fc14bSjoerg virtual bool do_is_equal(memory_resource const &) const _NOEXCEPT = 0; 123*4d6fc14bSjoerg}; 124*4d6fc14bSjoerg 125*4d6fc14bSjoerg// 8.5.4, memory.resource.eq 126*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 127*4d6fc14bSjoergbool operator==(memory_resource const & __lhs, 128*4d6fc14bSjoerg memory_resource const & __rhs) _NOEXCEPT 129*4d6fc14bSjoerg{ 130*4d6fc14bSjoerg return &__lhs == &__rhs || __lhs.is_equal(__rhs); 131*4d6fc14bSjoerg} 132*4d6fc14bSjoerg 133*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 134*4d6fc14bSjoergbool operator!=(memory_resource const & __lhs, 135*4d6fc14bSjoerg memory_resource const & __rhs) _NOEXCEPT 136*4d6fc14bSjoerg{ 137*4d6fc14bSjoerg return !(__lhs == __rhs); 138*4d6fc14bSjoerg} 139*4d6fc14bSjoerg 140*4d6fc14bSjoerg_LIBCPP_FUNC_VIS 141*4d6fc14bSjoergmemory_resource * new_delete_resource() _NOEXCEPT; 142*4d6fc14bSjoerg 143*4d6fc14bSjoerg_LIBCPP_FUNC_VIS 144*4d6fc14bSjoergmemory_resource * null_memory_resource() _NOEXCEPT; 145*4d6fc14bSjoerg 146*4d6fc14bSjoerg_LIBCPP_FUNC_VIS 147*4d6fc14bSjoergmemory_resource * get_default_resource() _NOEXCEPT; 148*4d6fc14bSjoerg 149*4d6fc14bSjoerg_LIBCPP_FUNC_VIS 150*4d6fc14bSjoergmemory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT; 151*4d6fc14bSjoerg 152*4d6fc14bSjoerg// 8.6, memory.polymorphic.allocator.class 153*4d6fc14bSjoerg 154*4d6fc14bSjoerg// 8.6.1, memory.polymorphic.allocator.overview 155*4d6fc14bSjoergtemplate <class _ValueType> 156*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS polymorphic_allocator 157*4d6fc14bSjoerg{ 158*4d6fc14bSjoergpublic: 159*4d6fc14bSjoerg typedef _ValueType value_type; 160*4d6fc14bSjoerg 161*4d6fc14bSjoerg // 8.6.2, memory.polymorphic.allocator.ctor 162*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 163*4d6fc14bSjoerg polymorphic_allocator() _NOEXCEPT 164*4d6fc14bSjoerg : __res_(_VSTD_LFTS_PMR::get_default_resource()) 165*4d6fc14bSjoerg {} 166*4d6fc14bSjoerg 167*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 168*4d6fc14bSjoerg polymorphic_allocator(memory_resource * __r) _NOEXCEPT 169*4d6fc14bSjoerg : __res_(__r) 170*4d6fc14bSjoerg {} 171*4d6fc14bSjoerg 172*4d6fc14bSjoerg polymorphic_allocator(polymorphic_allocator const &) = default; 173*4d6fc14bSjoerg 174*4d6fc14bSjoerg template <class _Tp> 175*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 176*4d6fc14bSjoerg polymorphic_allocator(polymorphic_allocator<_Tp> const & __other) _NOEXCEPT 177*4d6fc14bSjoerg : __res_(__other.resource()) 178*4d6fc14bSjoerg {} 179*4d6fc14bSjoerg 180*4d6fc14bSjoerg polymorphic_allocator & 181*4d6fc14bSjoerg operator=(polymorphic_allocator const &) = delete; 182*4d6fc14bSjoerg 183*4d6fc14bSjoerg // 8.6.3, memory.polymorphic.allocator.mem 184*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 185*4d6fc14bSjoerg _ValueType* allocate(size_t __n) { 186*4d6fc14bSjoerg if (__n > __max_size()) { 187*4d6fc14bSjoerg __throw_length_error( 188*4d6fc14bSjoerg "std::experimental::pmr::polymorphic_allocator<T>::allocate(size_t n)" 189*4d6fc14bSjoerg " 'n' exceeds maximum supported size"); 190*4d6fc14bSjoerg } 191*4d6fc14bSjoerg return static_cast<_ValueType*>( 192*4d6fc14bSjoerg __res_->allocate(__n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType)) 193*4d6fc14bSjoerg ); 194*4d6fc14bSjoerg } 195*4d6fc14bSjoerg 196*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 197*4d6fc14bSjoerg void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT { 198*4d6fc14bSjoerg _LIBCPP_ASSERT(__n <= __max_size(), 199*4d6fc14bSjoerg "deallocate called for size which exceeds max_size()"); 200*4d6fc14bSjoerg __res_->deallocate(__p, __n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType)); 201*4d6fc14bSjoerg } 202*4d6fc14bSjoerg 203*4d6fc14bSjoerg template <class _Tp, class ..._Ts> 204*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 205*4d6fc14bSjoerg void construct(_Tp* __p, _Ts &&... __args) 206*4d6fc14bSjoerg { 207*4d6fc14bSjoerg _VSTD_LFTS::__lfts_user_alloc_construct( 208*4d6fc14bSjoerg __p, *this, _VSTD::forward<_Ts>(__args)... 209*4d6fc14bSjoerg ); 210*4d6fc14bSjoerg } 211*4d6fc14bSjoerg 212*4d6fc14bSjoerg template <class _T1, class _T2, class ..._Args1, class ..._Args2> 213*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 214*4d6fc14bSjoerg void construct(pair<_T1, _T2>* __p, piecewise_construct_t, 215*4d6fc14bSjoerg tuple<_Args1...> __x, tuple<_Args2...> __y) 216*4d6fc14bSjoerg { 217*4d6fc14bSjoerg ::new ((void*)__p) pair<_T1, _T2>(piecewise_construct 218*4d6fc14bSjoerg , __transform_tuple( 219*4d6fc14bSjoerg typename __lfts_uses_alloc_ctor< 220*4d6fc14bSjoerg _T1, polymorphic_allocator&, _Args1... 221*4d6fc14bSjoerg >::type() 222*4d6fc14bSjoerg , _VSTD::move(__x) 223*4d6fc14bSjoerg , typename __make_tuple_indices<sizeof...(_Args1)>::type{} 224*4d6fc14bSjoerg ) 225*4d6fc14bSjoerg , __transform_tuple( 226*4d6fc14bSjoerg typename __lfts_uses_alloc_ctor< 227*4d6fc14bSjoerg _T2, polymorphic_allocator&, _Args2... 228*4d6fc14bSjoerg >::type() 229*4d6fc14bSjoerg , _VSTD::move(__y) 230*4d6fc14bSjoerg , typename __make_tuple_indices<sizeof...(_Args2)>::type{} 231*4d6fc14bSjoerg ) 232*4d6fc14bSjoerg ); 233*4d6fc14bSjoerg } 234*4d6fc14bSjoerg 235*4d6fc14bSjoerg template <class _T1, class _T2> 236*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 237*4d6fc14bSjoerg void construct(pair<_T1, _T2>* __p) { 238*4d6fc14bSjoerg construct(__p, piecewise_construct, tuple<>(), tuple<>()); 239*4d6fc14bSjoerg } 240*4d6fc14bSjoerg 241*4d6fc14bSjoerg template <class _T1, class _T2, class _Up, class _Vp> 242*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 243*4d6fc14bSjoerg void construct(pair<_T1, _T2> * __p, _Up && __u, _Vp && __v) { 244*4d6fc14bSjoerg construct(__p, piecewise_construct 245*4d6fc14bSjoerg , _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__u)) 246*4d6fc14bSjoerg , _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__v))); 247*4d6fc14bSjoerg } 248*4d6fc14bSjoerg 249*4d6fc14bSjoerg template <class _T1, class _T2, class _U1, class _U2> 250*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 251*4d6fc14bSjoerg void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> const & __pr) { 252*4d6fc14bSjoerg construct(__p, piecewise_construct 253*4d6fc14bSjoerg , _VSTD::forward_as_tuple(__pr.first) 254*4d6fc14bSjoerg , _VSTD::forward_as_tuple(__pr.second)); 255*4d6fc14bSjoerg } 256*4d6fc14bSjoerg 257*4d6fc14bSjoerg template <class _T1, class _T2, class _U1, class _U2> 258*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 259*4d6fc14bSjoerg void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> && __pr){ 260*4d6fc14bSjoerg construct(__p, piecewise_construct 261*4d6fc14bSjoerg , _VSTD::forward_as_tuple(_VSTD::forward<_U1>(__pr.first)) 262*4d6fc14bSjoerg , _VSTD::forward_as_tuple(_VSTD::forward<_U2>(__pr.second))); 263*4d6fc14bSjoerg } 264*4d6fc14bSjoerg 265*4d6fc14bSjoerg template <class _Tp> 266*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 267*4d6fc14bSjoerg void destroy(_Tp * __p) _NOEXCEPT 268*4d6fc14bSjoerg { __p->~_Tp(); } 269*4d6fc14bSjoerg 270*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 271*4d6fc14bSjoerg polymorphic_allocator 272*4d6fc14bSjoerg select_on_container_copy_construction() const _NOEXCEPT 273*4d6fc14bSjoerg { return polymorphic_allocator(); } 274*4d6fc14bSjoerg 275*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 276*4d6fc14bSjoerg memory_resource * resource() const _NOEXCEPT 277*4d6fc14bSjoerg { return __res_; } 278*4d6fc14bSjoerg 279*4d6fc14bSjoergprivate: 280*4d6fc14bSjoerg template <class ..._Args, size_t ..._Idx> 281*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 282*4d6fc14bSjoerg tuple<_Args&&...> 283*4d6fc14bSjoerg __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, 284*4d6fc14bSjoerg __tuple_indices<_Idx...>) const 285*4d6fc14bSjoerg { 286*4d6fc14bSjoerg return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...); 287*4d6fc14bSjoerg } 288*4d6fc14bSjoerg 289*4d6fc14bSjoerg template <class ..._Args, size_t ..._Idx> 290*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 291*4d6fc14bSjoerg tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...> 292*4d6fc14bSjoerg __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t, 293*4d6fc14bSjoerg __tuple_indices<_Idx...>) 294*4d6fc14bSjoerg { 295*4d6fc14bSjoerg using _Tup = tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...>; 296*4d6fc14bSjoerg return _Tup(allocator_arg, *this, 297*4d6fc14bSjoerg _VSTD::get<_Idx>(_VSTD::move(__t))...); 298*4d6fc14bSjoerg } 299*4d6fc14bSjoerg 300*4d6fc14bSjoerg template <class ..._Args, size_t ..._Idx> 301*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 302*4d6fc14bSjoerg tuple<_Args&&..., polymorphic_allocator&> 303*4d6fc14bSjoerg __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t, 304*4d6fc14bSjoerg __tuple_indices<_Idx...>) 305*4d6fc14bSjoerg { 306*4d6fc14bSjoerg using _Tup = tuple<_Args&&..., polymorphic_allocator&>; 307*4d6fc14bSjoerg return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., *this); 308*4d6fc14bSjoerg } 309*4d6fc14bSjoerg 310*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 311*4d6fc14bSjoerg size_t __max_size() const _NOEXCEPT 312*4d6fc14bSjoerg { return numeric_limits<size_t>::max() / sizeof(value_type); } 313*4d6fc14bSjoerg 314*4d6fc14bSjoerg memory_resource * __res_; 315*4d6fc14bSjoerg}; 316*4d6fc14bSjoerg 317*4d6fc14bSjoerg// 8.6.4, memory.polymorphic.allocator.eq 318*4d6fc14bSjoerg 319*4d6fc14bSjoergtemplate <class _Tp, class _Up> 320*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 321*4d6fc14bSjoergbool operator==(polymorphic_allocator<_Tp> const & __lhs, 322*4d6fc14bSjoerg polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT 323*4d6fc14bSjoerg{ 324*4d6fc14bSjoerg return *__lhs.resource() == *__rhs.resource(); 325*4d6fc14bSjoerg} 326*4d6fc14bSjoerg 327*4d6fc14bSjoergtemplate <class _Tp, class _Up> 328*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 329*4d6fc14bSjoergbool operator!=(polymorphic_allocator<_Tp> const & __lhs, 330*4d6fc14bSjoerg polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT 331*4d6fc14bSjoerg{ 332*4d6fc14bSjoerg return !(__lhs == __rhs); 333*4d6fc14bSjoerg} 334*4d6fc14bSjoerg 335*4d6fc14bSjoerg// 8.7, memory.resource.adaptor 336*4d6fc14bSjoerg 337*4d6fc14bSjoerg// 8.7.1, memory.resource.adaptor.overview 338*4d6fc14bSjoergtemplate <class _CharAlloc> 339*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS __resource_adaptor_imp 340*4d6fc14bSjoerg : public memory_resource 341*4d6fc14bSjoerg{ 342*4d6fc14bSjoerg using _CTraits = allocator_traits<_CharAlloc>; 343*4d6fc14bSjoerg static_assert(is_same<typename _CTraits::value_type, char>::value 344*4d6fc14bSjoerg && is_same<typename _CTraits::pointer, char*>::value 345*4d6fc14bSjoerg && is_same<typename _CTraits::void_pointer, void*>::value, ""); 346*4d6fc14bSjoerg 347*4d6fc14bSjoerg static const size_t _MaxAlign = _LIBCPP_ALIGNOF(max_align_t); 348*4d6fc14bSjoerg 349*4d6fc14bSjoerg using _Alloc = typename _CTraits::template rebind_alloc< 350*4d6fc14bSjoerg typename aligned_storage<_MaxAlign, _MaxAlign>::type 351*4d6fc14bSjoerg >; 352*4d6fc14bSjoerg 353*4d6fc14bSjoerg using _ValueType = typename _Alloc::value_type; 354*4d6fc14bSjoerg 355*4d6fc14bSjoerg _Alloc __alloc_; 356*4d6fc14bSjoerg 357*4d6fc14bSjoergpublic: 358*4d6fc14bSjoerg typedef _CharAlloc allocator_type; 359*4d6fc14bSjoerg 360*4d6fc14bSjoerg __resource_adaptor_imp() = default; 361*4d6fc14bSjoerg __resource_adaptor_imp(__resource_adaptor_imp const &) = default; 362*4d6fc14bSjoerg __resource_adaptor_imp(__resource_adaptor_imp &&) = default; 363*4d6fc14bSjoerg 364*4d6fc14bSjoerg // 8.7.2, memory.resource.adaptor.ctor 365*4d6fc14bSjoerg 366*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 367*4d6fc14bSjoerg explicit __resource_adaptor_imp(allocator_type const & __a) 368*4d6fc14bSjoerg : __alloc_(__a) 369*4d6fc14bSjoerg {} 370*4d6fc14bSjoerg 371*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 372*4d6fc14bSjoerg explicit __resource_adaptor_imp(allocator_type && __a) 373*4d6fc14bSjoerg : __alloc_(_VSTD::move(__a)) 374*4d6fc14bSjoerg {} 375*4d6fc14bSjoerg 376*4d6fc14bSjoerg __resource_adaptor_imp & 377*4d6fc14bSjoerg operator=(__resource_adaptor_imp const &) = default; 378*4d6fc14bSjoerg 379*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 380*4d6fc14bSjoerg allocator_type get_allocator() const 381*4d6fc14bSjoerg { return __alloc_; } 382*4d6fc14bSjoerg 383*4d6fc14bSjoerg// 8.7.3, memory.resource.adaptor.mem 384*4d6fc14bSjoergprivate: 385*4d6fc14bSjoerg virtual void * do_allocate(size_t __bytes, size_t) 386*4d6fc14bSjoerg { 387*4d6fc14bSjoerg if (__bytes > __max_size()) { 388*4d6fc14bSjoerg __throw_length_error( 389*4d6fc14bSjoerg "std::experimental::pmr::resource_adaptor<T>::do_allocate(size_t bytes, size_t align)" 390*4d6fc14bSjoerg " 'bytes' exceeds maximum supported size"); 391*4d6fc14bSjoerg } 392*4d6fc14bSjoerg size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign; 393*4d6fc14bSjoerg return __alloc_.allocate(__s); 394*4d6fc14bSjoerg } 395*4d6fc14bSjoerg 396*4d6fc14bSjoerg virtual void do_deallocate(void * __p, size_t __bytes, size_t) 397*4d6fc14bSjoerg { 398*4d6fc14bSjoerg _LIBCPP_ASSERT(__bytes <= __max_size(), 399*4d6fc14bSjoerg "do_deallocate called for size which exceeds the maximum allocation size"); 400*4d6fc14bSjoerg size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign; 401*4d6fc14bSjoerg __alloc_.deallocate((_ValueType*)__p, __s); 402*4d6fc14bSjoerg } 403*4d6fc14bSjoerg 404*4d6fc14bSjoerg virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT { 405*4d6fc14bSjoerg __resource_adaptor_imp const * __p 406*4d6fc14bSjoerg = dynamic_cast<__resource_adaptor_imp const *>(&__other); 407*4d6fc14bSjoerg return __p ? __alloc_ == __p->__alloc_ : false; 408*4d6fc14bSjoerg } 409*4d6fc14bSjoerg 410*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 411*4d6fc14bSjoerg size_t __max_size() const _NOEXCEPT { 412*4d6fc14bSjoerg return numeric_limits<size_t>::max() - _MaxAlign; 413*4d6fc14bSjoerg } 414*4d6fc14bSjoerg}; 415*4d6fc14bSjoerg 416*4d6fc14bSjoergtemplate <class _Alloc> 417*4d6fc14bSjoergusing resource_adaptor = __resource_adaptor_imp< 418*4d6fc14bSjoerg typename allocator_traits<_Alloc>::template rebind_alloc<char> 419*4d6fc14bSjoerg >; 420*4d6fc14bSjoerg 421*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_LFTS_PMR 422*4d6fc14bSjoerg 423*4d6fc14bSjoerg_LIBCPP_POP_MACROS 424*4d6fc14bSjoerg 425*4d6fc14bSjoerg#endif /* _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE */ 426