libstdc++: memory_resource.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#ifndef _GLIBCXX_MEMORY_RESOURCE_H
31#define _GLIBCXX_MEMORY_RESOURCE_H 1
32
33#pragma GCC system_header
34
35#if __cplusplus >= 201703L
36
37#include <new>
38#include <cstddef>
40#include <bits/uses_allocator.h>
44
45#if ! __glibcxx_make_obj_using_allocator
47# include
48#endif
49
50namespace std _GLIBCXX_VISIBILITY(default)
51{
52_GLIBCXX_BEGIN_NAMESPACE_VERSION
53namespace pmr
54{
55
56
57
58
59
60
62 {
63 static constexpr size_t _S_max_align = alignof(max_align_t);
64
65 public:
69
71
72 [[nodiscard]]
73 void*
74 allocate(size_t __bytes, size_t __alignment = _S_max_align)
75 __attribute__((__returns_nonnull__,__alloc_size__(2),__alloc_align__(3)))
76 { return ::operator new(__bytes, do_allocate(__bytes, __alignment)); }
77
78 void
79 deallocate(void* __p, size_t __bytes, size_t __alignment = _S_max_align)
80 __attribute__((__nonnull__))
81 { return do_deallocate(__p, __bytes, __alignment); }
82
83 [[nodiscard]]
84 bool
86 { return do_is_equal(__other); }
87
88 private:
89 virtual void*
90 do_allocate(size_t __bytes, size_t __alignment) = 0;
91
92 virtual void
93 do_deallocate(void* __p, size_t __bytes, size_t __alignment) = 0;
94
95 virtual bool
96 do_is_equal(const memory_resource& __other) const noexcept = 0;
97 };
98
99 [[nodiscard]]
100 inline bool
102 { return &__a == &__b || __a.is_equal(__b); }
103
104#if __cpp_impl_three_way_comparison < 201907L
105 [[nodiscard]]
106 inline bool
107 operator!=(const memory_resource& __a, const memory_resource& __b) noexcept
108 { return !(__a == __b); }
109#endif
110
111
112
113
114
115
116
117
118
119 template<typename _Tp>
121 {
122
123
124 template<typename _Up>
125 struct __not_pair { using type = void; };
126
127 template<typename _Up1, typename _Up2>
128 struct __not_pair<pair<_Up1, _Up2>> { };
129
130 public:
131 using value_type = _Tp;
132
134 {
136 __attribute__((__returns_nonnull__));
138 }
139
141 __attribute__((__nonnull__))
142 : _M_resource(__r)
143 { _GLIBCXX_DEBUG_ASSERT(__r); }
144
146
147 template<typename _Up>
149 : _M_resource(__x.resource())
150 { }
151
154
155 [[nodiscard]]
156 _Tp*
157 allocate(size_t __n)
158 __attribute__((__returns_nonnull__))
159 {
161 std::__throw_bad_array_new_length();
162 return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),
163 alignof(_Tp)));
164 }
165
166 void
167 deallocate(_Tp* __p, size_t __n) noexcept
168 __attribute__((__nonnull__))
169 { _M_resource->deallocate(__p, __n * sizeof(_Tp), alignof(_Tp)); }
170
171#if __cplusplus > 201703L
172 [[nodiscard]] void*
173 allocate_bytes(size_t __nbytes,
174 size_t __alignment = alignof(max_align_t))
175 { return _M_resource->allocate(__nbytes, __alignment); }
176
177 void
178 deallocate_bytes(void* __p, size_t __nbytes,
179 size_t __alignment = alignof(max_align_t))
180 { _M_resource->deallocate(__p, __nbytes, __alignment); }
181
182 template<typename _Up>
183 [[nodiscard]] _Up*
184 allocate_object(size_t __n = 1)
185 {
187 std::__throw_bad_array_new_length();
188 return static_cast<_Up*>(allocate_bytes(__n * sizeof(_Up),
189 alignof(_Up)));
190 }
191
192 template<typename _Up>
193 void
194 deallocate_object(_Up* __p, size_t __n = 1)
195 { deallocate_bytes(__p, __n * sizeof(_Up), alignof(_Up)); }
196
197 template<typename _Up, typename... _CtorArgs>
198 [[nodiscard]] _Up*
199 new_object(_CtorArgs&&... __ctor_args)
200 {
201 _Up* __p = allocate_object<_Up>();
202 __try
203 {
204 construct(__p, std::forward<_CtorArgs>(__ctor_args)...);
205 }
206 __catch (...)
207 {
208 deallocate_object(__p);
209 __throw_exception_again;
210 }
211 return __p;
212 }
213
214 template<typename _Up>
215 void
216 delete_object(_Up* __p)
217 {
218 __p->~_Up();
219 deallocate_object(__p);
220 }
221#endif
222
223#if ! __glibcxx_make_obj_using_allocator
224 template<typename _Tp1, typename... _Args>
225 __attribute__((__nonnull__))
226 typename __not_pair<_Tp1>::type
227 construct(_Tp1* __p, _Args&&... __args)
228 {
229
230
231 using __use_tag
233 if constexpr (is_base_of_v<__uses_alloc0, __use_tag>)
234 ::new(__p) _Tp1(std::forward<_Args>(__args)...);
235 else if constexpr (is_base_of_v<__uses_alloc1_, __use_tag>)
236 ::new(__p) _Tp1(allocator_arg, *this,
237 std::forward<_Args>(__args)...);
238 else
239 ::new(__p) _Tp1(std::forward<_Args>(__args)..., *this);
240 }
241
242 template<typename _Tp1, typename _Tp2,
243 typename... _Args1, typename... _Args2>
244 __attribute__((__nonnull__))
245 void
248 {
249 auto __x_tag =
251 auto __y_tag =
255
257 _S_construct_p(__x_tag, __x_i, __x),
258 _S_construct_p(__y_tag, __y_i, __y));
259 }
260
261 template<typename _Tp1, typename _Tp2>
262 __attribute__((__nonnull__))
263 void
266
267 template<typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
268 __attribute__((__nonnull__))
269 void
271 {
275 }
276
277 template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
278 __attribute__((__nonnull__))
279 void
281 {
285 }
286
287 template<typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
288 __attribute__((__nonnull__))
289 void
291 {
295 }
296#else
297 template<typename _Tp1, typename... _Args>
298 __attribute__((__nonnull__))
299 void
300 construct(_Tp1* __p, _Args&&... __args)
301 {
302 std::uninitialized_construct_using_allocator(__p, *this,
303 std::forward<_Args>(__args)...);
304 }
305#endif
306
307 template<typename _Up>
308 __attribute__((__nonnull__))
309 void
310 destroy(_Up* __p)
311 { __p->~_Up(); }
312
314 select_on_container_copy_construction() const noexcept
316
318 resource() const noexcept
319 __attribute__((__returns_nonnull__))
320 { return _M_resource; }
321
322
323
324 [[nodiscard]]
325 friend bool
328 { return *__a.resource() == *__b.resource(); }
329
330#if __cpp_impl_three_way_comparison < 201907L
331 [[nodiscard]]
332 friend bool
335 { return !(__a == __b); }
336#endif
337
338 private:
339#if ! __glibcxx_make_obj_using_allocator
340 using __uses_alloc1_ = __uses_alloc1<polymorphic_allocator>;
341 using __uses_alloc2_ = __uses_alloc2<polymorphic_allocator>;
342
343 template<typename _Ind, typename... _Args>
344 static tuple<_Args&&...>
345 _S_construct_p(__uses_alloc0, _Ind, tuple<_Args...>& __t)
347
348 template<size_t... _Ind, typename... _Args>
352 {
353 return {
354 allocator_arg, *__ua._M_a, std::get<_Ind>(std::move(__t))...
355 };
356 }
357
358 template<size_t... _Ind, typename... _Args>
362 { return { std::get<_Ind>(std::move(__t))..., *__ua._M_a }; }
363#endif
364
366 };
367
368 template<typename _Tp1, typename _Tp2>
369 [[nodiscard]]
370 inline bool
373 { return *__a.resource() == *__b.resource(); }
374
375#if __cpp_impl_three_way_comparison < 201907L
376 template<typename _Tp1, typename _Tp2>
377 [[nodiscard]]
378 inline bool
379 operator!=(const polymorphic_allocator<_Tp1>& __a,
380 const polymorphic_allocator<_Tp2>& __b) noexcept
381 { return !(__a == __b); }
382#endif
383
384}
385
386 template<typename _Alloc> struct allocator_traits;
387
388
389
390
391
392
393
394 template<typename _Tp>
396 {
397
399
400
402
403
405
406
408
409
411
412
414
415
417
418
420
421
422
423
424
428
432
433
434
436
437 template<typename _Up>
439
440 template<typename _Up>
442
443
444
445
446
447
448
449
450 [[nodiscard]] static pointer
452 { return __a.allocate(__n); }
453
454
455
456
457
458
459
460
461
462
463
464
465 [[nodiscard]] static pointer
467 { return __a.allocate(__n); }
468
469
470
471
472
473
474
475
476
477 static void
479 { __a.deallocate(__p, __n); }
480
481
482
483
484
485
486
487
488
489
490
491
492 template<typename _Up, typename... _Args>
493 static void
495 { __a.construct(__p, std::forward<_Args>(__args)...); }
496
497
498
499
500
501
502
503
504 template<typename _Up>
505 static _GLIBCXX20_CONSTEXPR void
508 { __p->~_Up(); }
509
510
511
512
513
514 static _GLIBCXX20_CONSTEXPR size_type
516 { return size_t(-1) / sizeof(value_type); }
517 };
518
519_GLIBCXX_END_NAMESPACE_VERSION
520}
521
522#endif
523#endif
memory_resource * get_default_resource() noexcept
Get the current default memory resource pointer.
__bool_constant< false > false_type
The type used as a compile-time boolean with false value.
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.
Primary class template, tuple.
Uniform interface to all allocator types.
__detected_or_t< value_type *, __pointer, _Alloc > pointer
The allocator's pointer type.
typename _Size< _Alloc, difference_type >::type size_type
The allocator's size type.
_Alloc::value_type value_type
The allocated type.
_Alloc allocator_type
The allocator type.
Class template polymorphic_allocator.
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.
false_type propagate_on_container_swap
_Tp * pointer
The allocator's pointer type.
const _Tp * const_pointer
The allocator's const pointer type.
false_type propagate_on_container_move_assignment
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.
false_type propagate_on_container_copy_assignment
static allocator_type select_on_container_copy_construction(const allocator_type &) noexcept
void * void_pointer
The allocator's void pointer type.
false_type is_always_equal
Whether all instances of the allocator type compare equal.
std::size_t size_type
The allocator's size type.
Struct holding two objects of arbitrary type.
_T1 first
The first member.
_T2 second
The second member.
Tag type for piecewise construction of std::pair objects.
Class template integer_sequence.