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