From Jason Turner

[mem.poly.allocator.class]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpmk5x7xlp/{from.md → to.md} +271 -0
tmp/tmpmk5x7xlp/{from.md → to.md} RENAMED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Class template `polymorphic_allocator` <a id="mem.poly.allocator.class">[[mem.poly.allocator.class]]</a>
2
+
3
+ A specialization of class template `pmr::polymorphic_allocator` conforms
4
+ to the `Allocator` requirements ([[allocator.requirements]]).
5
+ Constructed with different memory resources, different instances of the
6
+ same specialization of `pmr::polymorphic_allocator` can exhibit entirely
7
+ different allocation behavior. This runtime polymorphism allows objects
8
+ that use `polymorphic_allocator` to behave as if they used different
9
+ allocator types at run time even though they use the same static
10
+ allocator type.
11
+
12
+ ``` cpp
13
+ template <class Tp>
14
+ class polymorphic_allocator {
15
+ memory_resource* memory_rsrc; // exposition only
16
+
17
+ public:
18
+ using value_type = Tp;
19
+
20
+ // [mem.poly.allocator.ctor], constructors
21
+ polymorphic_allocator() noexcept;
22
+ polymorphic_allocator(memory_resource* r);
23
+
24
+ polymorphic_allocator(const polymorphic_allocator& other) = default;
25
+
26
+ template <class U>
27
+ polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
28
+
29
+ polymorphic_allocator&
30
+ operator=(const polymorphic_allocator& rhs) = delete;
31
+
32
+ // [mem.poly.allocator.mem], member functions
33
+ Tp* allocate(size_t n);
34
+ void deallocate(Tp* p, size_t n);
35
+
36
+ template <class T, class... Args>
37
+ void construct(T* p, Args&&... args);
38
+
39
+ template <class T1, class T2, class... Args1, class... Args2>
40
+ void construct(pair<T1,T2>* p, piecewise_construct_t,
41
+ tuple<Args1...> x, tuple<Args2...> y);
42
+ template <class T1, class T2>
43
+ void construct(pair<T1,T2>* p);
44
+ template <class T1, class T2, class U, class V>
45
+ void construct(pair<T1,T2>* p, U&& x, V&& y);
46
+ template <class T1, class T2, class U, class V>
47
+ void construct(pair<T1,T2>* p, const pair<U, V>& pr);
48
+ template <class T1, class T2, class U, class V>
49
+ void construct(pair<T1,T2>* p, pair<U, V>&& pr);
50
+
51
+ template <class T>
52
+ void destroy(T* p);
53
+
54
+ polymorphic_allocator select_on_container_copy_construction() const;
55
+
56
+ memory_resource* resource() const;
57
+ };
58
+ ```
59
+
60
+ #### `polymorphic_allocator` constructors <a id="mem.poly.allocator.ctor">[[mem.poly.allocator.ctor]]</a>
61
+
62
+ ``` cpp
63
+ polymorphic_allocator() noexcept;
64
+ ```
65
+
66
+ *Effects:* Sets `memory_rsrc` to `get_default_resource()`.
67
+
68
+ ``` cpp
69
+ polymorphic_allocator(memory_resource* r);
70
+ ```
71
+
72
+ *Requires:* `r` is non-null.
73
+
74
+ *Effects:* Sets `memory_rsrc` to `r`.
75
+
76
+ *Throws:* Nothing.
77
+
78
+ [*Note 1*: This constructor provides an implicit conversion from
79
+ `memory_resource*`. — *end note*]
80
+
81
+ ``` cpp
82
+ template <class U>
83
+ polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
84
+ ```
85
+
86
+ *Effects:* Sets `memory_rsrc` to `other.resource()`.
87
+
88
+ #### `polymorphic_allocator` member functions <a id="mem.poly.allocator.mem">[[mem.poly.allocator.mem]]</a>
89
+
90
+ ``` cpp
91
+ Tp* allocate(size_t n);
92
+ ```
93
+
94
+ *Returns:* Equivalent to
95
+
96
+ ``` cpp
97
+ return static_cast<Tp*>(memory_rsrc->allocate(n * sizeof(Tp), alignof(Tp)));
98
+ ```
99
+
100
+ ``` cpp
101
+ void deallocate(Tp* p, size_t n);
102
+ ```
103
+
104
+ *Requires:* `p` was allocated from a memory resource `x`, equal to
105
+ `*memory_rsrc`, using `x.allocate(n * sizeof(Tp), alignof(Tp))`.
106
+
107
+ *Effects:* Equivalent to
108
+ `memory_rsrc->deallocate(p, n * sizeof(Tp), alignof(Tp))`.
109
+
110
+ *Throws:* Nothing.
111
+
112
+ ``` cpp
113
+ template <class T, class... Args>
114
+ void construct(T* p, Args&&... args);
115
+ ```
116
+
117
+ *Requires:* Uses-allocator construction of `T` with allocator
118
+ `resource()` (see  [[allocator.uses.construction]]) and constructor
119
+ arguments `std::forward<Args>(args)...` is well-formed.
120
+
121
+ [*Note 1*: Uses-allocator construction is always well formed for types
122
+ that do not use allocators. — *end note*]
123
+
124
+ *Effects:* Construct a `T` object in the storage whose address is
125
+ represented by `p` by uses-allocator construction with allocator
126
+ `resource()` and constructor arguments `std::forward<Args>(args)...`.
127
+
128
+ *Throws:* Nothing unless the constructor for `T` throws.
129
+
130
+ ``` cpp
131
+ template <class T1, class T2, class... Args1, class... Args2>
132
+ void construct(pair<T1,T2>* p, piecewise_construct_t,
133
+ tuple<Args1...> x, tuple<Args2...> y);
134
+ ```
135
+
136
+ [*Note 2*: This method and the `construct` methods that follow are
137
+ overloads for piecewise construction of
138
+ pairs ([[pairs.pair]]). — *end note*]
139
+
140
+ *Effects:* Let `xprime` be a `tuple` constructed from `x` according to
141
+ the appropriate rule from the following list.
142
+
143
+ [*Note 3*: The following description can be summarized as constructing
144
+ a `pair<T1, T2>` object in the storage whose address is represented by
145
+ `p`, as if by separate uses-allocator construction with allocator
146
+ `resource()` ([[allocator.uses.construction]]) of `p->first` using the
147
+ elements of `x` and `p->second` using the elements of
148
+ `y`. — *end note*]
149
+
150
+ - If `uses_allocator_v<T1,memory_resource*>` is `false`
151
+ and `is_constructible_v<T1,Args1...>` is `true`,
152
+ then `xprime` is `x`.
153
+ - Otherwise, if `uses_allocator_v<T1,memory_resource*>` is `true`
154
+ and `is_constructible_v<T1,allocator_arg_t,memory_resource*,Args1...>`
155
+ is `true`,
156
+ then `xprime` is
157
+ `tuple_cat(make_tuple(allocator_arg, resource()), std::move(x))`.
158
+ - Otherwise, if `uses_allocator_v<T1,memory_resource*>` is `true`
159
+ and `is_constructible_v<T1,Args1...,memory_resource*>` is `true`,
160
+ then `xprime` is `tuple_cat(std::move(x), make_tuple(resource()))`.
161
+ - Otherwise the program is ill formed.
162
+
163
+ Let `yprime` be a tuple constructed from `y` according to the
164
+ appropriate rule from the following list:
165
+
166
+ - If `uses_allocator_v<T2,memory_resource*>` is `false`
167
+ and `is_constructible_v<T2,Args2...>` is `true`,
168
+ then `yprime` is `y`.
169
+ - Otherwise, if `uses_allocator_v<T2,memory_resource*>` is `true`
170
+ and `is_constructible_v<T2,allocator_arg_t,memory_resource*,Args2...>`
171
+ is `true`,
172
+ then `yprime` is
173
+ `tuple_cat(make_tuple(allocator_arg, resource()), std::move(y))`.
174
+ - Otherwise, if `uses_allocator_v<T2,memory_resource*>` is `true`
175
+ and `is_constructible_v<T2,Args2...,memory_resource*>` is `true`,
176
+ then `yprime` is `tuple_cat(std::move(y), make_tuple(resource()))`.
177
+ - Otherwise the program is ill formed.
178
+
179
+ Then, using `piecewise_construct`, `xprime`, and `yprime` as the
180
+ constructor arguments, this function constructs a `pair<T1, T2>` object
181
+ in the storage whose address is represented by `p`.
182
+
183
+ ``` cpp
184
+ template <class T1, class T2>
185
+ void construct(pair<T1,T2>* p);
186
+ ```
187
+
188
+ *Effects:* Equivalent to:
189
+
190
+ ``` cpp
191
+ construct(p, piecewise_construct, tuple<>(), tuple<>());
192
+ ```
193
+
194
+ ``` cpp
195
+ template <class T1, class T2, class U, class V>
196
+ void construct(pair<T1,T2>* p, U&& x, V&& y);
197
+ ```
198
+
199
+ *Effects:* Equivalent to:
200
+
201
+ ``` cpp
202
+ construct(p, piecewise_construct,
203
+ forward_as_tuple(std::forward<U>(x)),
204
+ forward_as_tuple(std::forward<V>(y)));
205
+ ```
206
+
207
+ ``` cpp
208
+ template <class T1, class T2, class U, class V>
209
+ void construct(pair<T1,T2>* p, const pair<U, V>& pr);
210
+ ```
211
+
212
+ *Effects:* Equivalent to:
213
+
214
+ ``` cpp
215
+ construct(p, piecewise_construct,
216
+ forward_as_tuple(pr.first),
217
+ forward_as_tuple(pr.second));
218
+ ```
219
+
220
+ ``` cpp
221
+ template <class T1, class T2, class U, class V>
222
+ void construct(pair<T1,T2>* p, pair<U, V>&& pr);
223
+ ```
224
+
225
+ *Effects:* Equivalent to:
226
+
227
+ ``` cpp
228
+ construct(p, piecewise_construct,
229
+ forward_as_tuple(std::forward<U>(pr.first)),
230
+ forward_as_tuple(std::forward<V>(pr.second)));
231
+ ```
232
+
233
+ ``` cpp
234
+ template <class T>
235
+ void destroy(T* p);
236
+ ```
237
+
238
+ *Effects:* As if by `p->T̃()`.
239
+
240
+ ``` cpp
241
+ polymorphic_allocator select_on_container_copy_construction() const;
242
+ ```
243
+
244
+ *Returns:* `polymorphic_allocator()`.
245
+
246
+ [*Note 4*: The memory resource is not propagated. — *end note*]
247
+
248
+ ``` cpp
249
+ memory_resource* resource() const;
250
+ ```
251
+
252
+ *Returns:* `memory_rsrc`.
253
+
254
+ #### `polymorphic_allocator` equality <a id="mem.poly.allocator.eq">[[mem.poly.allocator.eq]]</a>
255
+
256
+ ``` cpp
257
+ template <class T1, class T2>
258
+ bool operator==(const polymorphic_allocator<T1>& a,
259
+ const polymorphic_allocator<T2>& b) noexcept;
260
+ ```
261
+
262
+ *Returns:* `*a.resource() == *b.resource()`.
263
+
264
+ ``` cpp
265
+ template <class T1, class T2>
266
+ bool operator!=(const polymorphic_allocator<T1>& a,
267
+ const polymorphic_allocator<T2>& b) noexcept;
268
+ ```
269
+
270
+ *Returns:* `!(a == b)`.
271
+