From Jason Turner

[polymorphic]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpwwv1a8ns/{from.md → to.md} +425 -0
tmp/tmpwwv1a8ns/{from.md → to.md} RENAMED
@@ -0,0 +1,425 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Class template `polymorphic` <a id="polymorphic">[[polymorphic]]</a>
2
+
3
+ #### General <a id="polymorphic.general">[[polymorphic.general]]</a>
4
+
5
+ A polymorphic object manages the lifetime of an owned object. A
6
+ polymorphic object may own objects of different types at different
7
+ points in its lifetime. A polymorphic object is *valueless* if it has no
8
+ owned object. A polymorphic object may become valueless only after it
9
+ has been moved from.
10
+
11
+ In every specialization `polymorphic<T, Allocator>`, if the type
12
+ `allocator_traits<Allocator>::value_type` is not the same type as `T`,
13
+ the program is ill-formed. Every object of type
14
+ `polymorphic<T, Allocator>` uses an object of type `Allocator` to
15
+ allocate and free storage for the owned object as needed.
16
+
17
+ Constructing an owned object of type `U` with `args...` using the
18
+ allocator `a` means calling
19
+ `allocator_traits<Allocator>::construct(a, p, args...)` where `args` is
20
+ an expression pack, `a` is an allocator, and *`p`* points to storage
21
+ suitable for an owned object of type `U`.
22
+
23
+ The member *`alloc`* is used for any memory allocation and element
24
+ construction performed by member functions during the lifetime of each
25
+ polymorphic value object, or until the allocator is replaced. The
26
+ allocator may be replaced only via assignment or `swap()`. `Allocator`
27
+ replacement is performed by copy assignment, move assignment, or
28
+ swapping of the allocator only if [[container.reqmts]]:
29
+
30
+ - `allocator_traits<Allocator>::propagate_on_container_copy_assignment::value`,
31
+ or
32
+ - `allocator_traits<Allocator>::propagate_on_container_move_assignment::value`,
33
+ or
34
+ - `allocator_traits<Allocator>::propagate_on_container_swap::value`
35
+
36
+ is `true` within the implementation of the corresponding `polymorphic`
37
+ operation.
38
+
39
+ A program that instantiates the definition of `polymorphic` for a
40
+ non-object type, an array type, `in_place_t`, a specialization of
41
+ `in_place_type_t`, or a cv-qualified type is ill-formed.
42
+
43
+ The template parameter `T` of `polymorphic` may be an incomplete type.
44
+
45
+ The template parameter `Allocator` of `polymorphic` shall meet the
46
+ requirements of *Cpp17Allocator*.
47
+
48
+ If a program declares an explicit or partial specialization of
49
+ `polymorphic`, the behavior is undefined.
50
+
51
+ #### Synopsis <a id="polymorphic.syn">[[polymorphic.syn]]</a>
52
+
53
+ ``` cpp
54
+ namespace std {
55
+ template<class T, class Allocator = allocator<T>>
56
+ class polymorphic {
57
+ public:
58
+ using value_type = T;
59
+ using allocator_type = Allocator;
60
+ using pointer = allocator_traits<Allocator>::pointer;
61
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
62
+
63
+ // [polymorphic.ctor], constructors
64
+ constexpr explicit polymorphic();
65
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a);
66
+ constexpr polymorphic(const polymorphic& other);
67
+ constexpr polymorphic(allocator_arg_t, const Allocator& a, const polymorphic& other);
68
+ constexpr polymorphic(polymorphic&& other) noexcept;
69
+ constexpr polymorphic(allocator_arg_t, const Allocator& a, polymorphic&& other)
70
+ noexcept(see below);
71
+ template<class U = T>
72
+ constexpr explicit polymorphic(U&& u);
73
+ template<class U = T>
74
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, U&& u);
75
+ template<class U, class... Ts>
76
+ constexpr explicit polymorphic(in_place_type_t<U>, Ts&&... ts);
77
+ template<class U, class... Ts>
78
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a,
79
+ in_place_type_t<U>, Ts&&... ts);
80
+ template<class U, class I, class... Us>
81
+ constexpr explicit polymorphic(in_place_type_t<U>, initializer_list<I> ilist, Us&&... us);
82
+ template<class U, class I, class... Us>
83
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a,
84
+ in_place_type_t<U>, initializer_list<I> ilist, Us&&... us);
85
+
86
+ // [polymorphic.dtor], destructor
87
+ constexpr ~polymorphic();
88
+
89
+ // [polymorphic.assign], assignment
90
+ constexpr polymorphic& operator=(const polymorphic& other);
91
+ constexpr polymorphic& operator=(polymorphic&& other) noexcept(see below);
92
+
93
+ // [polymorphic.obs], observers
94
+ constexpr const T& operator*() const noexcept;
95
+ constexpr T& operator*() noexcept;
96
+ constexpr const_pointer operator->() const noexcept;
97
+ constexpr pointer operator->() noexcept;
98
+ constexpr bool valueless_after_move() const noexcept;
99
+ constexpr allocator_type get_allocator() const noexcept;
100
+
101
+ // [polymorphic.swap], swap
102
+ constexpr void swap(polymorphic& other) noexcept(see below);
103
+ friend constexpr void swap(polymorphic& lhs, polymorphic& rhs) noexcept(see below);
104
+
105
+ private:
106
+ Allocator alloc = Allocator(); // exposition only
107
+ };
108
+ }
109
+ ```
110
+
111
+ #### Constructors <a id="polymorphic.ctor">[[polymorphic.ctor]]</a>
112
+
113
+ The following element applies to all functions in  [[polymorphic.ctor]]:
114
+
115
+ *Throws:* Nothing unless `allocator_traits<Allocator>::allocate` or
116
+ `allocator_traits<Allocator>::construct` throws.
117
+
118
+ ``` cpp
119
+ constexpr explicit polymorphic();
120
+ ```
121
+
122
+ *Constraints:* `is_default_constructible_v<Allocator>` is `true`.
123
+
124
+ *Mandates:*
125
+
126
+ - `is_default_constructible_v<T>` is `true`, and
127
+ - `is_copy_constructible_v<T>` is `true`.
128
+
129
+ *Effects:* Constructs an owned object of type `T` with an empty argument
130
+ list using the allocator *alloc*.
131
+
132
+ ``` cpp
133
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a);
134
+ ```
135
+
136
+ *Mandates:*
137
+
138
+ - `is_default_constructible_v<T>` is `true`, and
139
+ - `is_copy_constructible_v<T>` is `true`.
140
+
141
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. Constructs
142
+ an owned object of type `T` with an empty argument list using the
143
+ allocator *alloc*.
144
+
145
+ ``` cpp
146
+ constexpr polymorphic(const polymorphic& other);
147
+ ```
148
+
149
+ *Effects:* *alloc* is direct-non-list-initialized with
150
+ `allocator_traits<Allocator>::select_on_container_copy_construction(other.`*`alloc`*`)`.
151
+ If `other` is valueless, `*this` is valueless. Otherwise, constructs an
152
+ owned object of type `U`, where `U` is the type of the owned object in
153
+ `other`, with the owned object in `other` using the allocator *alloc*.
154
+
155
+ ``` cpp
156
+ constexpr polymorphic(allocator_arg_t, const Allocator& a, const polymorphic& other);
157
+ ```
158
+
159
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. If `other`
160
+ is valueless, `*this` is valueless. Otherwise, constructs an owned
161
+ object of type `U`, where `U` is the type of the owned object in
162
+ `other`, with the owned object in `other` using the allocator *alloc*.
163
+
164
+ ``` cpp
165
+ constexpr polymorphic(polymorphic&& other) noexcept;
166
+ ```
167
+
168
+ *Effects:* *alloc* is direct-non-list-initialized with
169
+ `std::move(other.`*`alloc`*`)`. If `other` is valueless, `*this` is
170
+ valueless. Otherwise, either `*this` takes ownership of the owned object
171
+ of `other` or, owns an object of the same type constructed from the
172
+ owned object of `other` considering that owned object as an rvalue,
173
+ using the allocator *alloc*.
174
+
175
+ ``` cpp
176
+ constexpr polymorphic(allocator_arg_t, const Allocator& a, polymorphic&& other)
177
+ noexcept(allocator_traits<Allocator>::is_always_equal::value);
178
+ ```
179
+
180
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. If `other`
181
+ is valueless, `*this` is valueless. Otherwise, if
182
+ *`alloc`*` == other.`*`alloc`* is `true`, either constructs an object of
183
+ type `polymorphic` that owns the owned object of `other`, making `other`
184
+ valueless; or, owns an object of the same type constructed from the
185
+ owned object of `other` considering that owned object as an rvalue.
186
+ Otherwise, if *`alloc`*` != other.`*`alloc`* is `true`, constructs an
187
+ object of type `polymorphic`, considering the owned object in `other` as
188
+ an rvalue, using the allocator *alloc*.
189
+
190
+ ``` cpp
191
+ template<class U = T>
192
+ constexpr explicit polymorphic(U&& u);
193
+ ```
194
+
195
+ *Constraints:* Where `UU` is `remove_cvref_t<U>`,
196
+
197
+ - `is_same_v<UU, polymorphic>` is `false`,
198
+ - `derived_from<UU, T>` is `true`,
199
+ - `is_constructible_v<UU, U>` is `true`,
200
+ - `is_copy_constructible_v<UU>` is `true`,
201
+ - `UU` is not a specialization of `in_place_type_t`, and
202
+ - `is_default_constructible_v<Allocator>` is `true`.
203
+
204
+ *Effects:* Constructs an owned object of type `UU` with
205
+ `std::forward<U>(u)` using the allocator *alloc*.
206
+
207
+ ``` cpp
208
+ template<class U = T>
209
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, U&& u);
210
+ ```
211
+
212
+ *Constraints:* Where `UU` is `remove_cvref_t<U>`,
213
+
214
+ - `is_same_v<UU, polymorphic>` is `false`,
215
+ - `derived_from<UU, T>` is `true`,
216
+ - `is_constructible_v<UU, U>` is `true`,
217
+ - `is_copy_constructible_v<UU>` is `true`, and
218
+ - `UU` is not a specialization of `in_place_type_t`.
219
+
220
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. Constructs
221
+ an owned object of type `UU` with `std::forward<U>(u)` using the
222
+ allocator *alloc*.
223
+
224
+ ``` cpp
225
+ template<class U, class... Ts>
226
+ constexpr explicit polymorphic(in_place_type_t<U>, Ts&&... ts);
227
+ ```
228
+
229
+ *Constraints:*
230
+
231
+ - `is_same_v<remove_cvref_t<U>, U>` is `true`,
232
+ - `derived_from<U, T>` is `true`,
233
+ - `is_constructible_v<U, Ts...>` is `true`,
234
+ - `is_copy_constructible_v<U>` is `true`, and
235
+ - `is_default_constructible_v<Allocator>` is `true`.
236
+
237
+ *Effects:* Constructs an owned object of type `U` with
238
+ `std::forward<Ts>(ts)...` using the allocator *alloc*.
239
+
240
+ ``` cpp
241
+ template<class U, class... Ts>
242
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a,
243
+ in_place_type_t<U>, Ts&&... ts);
244
+ ```
245
+
246
+ *Constraints:*
247
+
248
+ - `is_same_v<remove_cvref_t<U>, U>` is `true`,
249
+ - `derived_from<U, T>` is `true`,
250
+ - `is_constructible_v<U, Ts...>` is `true`, and
251
+ - `is_copy_constructible_v<U>` is `true`.
252
+
253
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. Constructs
254
+ an owned object of type `U` with `std::forward<Ts>(ts)...` using the
255
+ allocator *alloc*.
256
+
257
+ ``` cpp
258
+ template<class U, class I, class... Us>
259
+ constexpr explicit polymorphic(in_place_type_t<U>, initializer_list<I> ilist, Us&&... us);
260
+ ```
261
+
262
+ *Constraints:*
263
+
264
+ - `is_same_v<remove_cvref_t<U>, U>` is `true`,
265
+ - `derived_from<U, T>` is `true`,
266
+ - `is_constructible_v<U, initializer_list<I>&, Us...>` is `true`,
267
+ - `is_copy_constructible_v<U>` is `true`, and
268
+ - `is_default_constructible_v<Allocator>` is `true`.
269
+
270
+ *Effects:* Constructs an owned object of type `U` with the arguments
271
+ `ilist, std::forward<Us>(us)...` using the allocator *alloc*.
272
+
273
+ ``` cpp
274
+ template<class U, class I, class... Us>
275
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a,
276
+ in_place_type_t<U>, initializer_list<I> ilist, Us&&... us);
277
+ ```
278
+
279
+ *Constraints:*
280
+
281
+ - `is_same_v<remove_cvref_t<U>, U>` is `true`,
282
+ - `derived_from<U, T>` is `true`,
283
+ - `is_constructible_v<U, initializer_list<I>&, Us...>` is `true`, and
284
+ - `is_copy_constructible_v<U>` is `true`.
285
+
286
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. Constructs
287
+ an owned object of type `U` with the arguments
288
+ `ilist, std::forward<Us>(us)...` using the allocator *alloc*.
289
+
290
+ #### Destructor <a id="polymorphic.dtor">[[polymorphic.dtor]]</a>
291
+
292
+ ``` cpp
293
+ constexpr ~polymorphic();
294
+ ```
295
+
296
+ *Mandates:* `T` is a complete type.
297
+
298
+ *Effects:* If `*this` is not valueless, destroys the owned object using
299
+ `allocator_traits<Allocator>::destroy` and then the storage is
300
+ deallocated.
301
+
302
+ #### Assignment <a id="polymorphic.assign">[[polymorphic.assign]]</a>
303
+
304
+ ``` cpp
305
+ constexpr polymorphic& operator=(const polymorphic& other);
306
+ ```
307
+
308
+ *Mandates:* `T` is a complete type.
309
+
310
+ *Effects:* If `addressof(other) == this` is `true`, there are no
311
+ effects. Otherwise:
312
+
313
+ - The allocator needs updating if
314
+ `allocator_traits<Allocator>::propagate_on_container_copy_assignment::value`
315
+ is `true`.
316
+ - If `other` is not valueless, a new owned object is constructed in
317
+ `*this` using `allocator_traits<Allocator>::construct` with the owned
318
+ object from `other` as the argument, using either the allocator in
319
+ `*this` or the allocator in `other` if the allocator needs updating.
320
+ - The previously owned object in `*this`, if any, is destroyed using
321
+ `allocator_traits<Allocator>::destroy` and then the storage is
322
+ deallocated.
323
+ - If the allocator needs updating, the allocator in `*this` is replaced
324
+ with a copy of the allocator in `other`.
325
+
326
+ *Returns:* A reference to `*this`.
327
+
328
+ *Remarks:* If any exception is thrown, there are no effects on `*this`.
329
+
330
+ ``` cpp
331
+ constexpr polymorphic& operator=(polymorphic&& other)
332
+ noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
333
+ allocator_traits<Allocator>::is_always_equal::value);
334
+ ```
335
+
336
+ *Mandates:* If `allocator_traits<Allocator>::is_always_equal::value` is
337
+ `false`, `T` is a complete type.
338
+
339
+ *Effects:* If `addressof(other) == this` is `true`, there are no
340
+ effects. Otherwise:
341
+
342
+ - The allocator needs updating if
343
+ `allocator_traits<Allocator>::propagate_on_container_move_assignment::value`
344
+ is `true`.
345
+ - If *`alloc`*` == other.`*`alloc`* is `true`, swaps the owned objects
346
+ in `*this` and `other`; the owned object in `other`, if any, is then
347
+ destroyed using `allocator_traits<Allocator>::destroy` and then the
348
+ storage is deallocated.
349
+ - Otherwise, if *`alloc`*` != other.`*`alloc`* is `true`; if `other` is
350
+ not valueless, a new owned object is constructed in `*this` using
351
+ `allocator_traits<Allocator>::construct` with the owned object from
352
+ `other` as the argument as an rvalue, using either the allocator in
353
+ `*this` or the allocator in `other` if the allocator needs updating.
354
+ - The previously owned object in `*this`, if any, is destroyed using
355
+ `allocator_traits<Allocator>::destroy` and then the storage is
356
+ deallocated.
357
+ - If the allocator needs updating, the allocator in `*this` is replaced
358
+ with a copy of the allocator in `other`.
359
+
360
+ *Returns:* A reference to `*this`.
361
+
362
+ *Remarks:* If any exception is thrown, there are no effects on `*this`
363
+ or `other`.
364
+
365
+ #### Observers <a id="polymorphic.obs">[[polymorphic.obs]]</a>
366
+
367
+ ``` cpp
368
+ constexpr const T& operator*() const noexcept;
369
+ constexpr T& operator*() noexcept;
370
+ ```
371
+
372
+ *Preconditions:* `*this` is not valueless.
373
+
374
+ *Returns:* A reference to the owned object.
375
+
376
+ ``` cpp
377
+ constexpr const_pointer operator->() const noexcept;
378
+ constexpr pointer operator->() noexcept;
379
+ ```
380
+
381
+ *Preconditions:* `*this` is not valueless.
382
+
383
+ *Returns:* A pointer to the owned object.
384
+
385
+ ``` cpp
386
+ constexpr bool valueless_after_move() const noexcept;
387
+ ```
388
+
389
+ *Returns:* `true` if `*this` is valueless, otherwise `false`.
390
+
391
+ ``` cpp
392
+ constexpr allocator_type get_allocator() const noexcept;
393
+ ```
394
+
395
+ *Returns:* *alloc*.
396
+
397
+ #### Swap <a id="polymorphic.swap">[[polymorphic.swap]]</a>
398
+
399
+ ``` cpp
400
+ constexpr void swap(polymorphic& other)
401
+ noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
402
+ allocator_traits<Allocator>::is_always_equal::value);
403
+ ```
404
+
405
+ *Preconditions:* If
406
+ `allocator_traits<Allocator>::propagate_on_container_swap::value` is
407
+ `true`, then `Allocator` meets the *Cpp17Swappable* requirements.
408
+ Otherwise `get_allocator() == other.get_allocator()` is `true`.
409
+
410
+ *Effects:* Swaps the states of `*this` and `other`, exchanging owned
411
+ objects or valueless states. If
412
+ `allocator_traits<Allocator>::propagate_on_container_swap::value` is
413
+ `true`, then the allocators of `*this` and `other` are exchanged by
414
+ calling `swap` as described in  [[swappable.requirements]]. Otherwise,
415
+ the allocators are not swapped.
416
+
417
+ [*Note 1*: Does not call `swap` on the owned objects
418
+ directly. — *end note*]
419
+
420
+ ``` cpp
421
+ constexpr void swap(polymorphic& lhs, polymorphic& rhs) noexcept(noexcept(lhs.swap(rhs)));
422
+ ```
423
+
424
+ *Effects:* Equivalent to `lhs.swap(rhs)`.
425
+