30#ifndef _GLIBCXX_MEMORY_RESOURCE_H
31#define _GLIBCXX_MEMORY_RESOURCE_H 1
33#pragma GCC system_header
35#if __cplusplus >= 201703L
40#include <bits/uses_allocator.h>
45#if ! __cpp_lib_make_obj_using_allocator
50namespace std _GLIBCXX_VISIBILITY(default)
52_GLIBCXX_BEGIN_NAMESPACE_VERSION
58 static constexpr size_t _S_max_align =
alignof(max_align_t);
69 allocate(
size_t __bytes,
size_t __alignment = _S_max_align)
70 __attribute__((__returns_nonnull__,__alloc_size__(2),__alloc_align__(3)))
71 { return ::operator
new(__bytes, do_allocate(__bytes, __alignment)); }
74 deallocate(
void* __p,
size_t __bytes,
size_t __alignment = _S_max_align)
75 __attribute__((__nonnull__))
76 {
return do_deallocate(__p, __bytes, __alignment); }
81 {
return do_is_equal(__other); }
85 do_allocate(
size_t __bytes,
size_t __alignment) = 0;
88 do_deallocate(
void* __p,
size_t __bytes,
size_t __alignment) = 0;
97 {
return &__a == &__b || __a.is_equal(__b); }
99#if __cpp_impl_three_way_comparison < 201907L
102 operator!=(
const memory_resource& __a,
const memory_resource& __b)
noexcept
103 {
return !(__a == __b); }
107 template<
typename _Tp>
108 class polymorphic_allocator
112 template<
typename _Up>
113 struct __not_pair {
using type = void; };
115 template<
typename _Up1,
typename _Up2>
116 struct __not_pair<pair<_Up1, _Up2>> { };
119 using value_type = _Tp;
121 polymorphic_allocator() noexcept
124 __attribute__((__returns_nonnull__));
125 _M_resource = get_default_resource();
128 polymorphic_allocator(memory_resource* __r) noexcept
129 __attribute__((__nonnull__))
131 { _GLIBCXX_DEBUG_ASSERT(__r); }
133 polymorphic_allocator(
const polymorphic_allocator& __other) =
default;
135 template<
typename _Up>
136 polymorphic_allocator(
const polymorphic_allocator<_Up>& __x) noexcept
137 : _M_resource(__x.resource())
140 polymorphic_allocator&
141 operator=(
const polymorphic_allocator&) =
delete;
146 __attribute__((__returns_nonnull__))
149 std::__throw_bad_array_new_length();
150 return static_cast<_Tp*
>(_M_resource->allocate(__n *
sizeof(_Tp),
155 deallocate(_Tp* __p,
size_t __n)
noexcept
156 __attribute__((__nonnull__))
157 { _M_resource->deallocate(__p, __n *
sizeof(_Tp),
alignof(_Tp)); }
159#if __cplusplus > 201703L
161 allocate_bytes(
size_t __nbytes,
162 size_t __alignment =
alignof(max_align_t))
163 {
return _M_resource->allocate(__nbytes, __alignment); }
166 deallocate_bytes(
void* __p,
size_t __nbytes,
167 size_t __alignment =
alignof(max_align_t))
168 { _M_resource->deallocate(__p, __nbytes, __alignment); }
170 template<
typename _Up>
172 allocate_object(
size_t __n = 1)
175 std::__throw_bad_array_new_length();
176 return static_cast<_Up*
>(allocate_bytes(__n *
sizeof(_Up),
180 template<
typename _Up>
182 deallocate_object(_Up* __p,
size_t __n = 1)
183 { deallocate_bytes(__p, __n *
sizeof(_Up),
alignof(_Up)); }
185 template<
typename _Up,
typename... _CtorArgs>
187 new_object(_CtorArgs&&... __ctor_args)
189 _Up* __p = allocate_object<_Up>();
192 construct(__p, std::forward<_CtorArgs>(__ctor_args)...);
196 deallocate_object(__p);
197 __throw_exception_again;
202 template<
typename _Up>
204 delete_object(_Up* __p)
207 deallocate_object(__p);
211#if ! __cpp_lib_make_obj_using_allocator
212 template<
typename _Tp1,
typename... _Args>
213 __attribute__((__nonnull__))
214 typename __not_pair<_Tp1>::type
215 construct(_Tp1* __p, _Args&&... __args)
220 = std::__uses_alloc_t<_Tp1, polymorphic_allocator, _Args...>;
221 if constexpr (is_base_of_v<__uses_alloc0, __use_tag>)
222 ::new(__p) _Tp1(std::forward<_Args>(__args)...);
223 else if constexpr (is_base_of_v<__uses_alloc1_, __use_tag>)
224 ::new(__p) _Tp1(allocator_arg, *
this,
225 std::forward<_Args>(__args)...);
227 ::new(__p) _Tp1(std::forward<_Args>(__args)..., *
this);
230 template<
typename _Tp1,
typename _Tp2,
231 typename... _Args1,
typename... _Args2>
232 __attribute__((__nonnull__))
234 construct(pair<_Tp1, _Tp2>* __p, piecewise_construct_t,
235 tuple<_Args1...> __x, tuple<_Args2...> __y)
238 __use_alloc<_Tp1, polymorphic_allocator, _Args1...>(*this);
240 __use_alloc<_Tp2, polymorphic_allocator, _Args2...>(*this);
245 _S_construct_p(__x_tag, __x_i, __x),
246 _S_construct_p(__y_tag, __y_i, __y));
249 template<
typename _Tp1,
typename _Tp2>
250 __attribute__((__nonnull__))
252 construct(pair<_Tp1, _Tp2>* __p)
255 template<
typename _Tp1,
typename _Tp2,
typename _Up,
typename _Vp>
256 __attribute__((__nonnull__))
258 construct(pair<_Tp1, _Tp2>* __p, _Up&& __x, _Vp&& __y)
265 template <
typename _Tp1,
typename _Tp2,
typename _Up,
typename _Vp>
266 __attribute__((__nonnull__))
275 template<
typename _Tp1,
typename _Tp2,
typename _Up,
typename _Vp>
276 __attribute__((__nonnull__))
278 construct(pair<_Tp1, _Tp2>* __p, pair<_Up, _Vp>&& __pr)
285 template<
typename _Tp1,
typename... _Args>
286 __attribute__((__nonnull__))
288 construct(_Tp1* __p, _Args&&... __args)
290 std::uninitialized_construct_using_allocator(__p, *
this,
291 std::forward<_Args>(__args)...);
295 template<
typename _Up>
296 _GLIBCXX20_DEPRECATED_SUGGEST(
"allocator_traits::destroy")
297 __attribute__((__nonnull__))
302 polymorphic_allocator
303 select_on_container_copy_construction() const noexcept
304 {
return polymorphic_allocator(); }
307 resource() const noexcept
308 __attribute__((__returns_nonnull__))
309 {
return _M_resource; }
315 operator==(
const polymorphic_allocator& __a,
316 const polymorphic_allocator& __b)
noexcept
317 {
return *__a.resource() == *__b.resource(); }
319#if __cpp_impl_three_way_comparison < 201907L
322 operator!=(
const polymorphic_allocator& __a,
323 const polymorphic_allocator& __b)
noexcept
324 {
return !(__a == __b); }
328#if ! __cpp_lib_make_obj_using_allocator
329 using __uses_alloc1_ = __uses_alloc1<polymorphic_allocator>;
330 using __uses_alloc2_ = __uses_alloc2<polymorphic_allocator>;
332 template<
typename _Ind,
typename... _Args>
333 static tuple<_Args&&...>
334 _S_construct_p(__uses_alloc0, _Ind, tuple<_Args...>& __t)
337 template<
size_t... _Ind,
typename... _Args>
338 static tuple<allocator_arg_t, polymorphic_allocator, _Args&&...>
339 _S_construct_p(__uses_alloc1_ __ua, index_sequence<_Ind...>,
340 tuple<_Args...>& __t)
343 allocator_arg, *__ua._M_a, std::get<_Ind>(
std::move(__t))...
347 template<
size_t... _Ind,
typename... _Args>
348 static tuple<_Args&&..., polymorphic_allocator>
349 _S_construct_p(__uses_alloc2_ __ua, index_sequence<_Ind...>,
350 tuple<_Args...>& __t)
351 {
return { std::get<_Ind>(
std::move(__t))..., *__ua._M_a }; }
354 memory_resource* _M_resource;
357 template<
typename _Tp1,
typename _Tp2>
360 operator==(
const polymorphic_allocator<_Tp1>& __a,
361 const polymorphic_allocator<_Tp2>& __b)
noexcept
362 {
return *__a.resource() == *__b.resource(); }
364#if __cpp_impl_three_way_comparison < 201907L
365 template<
typename _Tp1,
typename _Tp2>
368 operator!=(
const polymorphic_allocator<_Tp1>& __a,
369 const polymorphic_allocator<_Tp2>& __b)
noexcept
370 {
return !(__a == __b); }
375 template<
typename _Alloc>
struct allocator_traits;
378 template<
typename _Tp>
421 template<
typename _Up>
422 using rebind_alloc = pmr::polymorphic_allocator<_Up>;
424 template<
typename _Up>
436 {
return __a.allocate(__n); }
449 [[nodiscard]]
static pointer
451 {
return __a.allocate(__n); }
463 { __a.deallocate(__p, __n); }
476 template<
typename _Up,
typename... _Args>
479 { __a.construct(__p, std::forward<_Args>(__args)...); }
488 template<
typename _Up>
489 static _GLIBCXX20_CONSTEXPR
void
498 static _GLIBCXX20_CONSTEXPR size_type
503_GLIBCXX_END_NAMESPACE_VERSION
memory_resource * get_default_resource() noexcept
Get the current default memory resource pointer.
constexpr tuple< _Elements &&... > forward_as_tuple(_Elements &&... __args) noexcept
Create a tuple of lvalue or rvalue references to the arguments.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr piecewise_construct_t piecewise_construct
Tag for piecewise construction of std::pair objects.
ISO C++ entities toplevel namespace is std.
make_index_sequence< sizeof...(_Types)> index_sequence_for
Alias template index_sequence_for.
__numeric_traits_integer< _Tp > __int_traits
Convenience alias for __numeric_traits<integer-type>.
Uniform interface to all allocator types.
static void construct(allocator_type &__a, _Up *__p, _Args &&... __args)
Construct an object of type _Up
std::ptrdiff_t difference_type
The allocator's difference type.
static void deallocate(allocator_type &__a, pointer __p, size_type __n)
Deallocate memory.
_Tp value_type
The allocated type.
static constexpr void destroy(allocator_type &, _Up *__p) noexcept(is_nothrow_destructible< _Up >::value)
Destroy an object of type _Up
static constexpr size_type max_size(const allocator_type &) noexcept
The maximum supported allocation size.
static pointer allocate(allocator_type &__a, size_type __n)
Allocate memory.
_Tp * pointer
The allocator's pointer type.
const _Tp * const_pointer
The allocator's const pointer type.
static pointer allocate(allocator_type &__a, size_type __n, const_void_pointer)
Allocate memory.
const void * const_void_pointer
The allocator's const void pointer type.
static allocator_type select_on_container_copy_construction(const allocator_type &) noexcept
void * void_pointer
The allocator's void pointer type.
std::size_t size_type
The allocator's size type.
pmr::polymorphic_allocator< _Tp > allocator_type
The allocator type.
Struct holding two objects of arbitrary type.
_T1 first
The first member.
_T2 second
The second member.