From Jason Turner

[concepts]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpsxcm0fhs/{from.md → to.md} +1088 -0
tmp/tmpsxcm0fhs/{from.md → to.md} RENAMED
@@ -0,0 +1,1088 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Concepts library <a id="concepts">[[concepts]]</a>
2
+
3
+ ## General <a id="concepts.general">[[concepts.general]]</a>
4
+
5
+ This Clause describes library components that C++ programs may use to
6
+ perform compile-time validation of template arguments and perform
7
+ function dispatch based on properties of types. The purpose of these
8
+ concepts is to establish a foundation for equational reasoning in
9
+ programs.
10
+
11
+ The following subclauses describe language-related concepts, comparison
12
+ concepts, object concepts, and callable concepts as summarized in
13
+ [[concepts.summary]].
14
+
15
+ **Table: Fundamental concepts library summary** <a id="concepts.summary">[concepts.summary]</a>
16
+
17
+ | Subclause | | Header |
18
+ | --------------------- | ------------------------- | ------------ |
19
+ | [[concepts.equality]] | Equality preservation | |
20
+ | [[concepts.lang]] | Language-related concepts | `<concepts>` |
21
+ | [[concepts.compare]] | Comparison concepts | |
22
+ | [[concepts.object]] | Object concepts | |
23
+ | [[concepts.callable]] | Callable concepts | |
24
+
25
+
26
+ ## Equality preservation <a id="concepts.equality">[[concepts.equality]]</a>
27
+
28
+ An expression is *equality-preserving* if, given equal inputs, the
29
+ expression results in equal outputs. The inputs to an expression are the
30
+ set of the expression’s operands. The output of an expression is the
31
+ expression’s result and all operands modified by the expression. For the
32
+ purposes of this subclause, the operands of an expression are the
33
+ largest subexpressions that include only:
34
+
35
+ - an *id-expression* [[expr.prim.id]], and
36
+ - invocations of the library function templates `std::move`,
37
+ `std::forward`, and `std::declval` ([[forward]], [[declval]]).
38
+
39
+ [*Example 1*: The operands of the expression `a = std::move(b)` are `a`
40
+ and `std::move(b)`. — *end example*]
41
+
42
+ Not all input values need be valid for a given expression; e.g., for
43
+ integers `a` and `b`, the expression `a / b` is not well-defined when
44
+ `b` is `0`. This does not preclude the expression `a / b` being
45
+ equality-preserving. The *domain* of an expression is the set of input
46
+ values for which the expression is required to be well-defined.
47
+
48
+ Expressions required by this document to be equality-preserving are
49
+ further required to be stable: two evaluations of such an expression
50
+ with the same input objects are required to have equal outputs absent
51
+ any explicit intervening modification of those input objects.
52
+
53
+ [*Note 1*: This requirement allows generic code to reason about the
54
+ current values of objects based on knowledge of the prior values as
55
+ observed via equality-preserving expressions. It effectively forbids
56
+ spontaneous changes to an object, changes to an object from another
57
+ thread of execution, changes to an object as side effects of
58
+ non-modifying expressions, and changes to an object as side effects of
59
+ modifying a distinct object if those changes could be observable to a
60
+ library function via an equality-preserving expression that is required
61
+ to be valid for that object. — *end note*]
62
+
63
+ Expressions declared in a *requires-expression* in this document are
64
+ required to be equality-preserving, except for those annotated with the
65
+ comment “not required to be equality-preserving.” An expression so
66
+ annotated may be equality-preserving, but is not required to be so.
67
+
68
+ An expression that may alter the value of one or more of its inputs in a
69
+ manner observable to equality-preserving expressions is said to modify
70
+ those inputs. This document uses a notational convention to specify
71
+ which expressions declared in a *requires-expression* modify which
72
+ inputs: except where otherwise specified, an expression operand that is
73
+ a non-constant lvalue or rvalue may be modified. Operands that are
74
+ constant lvalues or rvalues are required to not be modified. For the
75
+ purposes of this subclause, the cv-qualification and value category of
76
+ each operand are determined by assuming that each template type
77
+ parameter denotes a cv-unqualified complete non-array object type.
78
+
79
+ Where a *requires-expression* declares an expression that is
80
+ non-modifying for some constant lvalue operand, additional variations of
81
+ that expression that accept a non-constant lvalue or (possibly constant)
82
+ rvalue for the given operand are also required except where such an
83
+ expression variation is explicitly required with differing semantics.
84
+ These *implicit expression variations* are required to meet the semantic
85
+ requirements of the declared expression. The extent to which an
86
+ implementation validates the syntax of the variations is unspecified.
87
+
88
+ [*Example 2*:
89
+
90
+ ``` cpp
91
+ template<class T> concept C = requires(T a, T b, const T c, const T d) {
92
+ c == d; // #1
93
+ a = std::move(b); // #2
94
+ a = c; // #3
95
+ };
96
+ ```
97
+
98
+ For the above example:
99
+
100
+ - Expression \#1 does not modify either of its operands, \#2 modifies
101
+ both of its operands, and \#3 modifies only its first operand `a`.
102
+ - Expression \#1 implicitly requires additional expression variations
103
+ that meet the requirements for `c == d` (including non-modification),
104
+ as if the expressions
105
+ ``` cpp
106
+ c == b;
107
+ c == std::move(d); c == std::move(b);
108
+ std::move(c) == d; std::move(c) == b;
109
+ std::move(c) == std::move(d); std::move(c) == std::move(b);
110
+
111
+ a == d; a == b;
112
+ a == std::move(d); a == std::move(b);
113
+ std::move(a) == d; std::move(a) == b;
114
+ std::move(a) == std::move(d); std::move(a) == std::move(b);
115
+ ```
116
+
117
+ had been declared as well.
118
+ - Expression \#3 implicitly requires additional expression variations
119
+ that meet the requirements for `a = c` (including non-modification of
120
+ the second operand), as if the expressions `a = b` and
121
+ `a = std::move(c)` had been declared. Expression \#3 does not
122
+ implicitly require an expression variation with a non-constant rvalue
123
+ second operand, since expression \#2 already specifies exactly such an
124
+ expression explicitly.
125
+
126
+ — *end example*]
127
+
128
+ [*Example 3*:
129
+
130
+ The following type `T` meets the explicitly stated syntactic
131
+ requirements of concept `C` above but does not meet the additional
132
+ implicit requirements:
133
+
134
+ ``` cpp
135
+ struct T {
136
+ bool operator==(const T&) const { return true; }
137
+ bool operator==(T&) = delete;
138
+ };
139
+ ```
140
+
141
+ `T` fails to meet the implicit requirements of `C`, so `T` satisfies but
142
+ does not model `C`. Since implementations are not required to validate
143
+ the syntax of implicit requirements, it is unspecified whether an
144
+ implementation diagnoses as ill-formed a program that requires `C<T>`.
145
+
146
+ — *end example*]
147
+
148
+ ## Header `<concepts>` synopsis <a id="concepts.syn">[[concepts.syn]]</a>
149
+
150
+ ``` cpp
151
+ namespace std {
152
+ // [concepts.lang], language-related concepts
153
+ // [concept.same], concept same_as
154
+ template<class T, class U>
155
+ concept same_as = see below;
156
+
157
+ // [concept.derived], concept derived_from
158
+ template<class Derived, class Base>
159
+ concept derived_from = see below;
160
+
161
+ // [concept.convertible], concept convertible_to
162
+ template<class From, class To>
163
+ concept convertible_to = see below;
164
+
165
+ // [concept.commonref], concept common_reference_with
166
+ template<class T, class U>
167
+ concept common_reference_with = see below;
168
+
169
+ // [concept.common], concept common_with
170
+ template<class T, class U>
171
+ concept common_with = see below;
172
+
173
+ // [concepts.arithmetic], arithmetic concepts
174
+ template<class T>
175
+ concept integral = see below;
176
+ template<class T>
177
+ concept signed_integral = see below;
178
+ template<class T>
179
+ concept unsigned_integral = see below;
180
+ template<class T>
181
+ concept floating_point = see below;
182
+
183
+ // [concept.assignable], concept assignable_from
184
+ template<class LHS, class RHS>
185
+ concept assignable_from = see below;
186
+
187
+ // [concept.swappable], concept swappable
188
+ namespace ranges {
189
+ inline namespace unspecified {
190
+ inline constexpr unspecified swap = unspecified;
191
+ }
192
+ }
193
+ template<class T>
194
+ concept swappable = see below;
195
+ template<class T, class U>
196
+ concept swappable_with = see below;
197
+
198
+ // [concept.destructible], concept destructible
199
+ template<class T>
200
+ concept destructible = see below;
201
+
202
+ // [concept.constructible], concept constructible_from
203
+ template<class T, class... Args>
204
+ concept constructible_from = see below;
205
+
206
+ // [concept.default.init], concept default_initializable
207
+ template<class T>
208
+ concept default_initializable = see below;
209
+
210
+ // [concept.moveconstructible], concept move_constructible
211
+ template<class T>
212
+ concept move_constructible = see below;
213
+
214
+ // [concept.copyconstructible], concept copy_constructible
215
+ template<class T>
216
+ concept copy_constructible = see below;
217
+
218
+ // [concepts.compare], comparison concepts
219
+ // [concept.equalitycomparable], concept equality_comparable
220
+ template<class T>
221
+ concept equality_comparable = see below;
222
+ template<class T, class U>
223
+ concept equality_comparable_with = see below;
224
+
225
+ // [concept.totallyordered], concept totally_ordered
226
+ template<class T>
227
+ concept totally_ordered = see below;
228
+ template<class T, class U>
229
+ concept totally_ordered_with = see below;
230
+
231
+ // [concepts.object], object concepts
232
+ template<class T>
233
+ concept movable = see below;
234
+ template<class T>
235
+ concept copyable = see below;
236
+ template<class T>
237
+ concept semiregular = see below;
238
+ template<class T>
239
+ concept regular = see below;
240
+
241
+ // [concepts.callable], callable concepts
242
+ // [concept.invocable], concept invocable
243
+ template<class F, class... Args>
244
+ concept invocable = see below;
245
+
246
+ // [concept.regularinvocable], concept regular_invocable
247
+ template<class F, class... Args>
248
+ concept regular_invocable = see below;
249
+
250
+ // [concept.predicate], concept predicate
251
+ template<class F, class... Args>
252
+ concept predicate = see below;
253
+
254
+ // [concept.relation], concept relation
255
+ template<class R, class T, class U>
256
+ concept relation = see below;
257
+
258
+ // [concept.equiv], concept equivalence_relation
259
+ template<class R, class T, class U>
260
+ concept equivalence_relation = see below;
261
+
262
+ // [concept.strictweakorder], concept strict_weak_order
263
+ template<class R, class T, class U>
264
+ concept strict_weak_order = see below;
265
+ }
266
+ ```
267
+
268
+ ## Language-related concepts <a id="concepts.lang">[[concepts.lang]]</a>
269
+
270
+ ### General <a id="concepts.lang.general">[[concepts.lang.general]]</a>
271
+
272
+ Subclause [[concepts.lang]] contains the definition of concepts
273
+ corresponding to language features. These concepts express relationships
274
+ between types, type classifications, and fundamental type properties.
275
+
276
+ ### Concept <a id="concept.same">[[concept.same]]</a>
277
+
278
+ ``` cpp
279
+ template<class T, class U>
280
+ concept same-as-impl = is_same_v<T, U>; // exposition only
281
+
282
+ template<class T, class U>
283
+ concept same_as = same-as-impl<T, U> && same-as-impl<U, T>;
284
+ ```
285
+
286
+ [*Note 1*: `same_as<T, U>` subsumes `same_as<U, T>` and vice
287
+ versa. — *end note*]
288
+
289
+ ### Concept <a id="concept.derived">[[concept.derived]]</a>
290
+
291
+ ``` cpp
292
+ template<class Derived, class Base>
293
+ concept derived_from =
294
+ is_base_of_v<Base, Derived> &&
295
+ is_convertible_v<const volatile Derived*, const volatile Base*>;
296
+ ```
297
+
298
+ [*Note 1*: `derived_from<Derived, Base>` is satisfied if and only if
299
+ `Derived` is publicly and unambiguously derived from `Base`, or
300
+ `Derived` and `Base` are the same class type ignoring
301
+ cv-qualifiers. — *end note*]
302
+
303
+ ### Concept <a id="concept.convertible">[[concept.convertible]]</a>
304
+
305
+ Given types `From` and `To` and an expression `E` such that
306
+ `decltype((E))` is `add_rvalue_reference_t<From>`,
307
+ `convertible_to<From, To>` requires `E` to be both implicitly and
308
+ explicitly convertible to type `To`. The implicit and explicit
309
+ conversions are required to produce equal results.
310
+
311
+ ``` cpp
312
+ template<class From, class To>
313
+ concept convertible_to =
314
+ is_convertible_v<From, To> &&
315
+ requires(add_rvalue_reference_t<From> (&f)()) {
316
+ static_cast<To>(f());
317
+ };
318
+ ```
319
+
320
+ Let `FromR` be `add_rvalue_reference_t<From>` and `test` be the invented
321
+ function:
322
+
323
+ ``` cpp
324
+ To test(FromR (&f)()) {
325
+ return f();
326
+ }
327
+ ```
328
+
329
+ and let `f` be a function with no arguments and return type `FromR` such
330
+ that `f()` is equality-preserving. Types `From` and `To` model
331
+ `convertible_to<From, To>` only if:
332
+
333
+ - `To` is not an object or reference-to-object type, or
334
+ `static_cast<To>(f())` is equal to `test(f)`.
335
+ - `FromR` is not a reference-to-object type, or
336
+ - If `FromR` is an rvalue reference to a non const-qualified type, the
337
+ resulting state of the object referenced by `f()` after either above
338
+ expression is valid but unspecified [[lib.types.movedfrom]].
339
+ - Otherwise, the object referred to by `f()` is not modified by either
340
+ above expression.
341
+
342
+ ### Concept <a id="concept.commonref">[[concept.commonref]]</a>
343
+
344
+ For two types `T` and `U`, if `common_reference_t<T, U>` is well-formed
345
+ and denotes a type `C` such that both `convertible_to<T, C>` and
346
+ `convertible_to<U, C>` are modeled, then `T` and `U` share a *common
347
+ reference type*, `C`.
348
+
349
+ [*Note 1*: `C` could be the same as `T`, or `U`, or it could be a
350
+ different type. `C` may be a reference type. — *end note*]
351
+
352
+ ``` cpp
353
+ template<class T, class U>
354
+ concept common_reference_with =
355
+ same_as<common_reference_t<T, U>, common_reference_t<U, T>> &&
356
+ convertible_to<T, common_reference_t<T, U>> &&
357
+ convertible_to<U, common_reference_t<T, U>>;
358
+ ```
359
+
360
+ Let `C` be `common_reference_t<T, U>`. Let `t1` and `t2` be
361
+ equality-preserving expressions [[concepts.equality]] such that
362
+ `decltype((t1))` and `decltype((t2))` are each `T`, and let `u1` and
363
+ `u2` be equality-preserving expressions such that `decltype((u1))` and
364
+ `decltype((u2))` are each `U`. `T` and `U` model
365
+ `common_reference_with<T, U>` only if:
366
+
367
+ - `C(t1)` equals `C(t2)` if and only if `t1` equals `t2`, and
368
+ - `C(u1)` equals `C(u2)` if and only if `u1` equals `u2`.
369
+
370
+ [*Note 1*: Users can customize the behavior of `common_reference_with`
371
+ by specializing the `basic_common_reference` class
372
+ template [[meta.trans.other]]. — *end note*]
373
+
374
+ ### Concept <a id="concept.common">[[concept.common]]</a>
375
+
376
+ If `T` and `U` can both be explicitly converted to some third type, `C`,
377
+ then `T` and `U` share a *common type*, `C`.
378
+
379
+ [*Note 1*: `C` could be the same as `T`, or `U`, or it could be a
380
+ different type. `C` might not be unique. — *end note*]
381
+
382
+ ``` cpp
383
+ template<class T, class U>
384
+ concept common_with =
385
+ same_as<common_type_t<T, U>, common_type_t<U, T>> &&
386
+ requires {
387
+ static_cast<common_type_t<T, U>>(declval<T>());
388
+ static_cast<common_type_t<T, U>>(declval<U>());
389
+ } &&
390
+ common_reference_with<
391
+ add_lvalue_reference_t<const T>,
392
+ add_lvalue_reference_t<const U>> &&
393
+ common_reference_with<
394
+ add_lvalue_reference_t<common_type_t<T, U>>,
395
+ common_reference_t<
396
+ add_lvalue_reference_t<const T>,
397
+ add_lvalue_reference_t<const U>>>;
398
+ ```
399
+
400
+ Let `C` be `common_type_t<T, U>`. Let `t1` and `t2` be
401
+ equality-preserving expressions [[concepts.equality]] such that
402
+ `decltype((t1))` and `decltype((t2))` are each `T`, and let `u1` and
403
+ `u2` be equality-preserving expressions such that `decltype((u1))` and
404
+ `decltype((u2))` are each `U`. `T` and `U` model `common_with<T, U>`
405
+ only if:
406
+
407
+ - `C(t1)` equals `C(t2)` if and only if `t1` equals `t2`, and
408
+ - `C(u1)` equals `C(u2)` if and only if `u1` equals `u2`.
409
+
410
+ [*Note 1*: Users can customize the behavior of `common_with` by
411
+ specializing the `common_type` class
412
+ template [[meta.trans.other]]. — *end note*]
413
+
414
+ ### Arithmetic concepts <a id="concepts.arithmetic">[[concepts.arithmetic]]</a>
415
+
416
+ ``` cpp
417
+ template<class T>
418
+ concept integral = is_integral_v<T>;
419
+ template<class T>
420
+ concept signed_integral = integral<T> && is_signed_v<T>;
421
+ template<class T>
422
+ concept unsigned_integral = integral<T> && !signed_integral<T>;
423
+ template<class T>
424
+ concept floating_point = is_floating_point_v<T>;
425
+ ```
426
+
427
+ [*Note 1*: `signed_integral` can be modeled even by types that are not
428
+ signed integer types [[basic.fundamental]]; for example,
429
+ `char`. — *end note*]
430
+
431
+ [*Note 2*: `unsigned_integral` can be modeled even by types that are
432
+ not unsigned integer types [[basic.fundamental]]; for example,
433
+ `bool`. — *end note*]
434
+
435
+ ### Concept <a id="concept.assignable">[[concept.assignable]]</a>
436
+
437
+ ``` cpp
438
+ template<class LHS, class RHS>
439
+ concept assignable_from =
440
+ is_lvalue_reference_v<LHS> &&
441
+ common_reference_with<const remove_reference_t<LHS>&, const remove_reference_t<RHS>&> &&
442
+ requires(LHS lhs, RHS&& rhs) {
443
+ { lhs = std::forward<RHS>(rhs) } -> same_as<LHS>;
444
+ };
445
+ ```
446
+
447
+ Let:
448
+
449
+ - `lhs` be an lvalue that refers to an object `lcopy` such that
450
+ `decltype((lhs))` is `LHS`,
451
+ - `rhs` be an expression such that `decltype((rhs))` is `RHS`, and
452
+ - `rcopy` be a distinct object that is equal to `rhs`.
453
+
454
+ `LHS` and `RHS` model `assignable_from<LHS, RHS>` only if
455
+
456
+ - `addressof(lhs = rhs) == addressof(lcopy)`.
457
+ - After evaluating `lhs = rhs`:
458
+ - `lhs` is equal to `rcopy`, unless `rhs` is a non-const xvalue that
459
+ refers to `lcopy`.
460
+ - If `rhs` is a non-`const` xvalue, the resulting state of the object
461
+ to which it refers is valid but unspecified [[lib.types.movedfrom]].
462
+ - Otherwise, if `rhs` is a glvalue, the object to which it refers is
463
+ not modified.
464
+
465
+ [*Note 1*: Assignment need not be a total
466
+ function [[structure.requirements]]; in particular, if assignment to an
467
+ object `x` can result in a modification of some other object `y`, then
468
+ `x = y` is likely not in the domain of `=`. — *end note*]
469
+
470
+ ### Concept <a id="concept.swappable">[[concept.swappable]]</a>
471
+
472
+ Let `t1` and `t2` be equality-preserving expressions that denote
473
+ distinct equal objects of type `T`, and let `u1` and `u2` similarly
474
+ denote distinct equal objects of type `U`.
475
+
476
+ [*Note 1*: `t1` and `u1` can denote distinct objects, or the same
477
+ object. — *end note*]
478
+
479
+ An operation *exchanges the values* denoted by `t1` and `u1` if and only
480
+ if the operation modifies neither `t2` nor `u2` and:
481
+
482
+ - If `T` and `U` are the same type, the result of the operation is that
483
+ `t1` equals `u2` and `u1` equals `t2`.
484
+ - If `T` and `U` are different types and
485
+ `common_reference_with<decltype((t1)), decltype((u1))>` is modeled,
486
+ the result of the operation is that `C(t1)` equals `C(u2)` and `C(u1)`
487
+ equals `C(t2)` where `C` is
488
+ `common_reference_t<decltype((t1)), decltype((u1))>`.
489
+
490
+ The name `ranges::swap` denotes a customization point object
491
+ [[customization.point.object]]. The expression `ranges::swap(E1, E2)`
492
+ for subexpressions `E1` and `E2` is expression-equivalent to an
493
+ expression `S` determined as follows:
494
+
495
+ - `S` is `(void)swap(E1, E2)`[^1] if `E1` or `E2` has class or
496
+ enumeration type [[basic.compound]] and that expression is valid, with
497
+ overload resolution performed in a context that includes the
498
+ declaration
499
+ ``` cpp
500
+ template<class T>
501
+ void swap(T&, T&) = delete;
502
+ ```
503
+
504
+ and does not include a declaration of `ranges::swap`. If the function
505
+ selected by overload resolution does not exchange the values denoted
506
+ by `E1` and `E2`, the program is ill-formed, no diagnostic required.
507
+ - Otherwise, if `E1` and `E2` are lvalues of array types
508
+ [[basic.compound]] with equal extent and `ranges::swap(*E1, *E2)` is a
509
+ valid expression, `S` is `(void)ranges::swap_ranges(E1, E2)`, except
510
+ that `noexcept(S)` is equal to `noexcept({}ranges::swap(*E1, *E2))`.
511
+ - Otherwise, if `E1` and `E2` are lvalues of the same type `T` that
512
+ models `move_constructible<T>` and `assignable_from<T&, T>`, `S` is an
513
+ expression that exchanges the denoted values. `S` is a constant
514
+ expression if
515
+ - `T` is a literal type [[basic.types]],
516
+ - both `E1 = std::move(E2)` and `E2 = std::move(E1)` are constant
517
+ subexpressions [[defns.const.subexpr]], and
518
+ - the full-expressions of the initializers in the declarations
519
+ ``` cpp
520
+ T t1(std::move(E1));
521
+ T t2(std::move(E2));
522
+ ```
523
+
524
+ are constant subexpressions.
525
+
526
+ `noexcept(S)` is equal to
527
+ `is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>`.
528
+ - Otherwise, `ranges::swap(E1, E2)` is ill-formed. \[*Note 2*: This case
529
+ can result in substitution failure when `ranges::swap(E1, E2)` appears
530
+ in the immediate context of a template instantiation. — *end note*]
531
+
532
+ [*Note 3*: Whenever `ranges::swap(E1, E2)` is a valid expression, it
533
+ exchanges the values denoted by `E1` and `E2` and has type
534
+ `void`. — *end note*]
535
+
536
+ ``` cpp
537
+ template<class T>
538
+ concept swappable = requires(T& a, T& b) { ranges::swap(a, b); };
539
+ ```
540
+
541
+ ``` cpp
542
+ template<class T, class U>
543
+ concept swappable_with =
544
+ common_reference_with<T, U> &&
545
+ requires(T&& t, U&& u) {
546
+ ranges::swap(std::forward<T>(t), std::forward<T>(t));
547
+ ranges::swap(std::forward<U>(u), std::forward<U>(u));
548
+ ranges::swap(std::forward<T>(t), std::forward<U>(u));
549
+ ranges::swap(std::forward<U>(u), std::forward<T>(t));
550
+ };
551
+ ```
552
+
553
+ [*Note 4*: The semantics of the `swappable` and `swappable_with`
554
+ concepts are fully defined by the `ranges::swap` customization
555
+ point. — *end note*]
556
+
557
+ [*Example 1*:
558
+
559
+ User code can ensure that the evaluation of `swap` calls is performed in
560
+ an appropriate context under the various conditions as follows:
561
+
562
+ ``` cpp
563
+ #include <cassert>
564
+ #include <concepts>
565
+ #include <utility>
566
+
567
+ namespace ranges = std::ranges;
568
+
569
+ template<class T, std::swappable_with<T> U>
570
+ void value_swap(T&& t, U&& u) {
571
+ ranges::swap(std::forward<T>(t), std::forward<U>(u));
572
+ }
573
+
574
+ template<std::swappable T>
575
+ void lv_swap(T& t1, T& t2) {
576
+ ranges::swap(t1, t2);
577
+ }
578
+
579
+ namespace N {
580
+ struct A { int m; };
581
+ struct Proxy {
582
+ A* a;
583
+ Proxy(A& a) : a{&a} {}
584
+ friend void swap(Proxy x, Proxy y) {
585
+ ranges::swap(*x.a, *y.a);
586
+ }
587
+ };
588
+ Proxy proxy(A& a) { return Proxy{ a }; }
589
+ }
590
+
591
+ int main() {
592
+ int i = 1, j = 2;
593
+ lv_swap(i, j);
594
+ assert(i == 2 && j == 1);
595
+
596
+ N::A a1 = { 5 }, a2 = { -5 };
597
+ value_swap(a1, proxy(a2));
598
+ assert(a1.m == -5 && a2.m == 5);
599
+ }
600
+ ```
601
+
602
+ — *end example*]
603
+
604
+ ### Concept <a id="concept.destructible">[[concept.destructible]]</a>
605
+
606
+ The `destructible` concept specifies properties of all types, instances
607
+ of which can be destroyed at the end of their lifetime, or reference
608
+ types.
609
+
610
+ ``` cpp
611
+ template<class T>
612
+ concept destructible = is_nothrow_destructible_v<T>;
613
+ ```
614
+
615
+ [*Note 1*: Unlike the *Cpp17Destructible*
616
+ requirements ([[cpp17.destructible]]), this concept forbids destructors
617
+ that are potentially throwing, even if a particular invocation of the
618
+ destructor does not actually throw. — *end note*]
619
+
620
+ ### Concept <a id="concept.constructible">[[concept.constructible]]</a>
621
+
622
+ The `constructible_from` concept constrains the initialization of a
623
+ variable of a given type with a particular set of argument types.
624
+
625
+ ``` cpp
626
+ template<class T, class... Args>
627
+ concept constructible_from = destructible<T> && is_constructible_v<T, Args...>;
628
+ ```
629
+
630
+ ### Concept <a id="concept.default.init">[[concept.default.init]]</a>
631
+
632
+ ``` cpp
633
+ template<class T>
634
+ inline constexpr bool is-default-initializable = see below; // exposition only
635
+
636
+ template<class T>
637
+ concept default_initializable = constructible_from<T> &&
638
+ requires { T{}; } &&
639
+ is-default-initializable<T>;
640
+ ```
641
+
642
+ For a type `T`, *`is-default-initializable`*`<T>` is `true` if and only
643
+ if the variable definition
644
+
645
+ ``` cpp
646
+ T t;
647
+ ```
648
+
649
+ is well-formed for some invented variable `t`; otherwise it is `false`.
650
+ Access checking is performed as if in a context unrelated to `T`. Only
651
+ the validity of the immediate context of the variable initialization is
652
+ considered.
653
+
654
+ ### Concept <a id="concept.moveconstructible">[[concept.moveconstructible]]</a>
655
+
656
+ ``` cpp
657
+ template<class T>
658
+ concept move_constructible = constructible_from<T, T> && convertible_to<T, T>;
659
+ ```
660
+
661
+ If `T` is an object type, then let `rv` be an rvalue of type `T` and
662
+ `u2` a distinct object of type `T` equal to `rv`. `T` models
663
+ `move_constructible` only if
664
+
665
+ - After the definition `T u = rv;`, `u` is equal to `u2`.
666
+ - `T(rv)` is equal to `u2`.
667
+ - If `T` is not `const`, `rv`’s resulting state is valid but
668
+ unspecified [[lib.types.movedfrom]]; otherwise, it is unchanged.
669
+
670
+ ### Concept <a id="concept.copyconstructible">[[concept.copyconstructible]]</a>
671
+
672
+ ``` cpp
673
+ template<class T>
674
+ concept copy_constructible =
675
+ move_constructible<T> &&
676
+ constructible_from<T, T&> && convertible_to<T&, T> &&
677
+ constructible_from<T, const T&> && convertible_to<const T&, T> &&
678
+ constructible_from<T, const T> && convertible_to<const T, T>;
679
+ ```
680
+
681
+ If `T` is an object type, then let `v` be an lvalue of type (possibly
682
+ `const`) `T` or an rvalue of type `const T`. `T` models
683
+ `copy_constructible` only if
684
+
685
+ - After the definition `T u = v;`, `u` is equal to `v`
686
+ [[concepts.equality]] and `v` is not modified.
687
+ - `T(v)` is equal to `v` and does not modify `v`.
688
+
689
+ ## Comparison concepts <a id="concepts.compare">[[concepts.compare]]</a>
690
+
691
+ ### General <a id="concepts.compare.general">[[concepts.compare.general]]</a>
692
+
693
+ Subclause [[concepts.compare]] describes concepts that establish
694
+ relationships and orderings on values of possibly differing object
695
+ types.
696
+
697
+ ### Boolean testability <a id="concept.booleantestable">[[concept.booleantestable]]</a>
698
+
699
+ The exposition-only `boolean-testable` concept specifies the
700
+ requirements on expressions that are convertible to `bool` and for which
701
+ the logical operators  ([[expr.log.and]], [[expr.log.or]],
702
+ [[expr.unary.op]]) have the conventional semantics.
703
+
704
+ ``` cpp
705
+ template<class T>
706
+ concept boolean-testable-impl = convertible_to<T, bool>; // exposition only
707
+ ```
708
+
709
+ Let `e` be an expression such that `decltype((e))` is `T`. `T` models
710
+ `boolean-testable-impl` only if:
711
+
712
+ - either `remove_cvref_t<T>` is not a class type, or name lookup for the
713
+ names `operator&&` and `operator||` within the scope of
714
+ `remove_cvref_t<T>` as if by class member access lookup
715
+ [[class.member.lookup]] results in an empty declaration set; and
716
+ - name lookup for the names `operator&&` and `operator||` in the
717
+ associated namespaces and entities of `T` [[basic.lookup.argdep]]
718
+ finds no disqualifying declaration (defined below).
719
+
720
+ A *disqualifying parameter* is a function parameter whose declared type
721
+ `P`
722
+
723
+ - is not dependent on a template parameter, and there exists an implicit
724
+ conversion sequence [[over.best.ics]] from `e` to `P`; or
725
+ - is dependent on one or more template parameters, and either
726
+ - `P` contains no template parameter that participates in template
727
+ argument deduction [[temp.deduct.type]], or
728
+ - template argument deduction using the rules for deducing template
729
+ arguments in a function call [[temp.deduct.call]] and `e` as the
730
+ argument succeeds.
731
+
732
+ A *key parameter* of a function template `D` is a function parameter of
733
+ type cv `X` or reference thereto, where `X` names a specialization of a
734
+ class template that is a member of the same namespace as `D`, and `X`
735
+ contains at least one template parameter that participates in template
736
+ argument deduction.
737
+
738
+ [*Example 1*:
739
+
740
+ In
741
+
742
+ ``` cpp
743
+ namespace Z {
744
+ template<class> struct C {};
745
+ template<class T>
746
+ void operator&&(C<T> x, T y);
747
+ template<class T>
748
+ void operator||(C<type_identity_t<T>> x, T y);
749
+ }
750
+ ```
751
+
752
+ the declaration of `Z::operator&&` contains one key parameter, `C<T> x`,
753
+ and the declaration of `Z::operator||` contains no key parameters.
754
+
755
+ — *end example*]
756
+
757
+ A *disqualifying declaration* is
758
+
759
+ - a (non-template) function declaration that contains at least one
760
+ disqualifying parameter; or
761
+ - a function template declaration that contains at least one
762
+ disqualifying parameter, where
763
+ - at least one disqualifying parameter is a key parameter; or
764
+ - the declaration contains no key parameters; or
765
+ - the declaration declares a function template that is not visible in
766
+ its namespace [[namespace.memdef]].
767
+
768
+ [*Note 1*: The intention is to ensure that given two types `T1` and
769
+ `T2` that each model `boolean-testable-impl`, the `&&` and `||`
770
+ operators within the expressions `declval<T1>() && declval<T2>()` and
771
+ `declval<T1>() || declval<T2>()` resolve to the corresponding built-in
772
+ operators. — *end note*]
773
+
774
+ ``` cpp
775
+ template<class T>
776
+ concept boolean-testable = // exposition only
777
+ boolean-testable-impl<T> && requires (T&& t) {
778
+ { !std::forward<T>(t) } -> boolean-testable-impl;
779
+ };
780
+ ```
781
+
782
+ Let `e` be an expression such that `decltype((e))` is `T`. `T` models
783
+ `boolean-testable` only if `bool(e) == !bool(!e)`.
784
+
785
+ [*Example 2*: The types `bool`, `true_type` [[meta.type.synop]],
786
+ `int*`, and `bitset<N>::reference` [[template.bitset]] model
787
+ *`boolean-testable`*. — *end example*]
788
+
789
+ ### Concept <a id="concept.equalitycomparable">[[concept.equalitycomparable]]</a>
790
+
791
+ ``` cpp
792
+ template<class T, class U>
793
+ concept weakly-equality-comparable-with = // exposition only
794
+ requires(const remove_reference_t<T>& t,
795
+ const remove_reference_t<U>& u) {
796
+ { t == u } -> boolean-testable;
797
+ { t != u } -> boolean-testable;
798
+ { u == t } -> boolean-testable;
799
+ { u != t } -> boolean-testable;
800
+ };
801
+ ```
802
+
803
+ Given types `T` and `U`, let `t` and `u` be lvalues of types
804
+ `const remove_reference_t<T>` and `const remove_reference_t<U>`
805
+ respectively. `T` and `U` model
806
+ *`weakly-equality-comparable-with`*`<T, U>` only if
807
+
808
+ - `t == u`, `u == t`, `t != u`, and `u != t` have the same domain.
809
+ - `bool(u == t) == bool(t == u)`.
810
+ - `bool(t != u) == !bool(t == u)`.
811
+ - `bool(u != t) == bool(t != u)`.
812
+
813
+ ``` cpp
814
+ template<class T>
815
+ concept equality_comparable = weakly-equality-comparable-with<T, T>;
816
+ ```
817
+
818
+ Let `a` and `b` be objects of type `T`. `T` models `equality_comparable`
819
+ only if `bool(a == b)` is `true` when `a` is equal to `b`
820
+ [[concepts.equality]], and `false` otherwise.
821
+
822
+ [*Note 1*: The requirement that the expression `a == b` is
823
+ equality-preserving implies that `==` is transitive and
824
+ symmetric. — *end note*]
825
+
826
+ ``` cpp
827
+ template<class T, class U>
828
+ concept equality_comparable_with =
829
+ equality_comparable<T> && equality_comparable<U> &&
830
+ common_reference_with<const remove_reference_t<T>&, const remove_reference_t<U>&> &&
831
+ equality_comparable<
832
+ common_reference_t<
833
+ const remove_reference_t<T>&,
834
+ const remove_reference_t<U>&>> &&
835
+ weakly-equality-comparable-with<T, U>;
836
+ ```
837
+
838
+ Given types `T` and `U`, let `t` be an lvalue of type
839
+ `const remove_reference_t<T>`, `u` be an lvalue of type
840
+ `const remove_reference_t<U>`, and `C` be:
841
+
842
+ ``` cpp
843
+ common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&>
844
+ ```
845
+
846
+ `T` and `U` model `equality_comparable_with<T, U>` only if
847
+ `bool(t == u) == bool(C(t) == C(u))`.
848
+
849
+ ### Concept <a id="concept.totallyordered">[[concept.totallyordered]]</a>
850
+
851
+ ``` cpp
852
+ template<class T>
853
+ concept totally_ordered =
854
+ equality_comparable<T> && partially-ordered-with<T, T>;
855
+ ```
856
+
857
+ Given a type `T`, let `a`, `b`, and `c` be lvalues of type
858
+ `const remove_reference_t<T>`. `T` models `totally_ordered` only if
859
+
860
+ - Exactly one of `bool(a < b)`, `bool(a > b)`, or `bool(a == b)` is
861
+ `true`.
862
+ - If `bool(a < b)` and `bool(b < c)`, then `bool(a < c)`.
863
+ - `bool(a <= b) == !bool(b < a)`.
864
+ - `bool(a >= b) == !bool(a < b)`.
865
+
866
+ ``` cpp
867
+ template<class T, class U>
868
+ concept totally_ordered_with =
869
+ totally_ordered<T> && totally_ordered<U> &&
870
+ equality_comparable_with<T, U> &&
871
+ totally_ordered<
872
+ common_reference_t<
873
+ const remove_reference_t<T>&,
874
+ const remove_reference_t<U>&>> &&
875
+ partially-ordered-with<T, U>;
876
+ ```
877
+
878
+ Given types `T` and `U`, let `t` be an lvalue of type
879
+ `const remove_reference_t<T>`, `u` be an lvalue of type
880
+ `const remove_reference_t<U>`, and `C` be:
881
+
882
+ ``` cpp
883
+ common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&>
884
+ ```
885
+
886
+ `T` and `U` model `totally_ordered_with<T, U>` only if
887
+
888
+ - `bool(t < u) == bool(C(t) < C(u)).`
889
+ - `bool(t > u) == bool(C(t) > C(u)).`
890
+ - `bool(t <= u) == bool(C(t) <= C(u)).`
891
+ - `bool(t >= u) == bool(C(t) >= C(u)).`
892
+ - `bool(u < t) == bool(C(u) < C(t)).`
893
+ - `bool(u > t) == bool(C(u) > C(t)).`
894
+ - `bool(u <= t) == bool(C(u) <= C(t)).`
895
+ - `bool(u >= t) == bool(C(u) >= C(t)).`
896
+
897
+ ## Object concepts <a id="concepts.object">[[concepts.object]]</a>
898
+
899
+ This subclause describes concepts that specify the basis of the
900
+ value-oriented programming style on which the library is based.
901
+
902
+ ``` cpp
903
+ template<class T>
904
+ concept movable = is_object_v<T> && move_constructible<T> &&
905
+ assignable_from<T&, T> && swappable<T>;
906
+ template<class T>
907
+ concept copyable = copy_constructible<T> && movable<T> && assignable_from<T&, T&> &&
908
+ assignable_from<T&, const T&> && assignable_from<T&, const T>;
909
+ template<class T>
910
+ concept semiregular = copyable<T> && default_initializable<T>;
911
+ template<class T>
912
+ concept regular = semiregular<T> && equality_comparable<T>;
913
+ ```
914
+
915
+ [*Note 1*: The `semiregular` concept is modeled by types that behave
916
+ similarly to built-in types like `int`, except that they might not be
917
+ comparable with `==`. — *end note*]
918
+
919
+ [*Note 2*: The `regular` concept is modeled by types that behave
920
+ similarly to built-in types like `int` and that are comparable with
921
+ `==`. — *end note*]
922
+
923
+ ## Callable concepts <a id="concepts.callable">[[concepts.callable]]</a>
924
+
925
+ ### General <a id="concepts.callable.general">[[concepts.callable.general]]</a>
926
+
927
+ The concepts in subclause [[concepts.callable]] describe the
928
+ requirements on function objects [[function.objects]] and their
929
+ arguments.
930
+
931
+ ### Concept <a id="concept.invocable">[[concept.invocable]]</a>
932
+
933
+ The `invocable` concept specifies a relationship between a callable type
934
+ [[func.def]] `F` and a set of argument types `Args...` which can be
935
+ evaluated by the library function `invoke` [[func.invoke]].
936
+
937
+ ``` cpp
938
+ template<class F, class... Args>
939
+ concept invocable = requires(F&& f, Args&&... args) {
940
+ invoke(std::forward<F>(f), std::forward<Args>(args)...); // not required to be equality-preserving
941
+ };
942
+ ```
943
+
944
+ [*Example 1*: A function that generates random numbers can model
945
+ `invocable`, since the `invoke` function call expression is not required
946
+ to be equality-preserving [[concepts.equality]]. — *end example*]
947
+
948
+ ### Concept <a id="concept.regularinvocable">[[concept.regularinvocable]]</a>
949
+
950
+ ``` cpp
951
+ template<class F, class... Args>
952
+ concept regular_invocable = invocable<F, Args...>;
953
+ ```
954
+
955
+ The `invoke` function call expression shall be
956
+ equality-preserving [[concepts.equality]] and shall not modify the
957
+ function object or the arguments.
958
+
959
+ [*Note 1*: This requirement supersedes the annotation in the definition
960
+ of `invocable`. — *end note*]
961
+
962
+ [*Example 1*: A random number generator does not model
963
+ `regular_invocable`. — *end example*]
964
+
965
+ [*Note 2*: The distinction between `invocable` and `regular_invocable`
966
+ is purely semantic. — *end note*]
967
+
968
+ ### Concept <a id="concept.predicate">[[concept.predicate]]</a>
969
+
970
+ ``` cpp
971
+ template<class F, class... Args>
972
+ concept predicate =
973
+ regular_invocable<F, Args...> && boolean-testable<invoke_result_t<F, Args...>>;
974
+ ```
975
+
976
+ ### Concept <a id="concept.relation">[[concept.relation]]</a>
977
+
978
+ ``` cpp
979
+ template<class R, class T, class U>
980
+ concept relation =
981
+ predicate<R, T, T> && predicate<R, U, U> &&
982
+ predicate<R, T, U> && predicate<R, U, T>;
983
+ ```
984
+
985
+ ### Concept <a id="concept.equiv">[[concept.equiv]]</a>
986
+
987
+ ``` cpp
988
+ template<class R, class T, class U>
989
+ concept equivalence_relation = relation<R, T, U>;
990
+ ```
991
+
992
+ A `relation` models `equivalence_relation` only if it imposes an
993
+ equivalence relation on its arguments.
994
+
995
+ ### Concept <a id="concept.strictweakorder">[[concept.strictweakorder]]</a>
996
+
997
+ ``` cpp
998
+ template<class R, class T, class U>
999
+ concept strict_weak_order = relation<R, T, U>;
1000
+ ```
1001
+
1002
+ A `relation` models `strict_weak_order` only if it imposes a *strict
1003
+ weak ordering* on its arguments.
1004
+
1005
+ The term *strict* refers to the requirement of an irreflexive relation
1006
+ (`!comp(x, x)` for all `x`), and the term *weak* to requirements that
1007
+ are not as strong as those for a total ordering, but stronger than those
1008
+ for a partial ordering. If we define `equiv(a, b)` as
1009
+ `!comp(a, b) && !comp(b, a)`, then the requirements are that `comp` and
1010
+ `equiv` both be transitive relations:
1011
+
1012
+ - `comp(a, b) && comp(b, c)` implies `comp(a, c)`
1013
+ - `equiv(a, b) && equiv(b, c)` implies `equiv(a, c)`
1014
+
1015
+ [*Note 1*:
1016
+
1017
+ Under these conditions, it can be shown that
1018
+
1019
+ - `equiv` is an equivalence relation,
1020
+ - `comp` induces a well-defined relation on the equivalence classes
1021
+ determined by `equiv`, and
1022
+ - the induced relation is a strict total ordering.
1023
+
1024
+ — *end note*]
1025
+
1026
+ <!-- Link reference definitions -->
1027
+ [basic.compound]: basic.md#basic.compound
1028
+ [basic.fundamental]: basic.md#basic.fundamental
1029
+ [basic.lookup.argdep]: basic.md#basic.lookup.argdep
1030
+ [basic.types]: basic.md#basic.types
1031
+ [class.member.lookup]: class.md#class.member.lookup
1032
+ [concept.assignable]: #concept.assignable
1033
+ [concept.booleantestable]: #concept.booleantestable
1034
+ [concept.common]: #concept.common
1035
+ [concept.commonref]: #concept.commonref
1036
+ [concept.constructible]: #concept.constructible
1037
+ [concept.convertible]: #concept.convertible
1038
+ [concept.copyconstructible]: #concept.copyconstructible
1039
+ [concept.default.init]: #concept.default.init
1040
+ [concept.derived]: #concept.derived
1041
+ [concept.destructible]: #concept.destructible
1042
+ [concept.equalitycomparable]: #concept.equalitycomparable
1043
+ [concept.equiv]: #concept.equiv
1044
+ [concept.invocable]: #concept.invocable
1045
+ [concept.moveconstructible]: #concept.moveconstructible
1046
+ [concept.predicate]: #concept.predicate
1047
+ [concept.regularinvocable]: #concept.regularinvocable
1048
+ [concept.relation]: #concept.relation
1049
+ [concept.same]: #concept.same
1050
+ [concept.strictweakorder]: #concept.strictweakorder
1051
+ [concept.swappable]: #concept.swappable
1052
+ [concept.totallyordered]: #concept.totallyordered
1053
+ [concepts]: #concepts
1054
+ [concepts.arithmetic]: #concepts.arithmetic
1055
+ [concepts.callable]: #concepts.callable
1056
+ [concepts.callable.general]: #concepts.callable.general
1057
+ [concepts.compare]: #concepts.compare
1058
+ [concepts.compare.general]: #concepts.compare.general
1059
+ [concepts.equality]: #concepts.equality
1060
+ [concepts.general]: #concepts.general
1061
+ [concepts.lang]: #concepts.lang
1062
+ [concepts.lang.general]: #concepts.lang.general
1063
+ [concepts.object]: #concepts.object
1064
+ [concepts.summary]: #concepts.summary
1065
+ [concepts.syn]: #concepts.syn
1066
+ [cpp17.destructible]: #cpp17.destructible
1067
+ [customization.point.object]: library.md#customization.point.object
1068
+ [declval]: utilities.md#declval
1069
+ [defns.const.subexpr]: library.md#defns.const.subexpr
1070
+ [expr.log.and]: expr.md#expr.log.and
1071
+ [expr.log.or]: expr.md#expr.log.or
1072
+ [expr.prim.id]: expr.md#expr.prim.id
1073
+ [expr.unary.op]: expr.md#expr.unary.op
1074
+ [forward]: utilities.md#forward
1075
+ [func.def]: utilities.md#func.def
1076
+ [func.invoke]: utilities.md#func.invoke
1077
+ [function.objects]: utilities.md#function.objects
1078
+ [lib.types.movedfrom]: library.md#lib.types.movedfrom
1079
+ [meta.trans.other]: utilities.md#meta.trans.other
1080
+ [meta.type.synop]: utilities.md#meta.type.synop
1081
+ [namespace.memdef]: dcl.md#namespace.memdef
1082
+ [over.best.ics]: over.md#over.best.ics
1083
+ [structure.requirements]: library.md#structure.requirements
1084
+ [temp.deduct.call]: temp.md#temp.deduct.call
1085
+ [temp.deduct.type]: temp.md#temp.deduct.type
1086
+ [template.bitset]: utilities.md#template.bitset
1087
+
1088
+ [^1]: The name `swap` is used here unqualified.