From Jason Turner

[container.requirements.general]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp5oj_j2g7/{from.md → to.md} +658 -2
tmp/tmp5oj_j2g7/{from.md → to.md} RENAMED
@@ -1,8 +1,10 @@
1
- #### General <a id="container.requirements.general">[[container.requirements.general]]</a>
2
 
3
- In subclause [[container.gen.reqmts]],
 
 
4
 
5
  - `X` denotes a container class containing objects of type `T`,
6
  - `a` denotes a value of type `X`,
7
  - `b` and `c` denote values of type (possibly const) `X`,
8
  - `i` and `j` denote values of type (possibly const) `X::iterator`,
@@ -19,5 +21,659 @@ containers:
19
  template<class R, class T>
20
  concept container-compatible-range = // exposition only
21
  ranges::input_range<R> && convertible_to<ranges::range_reference_t<R>, T>;
22
  ```
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### General containers <a id="container.requirements.general">[[container.requirements.general]]</a>
2
 
3
+ #### Introduction <a id="container.intro.reqmts">[[container.intro.reqmts]]</a>
4
+
5
+ In [[container.requirements.general]],
6
 
7
  - `X` denotes a container class containing objects of type `T`,
8
  - `a` denotes a value of type `X`,
9
  - `b` and `c` denote values of type (possibly const) `X`,
10
  - `i` and `j` denote values of type (possibly const) `X::iterator`,
 
21
  template<class R, class T>
22
  concept container-compatible-range = // exposition only
23
  ranges::input_range<R> && convertible_to<ranges::range_reference_t<R>, T>;
24
  ```
25
 
