libstdc++
experimental/memory_resource
Go to the documentation of this file.
1
/
/
<
experimental
/
memory_resource
>
-
*
-
C
+
+
-
*
-
2
3
/
/
Copyright
(
C
)
2015-2025
Free
Software
Foundation
,
Inc
.
4
/
/
5
/
/
This
file
is
part
of
the
GNU
ISO
C
+
+
Library
.
This
library
is
free
6
/
/
software
;
you
can
redistribute
it
and
/
or
modify
it
under
the
7
/
/
terms
of
the
GNU
General
Public
License
as
published
by
the
8
/
/
Free
Software
Foundation
;
either
version
3
,
or
(
at
your
option
)
9
/
/
any
later
version
.
10
11
/
/
This
library
is
distributed
in
the
hope
that
it
will
be
useful
,
12
/
/
but
WITHOUT
ANY
WARRANTY
;
without
even
the
implied
warranty
of
13
/
/
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE
.
See
the
14
/
/
GNU
General
Public
License
for
more
details
.
15
16
/
/
Under
Section
7
of
GPL
version
3
,
you
are
granted
additional
17
/
/
permissions
described
in
the
GCC
Runtime
Library
Exception
,
version
18
/
/
3
.
1
,
as
published
by
the
Free
Software
Foundation
.
19
20
/
/
You
should
have
received
a
copy
of
the
GNU
General
Public
License
and
21
/
/
a
copy
of
the
GCC
Runtime
Library
Exception
along
with
this
program
;
22
/
/
see
the
files
COPYING3
and
COPYING
.
RUNTIME
respectively
.
If
not
,
see
23
/
/
<
http
:
/
/
www
.
gnu
.
org
/
licenses
/
>
.
24
25
/
*
*
@
file
experimental
/
memory_resource
26
*
This
is
a
TS
C
+
+
Library
header
.
27
*
@
ingroup
libfund
-
ts
28
*
/
29
30
#ifndef _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE
31
#define _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE 1
32
33
#ifdef _GLIBCXX_SYSHDR
34
#pragma GCC system_header
35
#endif
36
37
#include <bits/requires_hosted.h> // experimental is currently omitted
38
39
#if __cplusplus >= 201402L
40
41
#include <memory> // align, uses_allocator, __uses_alloc
42
#include <experimental/utility> // pair, experimental::erased_type
43
#include <tuple> // tuple, forward_as_tuple
44
#include <atomic> // atomic
45
#include <new> // placement new
46
#include <cstddef> // max_align_t
47
#include <bits/new_allocator.h>
48
#include <debug/assertions.h>
49
50
namespace
__gnu_cxx
_GLIBCXX_VISIBILITY
(
default
)
51
{
52
_GLIBCXX_BEGIN_NAMESPACE_VERSION
53
template
<
typename
_Tp
>
class
malloc_allocator
;
54
_GLIBCXX_END_NAMESPACE_VERSION
55
}
/
/
namespace
__gnu_cxx
56
57
namespace
std
{
58
_GLIBCXX_BEGIN_NAMESPACE_VERSION
59
60
namespace
experimental
{
61
inline
namespace
fundamentals_v2
{
62
namespace
pmr
{
63
#define __cpp_lib_experimental_memory_resources 201402L
64
65
/
/
Standard
memory
resources
66
67
/
/
8
.
5
Class
memory_resource
68
class
memory_resource
;
69
70
/
/
8
.
6
Class
template
polymorphic_allocator
71
template
<
typename
_Tp
>
72
class
polymorphic_allocator
;
73
74
template
<
typename
_Alloc
,
typename
_Resource
=
memory_resource
>
75
class
__resource_adaptor_imp
;
76
77
/
/
8
.
7
Alias
template
resource_adaptor
78
template
<
typename
_Alloc
>
79
using
resource_adaptor
=
__resource_adaptor_imp
<
80
type
name
allocator_traits
<
_Alloc
>
:
:
template
rebind_alloc
<
char
>>
;
81
82
/
/
8
.
8
Global
memory
resources
83
memory_resource
*
new_delete_resource
(
)
noexcept
;
84
memory_resource
*
null_memory_resource
(
)
noexcept
;
85
memory_resource
*
get_default_resource
(
)
noexcept
;
86
memory_resource
*
set_default_resource
(
memory_resource
*
__r
)
noexcept
;
87
88
/
/
TODO
8
.
9
Pool
resource
classes
89
90
class
memory_resource
91
{
92
static
constexpr
size_t
_S_max_align
=
alignof
(
max_align_t
)
;
93
94
public
:
95
memory_resource
(
)
=
default
;
96
memory_resource
(
const
memory_resource
&
)
=
default
;
97
virtual
~
memory_resource
(
)
=
default
;
98
99
memory_resource
&
operator
=
(
const
memory_resource
&
)
=
default
;
100
101
_GLIBCXX_NODISCARD
void
*
102
allocate
(
size_t
__bytes
,
size_t
__alignment
=
_S_max_align
)
103
{
return
do_allocate
(
__bytes
,
__alignment
)
; }
104
105
void
106
deallocate
(
void
*
__p
,
size_t
__bytes
,
size_t
__alignment
=
_S_max_align
)
107
{
return
do_deallocate
(
__p
,
__bytes
,
__alignment
)
; }
108
109
bool
110
is_equal
(
const
memory_resource
&
__other
)
const
noexcept
111
{
return
do_is_equal
(
__other
)
; }
112
113
protected
:
114
virtual
void
*
115
do_allocate
(
size_t
__bytes
,
size_t
__alignment
)
=
0
;
116
117
virtual
void
118
do_deallocate
(
void
*
__p
,
size_t
__bytes
,
size_t
__alignment
)
=
0
;
119
120
virtual
bool
121
do_is_equal
(
const
memory_resource
&
__other
)
const
noexcept
=
0
;
122
};
123
124
inline
bool
125
operator
==
(
const
memory_resource
&
__a
,
const
memory_resource
&
__b
)
noexcept
126
{
return
&
__a
==
&
__b
||
__a
.
is_equal
(
__b
)
; }
127
128
inline
bool
129
operator
!=
(
const
memory_resource
&
__a
,
const
memory_resource
&
__b
)
noexcept
130
{
return
!
(
__a
==
__b
)
; }
131
132
133
template
<
typename
_Tp
>
134
class
polymorphic_allocator
135
{
136
public
:
137
using
value_type
=
_Tp
;
138
139
polymorphic_allocator
(
)
noexcept
140
:
_M_resource
(
get_default_resource
(
)
)
141
{ }
142
143
polymorphic_allocator
(
memory_resource
*
__r
)
144
:
_M_resource
(
__r
)
145
{
_GLIBCXX_DEBUG_ASSERT
(
__r
)
; }
146
147
polymorphic_allocator
(
const
polymorphic_allocator
&
__other
)
=
default
;
148
149
template
<
typename
_Up
>
150
polymorphic_allocator
(
const
polymorphic_allocator
<
_Up
>
&
151
__other
)
noexcept
152
:
_M_resource
(
__other
.
resource
(
)
)
153
{ }
154
155
polymorphic_allocator
&
156
operator
=
(
const
polymorphic_allocator
&
__rhs
)
=
default
;
157
158
_GLIBCXX_NODISCARD
_Tp
*
allocate
(
size_t
__n
)
159
{
return
static_cast
<
_Tp
*
>
(
_M_resource
-
>
allocate
(
__n
*
sizeof
(
_Tp
)
,
160
alignof
(
_Tp
)
)
)
; }
161
162
void
163
deallocate
(
_Tp
*
__p
,
size_t
__n
)
164
{
_M_resource
-
>
deallocate
(
__p
,
__n
*
sizeof
(
_Tp
)
,
alignof
(
_Tp
)
)
; }
165
166
template
<
typename
_Tp1
,
typename
.
.
.
_Args
>
/
/
used
here
167
void
168
construct
(
_Tp1
*
__p
,
_Args
&&
.
.
.
__args
)
169
{
170
std
:
:
__uses_allocator_construct
(
this
-
>
resource
(
)
,
__p
,
171
std
:
:
forward
<
_Args
>
(
__args
)
.
.
.
)
;
172
}
173
174
/
/
Specializations
for
pair
using
piecewise
construction
175
template
<
typename
_Tp1
,
typename
_Tp2
,
176
type
name
.
.
.
_Args1
,
typename
.
.
.
_Args2
>
177
void
178
construct
(
pair
<
_Tp1
,
_Tp2
>
*
__p
,
piecewise_construct_t
,
179
tuple
<
_Args1
.
.
.
>
__x
,
tuple
<
_Args2
.
.
.
>
__y
)
180
{
181
memory_resource
*
const
__resource
=
this
-
>
resource
(
)
;
182
auto
__x_use_tag
=
183
std
:
:
__use_alloc
<
_Tp1
,
memory_resource
*
,
_Args1
.
.
.
>
(
__resource
)
;
184
auto
__y_use_tag
=
185
std
:
:
__use_alloc
<
_Tp2
,
memory_resource
*
,
_Args2
.
.
.
>
(
__resource
)
;
186
187
:
:
new
(
__p
)
std
:
:
pair
<
_Tp1
,
_Tp2
>
(
piecewise_construct
,
188
_M_construct_p
(
__x_use_tag
,
__x
)
,
189
_M_construct_p
(
__y_use_tag
,
__y
)
)
;
190
}
191
192
template
<
typename
_Tp1
,
typename
_Tp2
>
193
void
194
construct
(
pair
<
_Tp1
,
_Tp2
>
*
__p
)
195
{
this
-
>
construct
(
__p
,
piecewise_construct
,
tuple
<
>
(
)
,
tuple
<
>
(
)
)
; }
196
197
template
<
typename
_Tp1
,
typename
_Tp2
,
typename
_Up
,
typename
_Vp
>
198
void
199
construct
(
pair
<
_Tp1
,
_Tp2
>
*
__p
,
_Up
&&
__x
,
_Vp
&&
__y
)
200
{
201
this
-
>
construct
(
__p
,
piecewise_construct
,
202
std
:
:
forward_as_tuple
(
std
:
:
forward
<
_Up
>
(
__x
)
)
,
203
std
:
:
forward_as_tuple
(
std
:
:
forward
<
_Vp
>
(
__y
)
)
)
;
204
}
205
206
template
<
typename
_Tp1
,
typename
_Tp2
,
typename
_Up
,
typename
_Vp
>
207
void
208
construct
(
pair
<
_Tp1
,
_Tp2
>
*
__p
,
const
std
:
:
pair
<
_Up
,
_Vp
>
&
__pr
)
209
{
210
this
-
>
construct
(
__p
,
piecewise_construct
,
211
std
:
:
forward_as_tuple
(
__pr
.
first
)
,
212
std
:
:
forward_as_tuple
(
__pr
.
second
)
)
;
213
}
214
215
template
<
typename
_Tp1
,
typename
_Tp2
,
typename
_Up
,
typename
_Vp
>
216
void
217
construct
(
pair
<
_Tp1
,
_Tp2
>
*
__p
,
pair
<
_Up
,
_Vp
>
&&
__pr
)
218
{
219
this
-
>
construct
(
__p
,
piecewise_construct
,
220
std
:
:
forward_as_tuple
(
std
:
:
forward
<
_Up
>
(
__pr
.
first
)
)
,
221
std
:
:
forward_as_tuple
(
std
:
:
forward
<
_Vp
>
(
__pr
.
second
)
)
)
;
222
}
223
224
template
<
typename
_Up
>
225
void
226
destroy
(
_Up
*
__p
)
227
{
__p
-
>
~
_Up
(
)
; }
228
229
/
/
Return
a
default
-
constructed
allocator
(
no
allocator
propagation
)
230
polymorphic_allocator
231
select_on_container_copy_construction
(
)
const
232
{
return
polymorphic_allocator
(
)
; }
233
234
memory_resource
*
resource
(
)
const
{
return
_M_resource
; }
235
236
private
:
237
using
__uses_alloc1_
=
__uses_alloc1
<
memory_resource
*
>
;
238
using
__uses_alloc2_
=
__uses_alloc2
<
memory_resource
*
>
;
239
240
template
<
typename
_Tuple
>
241
_Tuple
&&
242
_M_construct_p
(
__uses_alloc0
,
_Tuple
&
__t
)
243
{
return
std
:
:
move
(
__t
)
; }
244
245
template
<
typename
.
.
.
_Args
>
246
decltype
(
auto
)
247
_M_construct_p
(
__uses_alloc1_
__ua
,
tuple
<
_Args
.
.
.
>
&
__t
)
248
{
return
tuple_cat
(
make_tuple
(
allocator_arg
,
*
(
__ua
.
_M_a
)
)
,
249
std
:
:
move
(
__t
)
)
; }
250
251
template
<
typename
.
.
.
_Args
>
252
decltype
(
auto
)
253
_M_construct_p
(
__uses_alloc2_
__ua
,
tuple
<
_Args
.
.
.
>
&
__t
)
254
{
return
tuple_cat
(
std
:
:
move
(
__t
)
,
make_tuple
(
*
(
__ua
.
_M_a
)
)
)
; }
255
256
memory_resource
*
_M_resource
;
257
};
258
259
template
<
class
_Tp1
,
class
_Tp2
>
260
bool
261
operator
==
(
const
polymorphic_allocator
<
_Tp1
>
&
__a
,
262
const
polymorphic_allocator
<
_Tp2
>
&
__b
)
noexcept
263
{
return
*
__a
.
resource
(
)
==
*
__b
.
resource
(
)
; }
264
265
template
<
class
_Tp1
,
class
_Tp2
>
266
bool
267
operator
!=
(
const
polymorphic_allocator
<
_Tp1
>
&
__a
,
268
const
polymorphic_allocator
<
_Tp2
>
&
__b
)
noexcept
269
{
return
!
(
__a
==
__b
)
; }
270
271
272
/
/
/
@
cond
undocumented
273
class
__resource_adaptor_common
274
{
275
template
<
typename
,
typename
>
friend
class
__resource_adaptor_imp
;
276
277
struct
_AlignMgr
278
{
279
_AlignMgr
(
size_t
__nbytes
,
size_t
__align
)
280
:
_M_nbytes
(
__nbytes
)
,
_M_align
(
__align
)
281
{ }
282
283
/
/
Total
size
that
needs
to
be
allocated
.
284
size_t
285
_M_alloc_size
(
)
const
{
return
_M_buf_size
(
)
+
_M_token_size
(
)
; }
286
287
void
*
288
_M_adjust
(
void
*
__ptr
)
const
289
{
290
const
auto
__orig_ptr
=
static_cast
<
char
*
>
(
__ptr
)
;
291
size_t
__space
=
_M_buf_size
(
)
;
292
/
/
Align
the
pointer
within
the
buffer
:
293
std
:
:
align
(
_M_align
,
_M_nbytes
,
__ptr
,
__space
)
;
294
const
auto
__aligned_ptr
=
static_cast
<
char
*
>
(
__ptr
)
;
295
const
auto
__token_size
=
_M_token_size
(
)
;
296
/
/
Store
token
immediately
after
the
aligned
block
:
297
char
*
const
__end
=
__aligned_ptr
+
_M_nbytes
;
298
if
(
__token_size
==
1
)
299
_S_write
<
unsigned
char
>
(
__end
,
__aligned_ptr
-
__orig_ptr
)
;
300
else
if
(
__token_size
==
sizeof
(
short
)
)
301
_S_write
<
unsigned
short
>
(
__end
,
__aligned_ptr
-
__orig_ptr
)
;
302
else
if
(
__token_size
==
sizeof
(
int
)
&&
sizeof
(
int
)
<
sizeof
(
char
*
)
)
303
_S_write
<
unsigned
int
>
(
__end
,
__aligned_ptr
-
__orig_ptr
)
;
304
else
/
/
(
__token_size
==
sizeof
(
char
*
)
)
305
/
/
Just
store
the
original
pointer
:
306
_S_write
<
char
*
>
(
__end
,
__orig_ptr
)
;
307
return
__aligned_ptr
;
308
}
309
310
char
*
311
_M_unadjust
(
char
*
__ptr
)
const
312
{
313
const
char
*
const
__end
=
__ptr
+
_M_nbytes
;
314
char
*
__orig_ptr
;
315
const
auto
__token_size
=
_M_token_size
(
)
;
316
/
/
Read
the
token
and
restore
the
original
pointer
:
317
if
(
__token_size
==
1
)
318
__orig_ptr
=
__ptr
-
_S_read
<
unsigned
char
>
(
__end
)
;
319
else
if
(
__token_size
==
sizeof
(
short
)
)
320
__orig_ptr
=
__ptr
-
_S_read
<
unsigned
short
>
(
__end
)
;
321
else
if
(
__token_size
==
sizeof
(
int
)
322
&&
sizeof
(
int
)
<
sizeof
(
char
*
)
)
323
__orig_ptr
=
__ptr
-
_S_read
<
unsigned
int
>
(
__end
)
;
324
else
/
/
(
__token_size
==
sizeof
(
char
*
)
)
325
__orig_ptr
=
_S_read
<
char
*
>
(
__end
)
;
326
/
/
The
adjustment
is
always
less
than
the
requested
alignment
,
327
/
/
so
if
that
isn
'
t
true
now
then
either
the
wrong
size
was
passed
328
/
/
to
deallocate
or
the
token
was
overwritten
by
a
buffer
overflow
:
329
__glibcxx_assert
(
static_cast
<
size_t
>
(
__ptr
-
__orig_ptr
)
<
_M_align
)
;
330
return
__orig_ptr
;
331
}
332
333
private
:
334
size_t
_M_nbytes
;
335
size_t
_M_align
;
336
337
/
/
Number
of
bytes
needed
to
fit
block
of
given
size
and
alignment
.
338
size_t
339
_M_buf_size
(
)
const
{
return
_M_nbytes
+
_M_align
-
1
; }
340
341
/
/
Number
of
additional
bytes
needed
to
write
the
token
.
342
int
343
_M_token_size
(
)
const
344
{
345
if
(
_M_align
<=
(
1
ul
<<
__CHAR_BIT__
)
)
346
return
1
;
347
if
(
_M_align
<=
(
1
ul
<<
(
sizeof
(
short
)
*
__CHAR_BIT__
)
)
)
348
return
sizeof
(
short
)
;
349
if
(
_M_align
<=
(
1
ull
<<
(
sizeof
(
int
)
*
__CHAR_BIT__
)
)
)
350
return
sizeof
(
int
)
;
351
return
sizeof
(
char
*
)
;
352
}
353
354
template
<
typename
_Tp
>
355
static
void
356
_S_write
(
void
*
__to
,
_Tp
__val
)
357
{
__builtin_memcpy
(
__to
,
&
__val
,
sizeof
(
_Tp
)
)
; }
358
359
template
<
typename
_Tp
>
360
static
_Tp
361
_S_read
(
const
void
*
__from
)
362
{
363
_Tp
__val
;
364
__builtin_memcpy
(
&
__val
,
__from
,
sizeof
(
_Tp
)
)
;
365
return
__val
;
366
}
367
};
368
};
369
/
/
/
@
endcond
370
371
/
/
8
.
7
.
1
__resource_adaptor_imp
372
template
<
typename
_Alloc
,
typename
_Resource
>
373
class
__resource_adaptor_imp
374
:
public
_Resource
,
private
__resource_adaptor_common
375
{
376
using
memory_resource
=
_Resource
;
377
378
static_assert
(
is_same
<
char
,
379
type
name
allocator_traits
<
_Alloc
>
:
:
value_type
>
:
:
value
,
380
"Allocator's value_type is char"
)
;
381
static_assert
(
is_same
<
char
*
,
382
type
name
allocator_traits
<
_Alloc
>
:
:
pointer
>
:
:
value
,
383
"Allocator's pointer type is value_type*"
)
;
384
static_assert
(
is_same
<
const
char
*
,
385
type
name
allocator_traits
<
_Alloc
>
:
:
const_pointer
>
:
:
value
,
386
"Allocator's const_pointer type is value_type const*"
)
;
387
static_assert
(
is_same
<
void
*
,
388
type
name
allocator_traits
<
_Alloc
>
:
:
void_pointer
>
:
:
value
,
389
"Allocator's void_pointer type is void*"
)
;
390
static_assert
(
is_same
<
const
void
*
,
391
type
name
allocator_traits
<
_Alloc
>
:
:
const_void_pointer
>
:
:
value
,
392
"Allocator's const_void_pointer type is void const*"
)
;
393
394
public
:
395
using
allocator_type
=
_Alloc
;
396
397
__resource_adaptor_imp
(
)
=
default
;
398
__resource_adaptor_imp
(
const
__resource_adaptor_imp
&
)
=
default
;
399
__resource_adaptor_imp
(
__resource_adaptor_imp
&&
)
=
default
;
400
401
explicit
__resource_adaptor_imp
(
const
_Alloc
&
__a2
)
402
:
_M_alloc
(
__a2
)
403
{ }
404
405
explicit
__resource_adaptor_imp
(
_Alloc
&&
__a2
)
406
:
_M_alloc
(
std
:
:
move
(
__a2
)
)
407
{ }
408
409
__resource_adaptor_imp
&
410
operator
=
(
const
__resource_adaptor_imp
&
)
=
default
;
411
412
allocator_type
get_allocator
(
)
const
noexcept
{
return
_M_alloc
; }
413
414
protected
:
415
#if (defined __sun__ || defined __VXWORKS__) && defined __i386__
416
/
/
Cannot
use
max_align_t
on
32-b
it
Solaris
x86
,
see
PR
libstdc
+
+
/
77691
417
# define _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC 0
418
#elif defined __hpux__ && defined __hppa__ && defined __LP64__
419
/
/
Ignore
inconsistent
long
double
and
malloc
alignment
(
libstdc
+
+
/
77691
)
420
# define _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC 0
421
#else
422
# define _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC 1
423
#endif
424
425
virtual
void
*
426
do_allocate
(
size_t
__bytes
,
size_t
__alignment
)
override
427
{
428
#if _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC
429
if
(
__alignment
==
alignof
(
max_align_t
)
)
430
return
_M_allocate
<
alignof
(
max_align_t
)
>
(
__bytes
)
;
431
#endif
432
switch
(
__alignment
)
433
{
434
case
1
:
435
return
_M_alloc
.
allocate
(
__bytes
)
;
436
case
2
:
437
return
_M_allocate
<
2
>
(
__bytes
)
;
438
case
4
:
439
return
_M_allocate
<
4
>
(
__bytes
)
;
440
case
8
:
441
return
_M_allocate
<
8
>
(
__bytes
)
;
442
}
443
const
_AlignMgr
__mgr
(
__bytes
,
__alignment
)
;
444
/
/
Assume
_M_alloc
returns
1-b
yte
aligned
memory
,
so
allocate
enough
445
/
/
space
to
fit
a
block
of
the
right
size
and
alignment
,
plus
some
446
/
/
extra
bytes
to
store
a
token
for
retrieving
the
original
pointer
.
447
return
__mgr
.
_M_adjust
(
_M_alloc
.
allocate
(
__mgr
.
_M_alloc_size
(
)
)
)
;
448
}
449
450
virtual
void
451
do_deallocate
(
void
*
__ptr
,
size_t
__bytes
,
size_t
__alignment
)
noexcept
452
override
453
{
454
#if _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC
455
if
(
__alignment
==
alignof
(
max_align_t
)
)
456
return
(
void
)
_M_deallocate
<
alignof
(
max_align_t
)
>
(
__ptr
,
__bytes
)
;
457
#endif
458
switch
(
__alignment
)
459
{
460
case
1
:
461
return
(
void
)
_M_alloc
.
deallocate
(
(
char
*
)
__ptr
,
__bytes
)
;
462
case
2
:
463
return
(
void
)
_M_deallocate
<
2
>
(
__ptr
,
__bytes
)
;
464
case
4
:
465
return
(
void
)
_M_deallocate
<
4
>
(
__ptr
,
__bytes
)
;
466
case
8
:
467
return
(
void
)
_M_deallocate
<
8
>
(
__ptr
,
__bytes
)
;
468
}
469
const
_AlignMgr
__mgr
(
__bytes
,
__alignment
)
;
470
/
/
Use
the
stored
token
to
retrieve
the
original
pointer
.
471
_M_alloc
.
deallocate
(
__mgr
.
_M_unadjust
(
(
char
*
)
__ptr
)
,
472
__mgr
.
_M_alloc_size
(
)
)
;
473
}
474
475
virtual
bool
476
do_is_equal
(
const
memory_resource
&
__other
)
const
noexcept
override
477
{
478
#if __cpp_rtti
479
if
(
auto
__p
=
dynamic_cast
<
const
__resource_adaptor_imp
*
>
(
&
__other
)
)
480
return
_M_alloc
==
__p
-
>
_M_alloc
;
481
#else
482
if
(
this
==
&
__other
)
/
/
Need
RTTI
to
do
better
than
this
.
483
return
true
;
484
#endif
485
return
false
;
486
}
487
488
private
:
489
template
<
size_t
_Num
>
490
struct
_Aligned_type
{
alignas
(
_Num
)
char
__c
[
_Num
]; };
491
492
/
/
Rebind
the
allocator
to
the
specified
type
and
use
it
to
allocate
.
493
template
<
size_t
_Num
,
typename
_Tp
=
_Aligned_type
<
_Num
>>
494
void
*
495
_M_allocate
(
size_t
__bytes
)
496
{
497
type
name
allocator_traits
<
_Alloc
>
:
:
template
498
rebind_alloc
<
_Tp
>
__a2
(
_M_alloc
)
;
499
const
size_t
__n
=
(
__bytes
+
_Num
-
1
)
/
_Num
;
500
return
__a2
.
allocate
(
__n
)
;
501
}
502
503
/
/
Rebind
the
allocator
to
the
specified
type
and
use
it
to
deallocate
.
504
template
<
size_t
_Num
,
typename
_Tp
=
_Aligned_type
<
_Num
>>
505
void
506
_M_deallocate
(
void
*
__ptr
,
size_t
__bytes
)
noexcept
507
{
508
type
name
allocator_traits
<
_Alloc
>
:
:
template
509
rebind_alloc
<
_Tp
>
__a2
(
_M_alloc
)
;
510
const
size_t
__n
=
(
__bytes
+
_Num
-
1
)
/
_Num
;
511
__a2
.
deallocate
(
(
_Tp
*
)
__ptr
,
__n
)
;
512
}
513
514
_Alloc
_M_alloc
{};
515
};
516
517
/
/
Global
memory
resources
518
519
inline
memory_resource
*
520
new_delete_resource
(
)
noexcept
521
{
522
using
type
=
resource_adaptor
<
std
:
:
__new_allocator
<
char
>>
;
523
alignas
(
type
)
static
unsigned
char
__buf
[
sizeof
(
type
)
];
524
static
type
*
__r
=
new
(
__buf
)
type
;
525
return
__r
;
526
}
527
528
inline
memory_resource
*
529
null_memory_resource
(
)
noexcept
530
{
531
class
type
final
:
public
memory_resource
532
{
533
void
*
534
do_allocate
(
size_t
,
size_t
)
override
535
{
std
:
:
__throw_bad_alloc
(
)
; }
536
537
void
538
do_deallocate
(
void
*
,
size_t
,
size_t
)
noexcept
override
539
{ }
540
541
bool
542
do_is_equal
(
const
memory_resource
&
__other
)
const
noexcept
override
543
{
return
this
==
&
__other
; }
544
};
545
546
alignas
(
type
)
static
unsigned
char
__buf
[
sizeof
(
type
)
];
547
static
type
*
__r
=
new
(
__buf
)
type
;
548
return
__r
;
549
}
550
551
/
/
The
default
memory
resource
552
553
/
/
/
@
cond
undocumented
554
inline
auto
&
555
__get_default_resource
(
)
556
{
557
#ifndef _GLIBCXX_HAS_GTHREADS
558
struct
type
{
559
using
value_type
=
memory_resource
*
;
560
explicit
type
(
value_type
__r
)
:
_M_r
(
__r
)
{ }
561
value_type
_M_r
;
562
value_type
load
(
)
const
{
return
_M_r
; }
563
value_type
exchange
(
value_type
__r
)
{
return
std
:
:
__exchange
(
_M_r
,
__r
)
; }
564
};
565
#else
566
using
type
=
atomic
<
memory_resource
*
>
;
567
#endif
568
alignas
(
type
)
static
unsigned
char
__buf
[
sizeof
(
type
)
];
569
static
type
*
__r
=
new
(
__buf
)
type
(
new_delete_resource
(
)
)
;
570
return
*
__r
;
571
}
572
/
/
/
@
endcond
573
574
/
/
/
Get
the
current
default
resource
.
575
inline
memory_resource
*
576
get_default_resource
(
)
noexcept
577
{
return
__get_default_resource
(
)
.
load
(
)
; }
578
579
/
/
/
Change
the
default
resource
and
return
the
previous
one
.
580
inline
memory_resource
*
581
set_default_resource(memory_resource* __r) noexcept
582
{
583
if
(
__r
==
nullptr
)
584
__r
=
new_delete_resource
(
)
;
585
return
__get_default_resource
(
)
.
exchange
(
__r
)
;
586
}
587
588
}
/
/
namespace
pmr
589
}
/
/
namespace
fundamentals_v2
590
}
/
/
namespace
experimental
591
592
_GLIBCXX_END_NAMESPACE_VERSION
593
}
/
/
namespace
std
594
#endif // C++14
595
#endif // _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE
experimental
memory_resource
Generated by
1.13.2