26
+ #### Container requirements <a id="container.reqmts">[[container.reqmts]]</a>
27
+
28
+ A type `X` meets the *container* requirements if the following types,
29
+ statements, and expressions are well-formed and have the specified
30
+ semantics.
31
+
32
+ ``` cpp
33
+ typename X::value_type
34
+ ```
35
+
36
+ *Result:* `T`
37
+
38
+ *Preconditions:* `T` is *Cpp17Erasable* from `X`
39
+ (see  [[container.alloc.reqmts]], below).
40
+
41
+ ``` cpp
42
+ typename X::reference
43
+ ```
44
+
45
+ *Result:* `T&`
46
+
47
+ ``` cpp
48
+ typename X::const_reference
49
+ ```
50
+
51
+ *Result:* `const T&`
52
+
53
+ ``` cpp
54
+ typename X::iterator
55
+ ```
56
+
57
+ *Result:* A type that meets the forward iterator
58
+ requirements [[forward.iterators]] with value type `T`. The type
59
+ `X::iterator` is convertible to `X::const_iterator`.
60
+
61
+ ``` cpp
62
+ typename X::const_iterator
63
+ ```
64
+
65
+ *Result:* A type that meets the requirements of a constant iterator and
66
+ those of a forward iterator with value type `T`.
67
+
68
+ ``` cpp
69
+ typename X::difference_type
70
+ ```
71
+
72
+ *Result:* A signed integer type, identical to the difference type of
73
+ `X::iterator` and `X::const_iterator`.
74
+
75
+ ``` cpp
76
+ typename X::size_type
77
+ ```
78
+
79
+ *Result:* An unsigned integer type that can represent any non-negative
80
+ value of `X::difference_type`.
81
+
82
+ ``` cpp
83
+ X u;
84
+ X u = X();
85
+ ```
86
+
87
+ *Ensures:* `u.empty()`
88
+
89
+ *Complexity:* Constant.
90
+
91
+ ``` cpp
92
+ X u(v);
93
+ X u = v;
94
+ ```
95
+
96
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X` (see below).
97
+
98
+ *Ensures:* `u == v`.
99
+
100
+ *Complexity:* Linear.
101
+
102
+ ``` cpp
103
+ X u(rv);
104
+ X u = rv;
105
+ ```
106
+
107
+ *Ensures:* `u` is equal to the value that `rv` had before this
108
+ construction.
109
+
110
+ *Complexity:* Linear for `array` and `inplace_vector` and constant for
111
+ all other standard containers.
112
+
113
+ ``` cpp
114
+ t = v
115
+ ```
116
+
117
+ *Result:* `X&`.
118
+
119
+ *Ensures:* `t == v`.
120
+
121
+ *Complexity:* Linear.
122
+
123
+ ``` cpp
124
+ t = rv
125
+ ```
126
+
127
+ *Result:* `X&`.
128
+
129
+ *Effects:* All existing elements of `t` are either move assigned to or
130
+ destroyed.
131
+
132
+ *Ensures:* If `t` and `rv` do not refer to the same object, `t` is equal
133
+ to the value that `rv` had before this assignment.
134
+
135
+ *Complexity:* Linear.
136
+
137
+ ``` cpp
138
+ a.~X()
139
+ ```
140
+
141
+ *Result:* `void`.
142
+
143
+ *Effects:* Destroys every element of `a`; any memory obtained is
144
+ deallocated.
145
+
146
+ *Complexity:* Linear.
147
+
148
+ ``` cpp
149
+ b.begin()
150
+ ```
151
+
152
+ *Result:* `iterator`; `const_iterator` for constant `b`.
153
+
154
+ *Returns:* An iterator referring to the first element in the container.
155
+
156
+ *Complexity:* Constant.
157
+
158
+ ``` cpp
159
+ b.end()
160
+ ```
161
+
162
+ *Result:* `iterator`; `const_iterator` for constant `b`.
163
+
164
+ *Returns:* An iterator which is the past-the-end value for the
165
+ container.
166
+
167
+ *Complexity:* Constant.
168
+
169
+ ``` cpp
170
+ b.cbegin()
171
+ ```
172
+
173
+ *Result:* `const_iterator`.
174
+
175
+ *Returns:* `const_cast<X const&>(b).begin()`
176
+
177
+ *Complexity:* Constant.
178
+
179
+ ``` cpp
180
+ b.cend()
181
+ ```
182
+
183
+ *Result:* `const_iterator`.
184
+
185
+ *Returns:* `const_cast<X const&>(b).end()`
186
+
187
+ *Complexity:* Constant.
188
+
189
+ ``` cpp
190
+ i <=> j
191
+ ```
192
+
193
+ *Result:* `strong_ordering`.
194
+
195
+ *Constraints:* `X::iterator` meets the random access iterator
196
+ requirements.
197
+
198
+ *Complexity:* Constant.
199
+
200
+ ``` cpp
201
+ c == b
202
+ ```
203
+
204
+ *Preconditions:* `T` meets the *Cpp17EqualityComparable* requirements.
205
+
206
+ *Result:* `bool`.
207
+
208
+ *Returns:* `equal(c.begin(), c.end(), b.begin(), b.end())`
209
+
210
+ [*Note 1*: The algorithm `equal` is defined in
211
+ [[alg.equal]]. — *end note*]
212
+
213
+ *Complexity:* Constant if `c.size() != b.size()`, linear otherwise.
214
+
215
+ *Remarks:* `==` is an equivalence relation.
216
+
217
+ ``` cpp
218
+ c != b
219
+ ```
220
+
221
+ *Effects:* Equivalent to `!(c == b)`.
222
+
223
+ ``` cpp
224
+ t.swap(s)
225
+ ```
226
+
227
+ *Result:* `void`.
228
+
229
+ *Effects:* Exchanges the contents of `t` and `s`.
230
+
231
+ *Complexity:* Linear for `array` and `inplace_vector`, and constant for
232
+ all other standard containers.
233
+
234
+ ``` cpp
235
+ swap(t, s)
236
+ ```
237
+
238
+ *Effects:* Equivalent to `t.swap(s)`.
239
+
240
+ ``` cpp
241
+ c.size()
242
+ ```
243
+
244
+ *Result:* `size_type`.
245
+
246
+ *Returns:* `distance(c.begin(), c.end())`, i.e., the number of elements
247
+ in the container.
248
+
249
+ *Complexity:* Constant.
250
+
251
+ *Remarks:* The number of elements is defined by the rules of
252
+ constructors, inserts, and erases.
253
+
254
+ ``` cpp
255
+ c.max_size()
256
+ ```
257
+
258
+ *Result:* `size_type`.
259
+
260
+ *Returns:* `distance(begin(), end())` for the largest possible
261
+ container.
262
+
263
+ *Complexity:* Constant.
264
+
265
+ ``` cpp
266
+ c.empty()
267
+ ```
268
+
269
+ *Result:* `bool`.
270
+
271
+ *Returns:* `c.begin() == c.end()`
272
+
273
+ *Complexity:* Constant.
274
+
275
+ *Remarks:* If the container is empty, then `c.empty()` is `true`.
276
+
277
+ In the expressions
278
+
279
+ ``` cpp
280
+ i == j
281
+ i != j
282
+ i < j
283
+ i <= j
284
+ i >= j
285
+ i > j
286
+ i <=> j
287
+ i - j
288
+ ```
289
+
290
+ where `i` and `j` denote objects of a container’s `iterator` type,
291
+ either or both may be replaced by an object of the container’s
292
+ `const_iterator` type referring to the same element with no change in
293
+ semantics.
294
+
295
+ Unless otherwise specified, all containers defined in this Clause obtain
296
+ memory using an allocator (see  [[allocator.requirements]]).
297
+
298
+ [*Note 1*: In particular, containers and iterators do not store
299
+ references to allocated elements other than through the allocator’s
300
+ pointer type, i.e., as objects of type `P` or
301
+ `pointer_traits<P>::template rebind<unspecified>`, where `P` is
302
+ `allocator_traits<allocator_type>::pointer`. — *end note*]
303
+
304
+ Copy constructors for these container types obtain an allocator by
305
+ calling
306
+ `allocator_traits<allocator_type>::select_on_container_copy_construction`
307
+ on the allocator belonging to the container being copied. Move
308
+ constructors obtain an allocator by move construction from the allocator
309
+ belonging to the container being moved. Such move construction of the
310
+ allocator shall not exit via an exception. All other constructors for
311
+ these container types take a `const allocator_type&` argument.
312
+
313
+ [*Note 2*: If an invocation of a constructor uses the default value of
314
+ an optional allocator argument, then the allocator type must support
315
+ value-initialization. — *end note*]
316
+
317
+ A copy of this allocator is used for any memory allocation and element
318
+ construction performed, by these constructors and by all other member
319
+ functions, during the lifetime of each container object or until the
320
+ allocator is replaced. The allocator may be replaced only via assignment
321
+ or `swap()`. Allocator replacement is performed by copy assignment, move
322
+ assignment, or swapping of the allocator only if
323
+
324
+ - `allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value`,
325
+ - `allocator_traits<allocator_type>::propagate_on_container_move_assignment::value`,
326
+ or
327
+ - `allocator_traits<allocator_type>::propagate_on_container_swap::value`
328
+
329
+ is `true` within the implementation of the corresponding container
330
+ operation. In all container types defined in this Clause, the member
331
+ `get_allocator()` returns a copy of the allocator used to construct the
332
+ container or, if that allocator has been replaced, a copy of the most
333
+ recent replacement.
334
+
335
+ The expression `a.swap(b)`, for containers `a` and `b` of a standard
336
+ container type other than `array` and `inplace_vector`, shall exchange
337
+ the values of `a` and `b` without invoking any move, copy, or swap
338
+ operations on the individual container elements. Any `Compare`, `Pred`,
339
+ or `Hash` types belonging to `a` and `b` shall meet the *Cpp17Swappable*
340
+ requirements and shall be exchanged by calling `swap` as described in 
341
+ [[swappable.requirements]]. If
342
+ `allocator_traits<allocator_type>::propagate_on_container_swap::value`
343
+ is `true`, then `allocator_type` shall meet the *Cpp17Swappable*
344
+ requirements and the allocators of `a` and `b` shall also be exchanged
345
+ by calling `swap` as described in  [[swappable.requirements]].
346
+ Otherwise, the allocators shall not be swapped, and the behavior is
347
+ undefined unless `a.get_allocator() == b.get_allocator()`. Every
348
+ iterator referring to an element in one container before the swap shall
349
+ refer to the same element in the other container after the swap. It is
350
+ unspecified whether an iterator with value `a.end()` before the swap
351
+ will have value `b.end()` after the swap.
352
+
353
+ Unless otherwise specified (see  [[associative.reqmts.except]],
354
+ [[unord.req.except]], [[deque.modifiers]], [[inplace.vector.modifiers]],
355
+ and [[vector.modifiers]]) all container types defined in this Clause
356
+ meet the following additional requirements:
357
+
358
+ - If an exception is thrown by an `insert()` or `emplace()` function
359
+ while inserting a single element, that function has no effects.
360
+ - If an exception is thrown by a `push_back()`, `push_front()`,
361
+ `emplace_back()`, or `emplace_front()` function, that function has no
362
+ effects.
363
+ - No `erase()`, `clear()`, `pop_back()` or `pop_front()` function throws
364
+ an exception.
365
+ - No copy constructor or assignment operator of a returned iterator
366
+ throws an exception.
367
+ - No `swap()` function throws an exception.
368
+ - No `swap()` function invalidates any references, pointers, or
369
+ iterators referring to the elements of the containers being swapped.
370
+ \[*Note 3*: The `end()` iterator does not refer to any element, so it
371
+ can be invalidated. — *end note*]
372
+
373
+ Unless otherwise specified (either explicitly or by defining a function
374
+ in terms of other functions), invoking a container member function or
375
+ passing a container as an argument to a library function shall not
376
+ invalidate iterators to, or change the values of, objects within that
377
+ container.
378
+
379
+ A *contiguous container* is a container whose member types `iterator`
380
+ and `const_iterator` meet the *Cpp17RandomAccessIterator* requirements
381
+ [[random.access.iterators]] and model `contiguous_iterator`
382
+ [[iterator.concept.contiguous]].
383
+
384
+ The behavior of certain container member functions and deduction guides
385
+ depends on whether types qualify as input iterators or allocators. The
386
+ extent to which an implementation determines that a type cannot be an
387
+ input iterator is unspecified, except that as a minimum integral types
388
+ shall not qualify as input iterators. Likewise, the extent to which an
389
+ implementation determines that a type cannot be an allocator is
390
+ unspecified, except that as a minimum a type `A` shall not qualify as an
391
+ allocator unless it meets both of the following conditions:
392
+
393
+ - The *qualified-id* `A::value_type` is valid and denotes a type
394
+ [[temp.deduct]].
395
+ - The expression `declval<A&>().allocate(size_t{})` is well-formed when
396
+ treated as an unevaluated operand.
397
+
398
+ #### Reversible container requirements <a id="container.rev.reqmts">[[container.rev.reqmts]]</a>
399
+
400
+ A type `X` meets the *reversible container* requirements if `X` meets
401
+ the container requirements, the iterator type of `X` belongs to the
402
+ bidirectional or random access iterator categories
403
+ [[iterator.requirements]], and the following types and expressions are
404
+ well-formed and have the specified semantics.
405
+
406
+ ``` cpp
407
+ typename X::reverse_iterator
408
+ ```
409
+
410
+ *Result:* The type `reverse_iterator<X::iterator>`, an iterator type
411
+ whose value type is `T`.
412
+
413
+ ``` cpp
414
+ typename X::const_reverse_iterator
415
+ ```
416
+
417
+ *Result:* The type `reverse_iterator<X::const_iterator>`, a constant
418
+ iterator type whose value type is `T`.
419
+
420
+ ``` cpp
421
+ a.rbegin()
422
+ ```
423
+
424
+ *Result:* `reverse_iterator`; `const_reverse_iterator` for constant `a`.
425
+
426
+ *Returns:* `reverse_iterator(end())`
427
+
428
+ *Complexity:* Constant.
429
+
430
+ ``` cpp
431
+ a.rend()
432
+ ```
433
+
434
+ *Result:* `reverse_iterator`; `const_reverse_iterator` for constant `a`.
435
+
436
+ *Returns:* `reverse_iterator(begin())`
437
+
438
+ *Complexity:* Constant.
439
+
440
+ ``` cpp
441
+ a.crbegin()
442
+ ```
443
+
444
+ *Result:* `const_reverse_iterator`.
445
+
446
+ *Returns:* `const_cast<X const&>(a).rbegin()`
447
+
448
+ *Complexity:* Constant.
449
+
450
+ ``` cpp
451
+ a.crend()
452
+ ```
453
+
454
+ *Result:* `const_reverse_iterator`.
455
+
456
+ *Returns:* `const_cast<X const&>(a).rend()`
457
+
458
+ *Complexity:* Constant.
459
+
460
+ #### Optional container requirements <a id="container.opt.reqmts">[[container.opt.reqmts]]</a>
461
+
462
+ The following operations are provided for some types of containers but
463
+ not others. Those containers for which the listed operations are
464
+ provided shall implement the semantics as described unless otherwise
465
+ stated. If the iterators passed to `lexicographical_compare_three_way`
466
+ meet the constexpr iterator requirements
467
+ [[iterator.requirements.general]] then the operations described below
468
+ are implemented by constexpr functions.
469
+
470
+ ``` cpp
471
+ a <=> b
472
+ ```
473
+
474
+ *Result:* *`synth-three-way-result`*`<X::value_type>`.
475
+
476
+ *Preconditions:* Either `T` models `three_way_comparable`, or `<` is
477
+ defined for values of type (possibly const) `T` and `<` is a total
478
+ ordering relationship.
479
+
480
+ *Returns:*
481
+ `lexicographical_compare_three_way(a.begin(), a.end(), b.begin(), b.end(), `*`synth-three-way`*`)`
482
+
483
+ [*Note 1*: The algorithm `lexicographical_compare_three_way` is defined
484
+ in [[algorithms]]. — *end note*]
485
+
486
+ *Complexity:* Linear.
487
+
488
+ #### Allocator-aware containers <a id="container.alloc.reqmts">[[container.alloc.reqmts]]</a>
489
+
490
+ Except for `array` and `inplace_vector`, all of the containers defined
491
+ in [[containers]], [[stacktrace.basic]], [[basic.string]], and
492
+ [[re.results]] meet the additional requirements of an
493
+ *allocator-aware container*, as described below.
494
+
495
+ Given an allocator type `A` and given a container type `X` having a
496
+ `value_type` identical to `T` and an `allocator_type` identical to
497
+ `allocator_traits<A>::rebind_alloc<T>` and given an lvalue `m` of type
498
+ `A`, a pointer `p` of type `T*`, an expression `v` that denotes an
499
+ lvalue of type `T` or `const T` or an rvalue of type `const T`, and an
500
+ rvalue `rv` of type `T`, the following terms are defined. If `X` is not
501
+ allocator-aware or is a specialization of `basic_string`, the terms
502
+ below are defined as if `A` were `allocator<T>` — no allocator object
503
+ needs to be created and user specializations of `allocator<T>` are not
504
+ instantiated:
505
+
506
+ - `T` is **Cpp17DefaultInsertable* into `X`* means that the following
507
+ expression is well-formed:
508
+ ``` cpp
509
+ allocator_traits<A>::construct(m, p)
510
+ ```
511
+ - An element of `X` is *default-inserted* if it is initialized by
512
+ evaluation of the expression
513
+ ``` cpp
514
+ allocator_traits<A>::construct(m, p)
515
+ ```
516
+
517
+ where `p` is the address of the uninitialized storage for the element
518
+ allocated within `X`.
519
+ - `T` is **Cpp17MoveInsertable* into `X`* means that the following
520
+ expression is well-formed:
521
+ ``` cpp
522
+ allocator_traits<A>::construct(m, p, rv)
523
+ ```
524
+
525
+ and its evaluation causes the following postcondition to hold: The
526
+ value of `*p` is equivalent to the value of `rv` before the
527
+ evaluation.
528
+ \[*Note 1*: `rv` remains a valid object. Its state is
529
+ unspecified. — *end note*]
530
+ - `T` is **Cpp17CopyInsertable* into `X`* means that, in addition to `T`
531
+ being *Cpp17MoveInsertable* into `X`, the following expression is
532
+ well-formed:
533
+ ``` cpp
534
+ allocator_traits<A>::construct(m, p, v)
535
+ ```
536
+
537
+ and its evaluation causes the following postcondition to hold: The
538
+ value of `v` is unchanged and is equivalent to `*p`.
539
+ - `T` is **Cpp17EmplaceConstructible* into `X` from `args`*, for zero or
540
+ more arguments `args`, means that the following expression is
541
+ well-formed:
542
+ ``` cpp
543
+ allocator_traits<A>::construct(m, p, args)
544
+ ```
545
+ - `T` is **Cpp17Erasable* from `X`* means that the following expression
546
+ is well-formed:
547
+ ``` cpp
548
+ allocator_traits<A>::destroy(m, p)
549
+ ```
550
+
551
+ [*Note 2*: A container calls
552
+ `allocator_traits<A>::construct(m, p, args)` to construct an element at
553
+ `p` using `args`, with `m == get_allocator()`. The default `construct`
554
+ in `allocator` will call `::new((void*)p) T(args)`, but specialized
555
+ allocators can choose a different definition. — *end note*]
556
+
557
+ In this subclause,
558
+
559
+ - `X` denotes an allocator-aware container class with a `value_type` of
560
+ `T` using an allocator of type `A`,
561
+ - `u` denotes a variable,
562
+ - `a` and `b` denote non-const lvalues of type `X`,
563
+ - `c` denotes an lvalue of type `const X`,
564
+ - `t` denotes an lvalue or a const rvalue of type `X`,
565
+ - `rv` denotes a non-const rvalue of type `X`, and
566
+ - `m` is a value of type `A`.
567
+
568
+ A type `X` meets the allocator-aware container requirements if `X` meets
569
+ the container requirements and the following types, statements, and
570
+ expressions are well-formed and have the specified semantics.
571
+
572
+ ``` cpp
573
+ typename X::allocator_type
574
+ ```
575
+
576
+ *Result:* `A`
577
+
578
+ *Mandates:* `allocator_type::value_type` is the same as `X::value_type`.
579
+
580
+ ``` cpp
581
+ c.get_allocator()
582
+ ```
583
+
584
+ *Result:* `A`
585
+
586
+ *Complexity:* Constant.
587
+
588
+ ``` cpp
589
+ X u;
590
+ X u = X();
591
+ ```
592
+
593
+ *Preconditions:* `A` meets the *Cpp17DefaultConstructible* requirements.
594
+
595
+ *Ensures:* `u.empty()` returns `true`, `u.get_allocator() == A()`.
596
+
597
+ *Complexity:* Constant.
598
+
599
+ ``` cpp
600
+ X u(m);
601
+ ```
602
+
603
+ *Ensures:* `u.empty()` returns `true`, `u.get_allocator() == m`.
604
+
605
+ *Complexity:* Constant.
606
+
607
+ ``` cpp
608
+ X u(t, m);
609
+ ```
610
+
611
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X`.
612
+
613
+ *Ensures:* `u == t`, `u.get_allocator() == m`.
614
+
615
+ *Complexity:* Linear.
616
+
617
+ ``` cpp
618
+ X u(rv);
619
+ ```
620
+
621
+ *Ensures:* `u` has the same elements as `rv` had before this
622
+ construction; the value of `u.get_allocator()` is the same as the value
623
+ of `rv.get_allocator()` before this construction.
624
+
625
+ *Complexity:* Constant.
626
+
627
+ ``` cpp
628
+ X u(rv, m);
629
+ ```
630
+
631
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `X`.
632
+
633
+ *Ensures:* `u` has the same elements, or copies of the elements, that
634
+ `rv` had before this construction, `u.get_allocator() == m`.
635
+
636
+ *Complexity:* Constant if `m == rv.get_allocator()`, otherwise linear.
637
+
638
+ ``` cpp
639
+ a = t
640
+ ```
641
+
642
+ *Result:* `X&`.
643
+
644
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X` and
645
+ *Cpp17CopyAssignable*.
646
+
647
+ *Ensures:* `a == t` is `true`.
648
+
649
+ *Complexity:* Linear.
650
+
651
+ ``` cpp
652
+ a = rv
653
+ ```
654
+
655
+ *Result:* `X&`.
656
+
657
+ *Preconditions:* If
658
+ `allocator_traits<allocator_type>::propagate_on_container_move_assignment::value`
659
+ is `false`, `T` is *Cpp17MoveInsertable* into `X` and
660
+ *Cpp17MoveAssignable*.
661
+
662
+ *Effects:* All existing elements of `a` are either move assigned to or
663
+ destroyed.
664
+
665
+ *Ensures:* If `a` and `rv` do not refer to the same object, `a` is equal
666
+ to the value that `rv` had before this assignment.
667
+
668
+ *Complexity:* Linear.
669
+
670
+ ``` cpp
671
+ a.swap(b)
672
+ ```
673
+
674
+ *Result:* `void`
675
+
676
+ *Effects:* Exchanges the contents of `a` and `b`.
677
+
678
+ *Complexity:* Constant.
679
+