From Jason Turner

[concepts]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpeb61t9lw/{from.md → to.md} +129 -78
tmp/tmpeb61t9lw/{from.md → to.md} RENAMED
@@ -32,25 +32,28 @@ 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
@@ -58,18 +61,18 @@ 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
@@ -83,11 +86,11 @@ 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
@@ -123,11 +126,11 @@ For the above example:
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
 
@@ -146,10 +149,11 @@ implementation diagnoses as ill-formed a program that requires `C<T>`.
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;
@@ -300,22 +304,22 @@ template<class Derived, class Base>
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:
@@ -344,12 +348,12 @@ that `f()` is equality-preserving. Types `From` and `To` model
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>> &&
@@ -374,12 +378,12 @@ template [[meta.trans.other]]. — *end note*]
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>> &&
@@ -490,31 +494,35 @@ if the operation modifies neither `t2` nor `u2` and:
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));
@@ -523,15 +531,15 @@ expression `S` determined as follows:
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>
@@ -548,13 +556,13 @@ template<class T, class 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:
@@ -629,11 +637,11 @@ template<class T, class... Args>
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>;
@@ -676,12 +684,12 @@ template<class 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`.
@@ -692,32 +700,39 @@ If `T` is an object type, then let `v` be an lvalue of type (possibly
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
@@ -729,13 +744,13 @@ A *disqualifying parameter* is a function parameter whose declared type
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
 
@@ -760,12 +775,12 @@ A *disqualifying declaration* is
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
@@ -782,11 +797,39 @@ template<class T>
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>
@@ -800,12 +843,12 @@ template<class T, class U>
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)`.
@@ -825,28 +868,33 @@ 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>
@@ -873,28 +921,30 @@ template<class T, class U>
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.
@@ -911,15 +961,15 @@ template<class 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>
@@ -1025,16 +1075,15 @@ Under these conditions, it can be shown that
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
@@ -1063,26 +1112,28 @@ Under these conditions, it can be shown that
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.
 
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.
 
 
 
 
43
 
44
+ [*Example 2*: For integers `a` and `b`, the expression `a / b` is not
45
+ well-defined when `b` is `0`. This does not preclude the expression
46
+ `a / b` being equality-preserving. *end example*]
47
+
48
+ The *domain* of an expression is the set of input values for which the
49
+ expression is required to be well-defined.
50
+
51
+ Expressions required to be equality-preserving are further required to
52
+ be stable: two evaluations of such an expression with the same input
53
+ objects are required to have equal outputs absent any explicit
54
+ intervening modification of those input objects.
55
 
56
  [*Note 1*: This requirement allows generic code to reason about the
57
  current values of objects based on knowledge of the prior values as
58
  observed via equality-preserving expressions. It effectively forbids
59
  spontaneous changes to an object, changes to an object from another
 
61
  non-modifying expressions, and changes to an object as side effects of
62
  modifying a distinct object if those changes could be observable to a
63
  library function via an equality-preserving expression that is required
64
  to be valid for that object. — *end note*]
65
 
66
+ Expressions declared in a *requires-expression* in the library clauses
67
+ are required to be equality-preserving, except for those annotated with
68
+ the comment “not required to be equality-preserving.” An expression so
69
  annotated may be equality-preserving, but is not required to be so.
70
 
71
  An expression that may alter the value of one or more of its inputs in a
72
  manner observable to equality-preserving expressions is said to modify
73
+ those inputs. The library clauses use a notational convention to specify
74
  which expressions declared in a *requires-expression* modify which
75
  inputs: except where otherwise specified, an expression operand that is
76
  a non-constant lvalue or rvalue may be modified. Operands that are
77
  constant lvalues or rvalues are required to not be modified. For the
78
  purposes of this subclause, the cv-qualification and value category of
 
86
  expression variation is explicitly required with differing semantics.
87
  These *implicit expression variations* are required to meet the semantic
88
  requirements of the declared expression. The extent to which an
89
  implementation validates the syntax of the variations is unspecified.
90
 
91
+ [*Example 3*:
92
 
93
  ``` cpp
94
  template<class T> concept C = requires(T a, T b, const T c, const T d) {
95
  c == d; // #1
96
  a = std::move(b); // #2
 
126
  second operand, since expression \#2 already specifies exactly such an
127
  expression explicitly.
128
 
129
  — *end example*]
130
 
131
+ [*Example 4*:
132
 
133
  The following type `T` meets the explicitly stated syntactic
134
  requirements of concept `C` above but does not meet the additional
135
  implicit requirements:
136
 
 
149
  — *end example*]
150
 
151
  ## Header `<concepts>` synopsis <a id="concepts.syn">[[concepts.syn]]</a>
152
 
153
  ``` cpp
154
+ // all freestanding
155
  namespace std {
156
  // [concepts.lang], language-related concepts
157
  // [concept.same], concept same_as
158
  template<class T, class U>
159
  concept same_as = see below;
 
304
  `Derived` and `Base` are the same class type ignoring
305
  cv-qualifiers. — *end note*]
306
 
307
  ### Concept <a id="concept.convertible">[[concept.convertible]]</a>
308
 
309
+ Given types `From` and `To` and an expression `E` whose type and value
310
+ category are the same as those of `declval<From>()`,
311
  `convertible_to<From, To>` requires `E` to be both implicitly and
312
  explicitly convertible to type `To`. The implicit and explicit
313
  conversions are required to produce equal results.
314
 
315
  ``` cpp
316
  template<class From, class To>
317
  concept convertible_to =
318
  is_convertible_v<From, To> &&
319
+ requires {
320
+ static_cast<To>(declval<From>());
321
  };
322
  ```
323
 
324
  Let `FromR` be `add_rvalue_reference_t<From>` and `test` be the invented
325
  function:
 
348
  For two types `T` and `U`, if `common_reference_t<T, U>` is well-formed
349
  and denotes a type `C` such that both `convertible_to<T, C>` and
350
  `convertible_to<U, C>` are modeled, then `T` and `U` share a *common
351
  reference type*, `C`.
352
 
353
+ [*Note 1*: `C` can be the same as `T` or `U`, or can be a different
354
+ type. `C` can be a reference type. — *end note*]
355
 
356
  ``` cpp
357
  template<class T, class U>
358
  concept common_reference_with =
359
  same_as<common_reference_t<T, U>, common_reference_t<U, T>> &&
 
378
  ### Concept <a id="concept.common">[[concept.common]]</a>
379
 
380
  If `T` and `U` can both be explicitly converted to some third type, `C`,
381
  then `T` and `U` share a *common type*, `C`.
382
 
383
+ [*Note 1*: `C` can be the same as `T` or `U`, or can be a different
384
+ type. `C` is not necessarily unique. — *end note*]
385
 
386
  ``` cpp
387
  template<class T, class U>
388
  concept common_with =
389
  same_as<common_type_t<T, U>, common_type_t<U, T>> &&
 
494
  The name `ranges::swap` denotes a customization point object
495
  [[customization.point.object]]. The expression `ranges::swap(E1, E2)`
496
  for subexpressions `E1` and `E2` is expression-equivalent to an
497
  expression `S` determined as follows:
498
 
499
+ - `S` is `(void)swap(E1, E2)`[^1]
500
+ if `E1` or `E2` has class or enumeration type [[basic.compound]] and
501
+ that expression is valid, with overload resolution performed in a
502
+ context that includes the declaration
503
  ``` cpp
504
  template<class T>
505
  void swap(T&, T&) = delete;
506
  ```
507
 
508
  and does not include a declaration of `ranges::swap`. If the function
509
  selected by overload resolution does not exchange the values denoted
510
  by `E1` and `E2`, the program is ill-formed, no diagnostic required.
511
+ \[*Note 2*: This precludes calling unconstrained program-defined
512
+ overloads of `swap`. When the deleted overload is viable,
513
+ program-defined overloads need to be more specialized
514
+ [[temp.func.order]] to be selected. — *end note*]
515
  - Otherwise, if `E1` and `E2` are lvalues of array types
516
  [[basic.compound]] with equal extent and `ranges::swap(*E1, *E2)` is a
517
  valid expression, `S` is `(void)ranges::swap_ranges(E1, E2)`, except
518
  that `noexcept(S)` is equal to `noexcept({}ranges::swap(*E1, *E2))`.
519
  - Otherwise, if `E1` and `E2` are lvalues of the same type `T` that
520
  models `move_constructible<T>` and `assignable_from<T&, T>`, `S` is an
521
  expression that exchanges the denoted values. `S` is a constant
522
  expression if
523
+ - `T` is a literal type [[term.literal.type]],
524
  - both `E1 = std::move(E2)` and `E2 = std::move(E1)` are constant
525
  subexpressions [[defns.const.subexpr]], and
526
  - the full-expressions of the initializers in the declarations
527
  ``` cpp
528
  T t1(std::move(E1));
 
531
 
532
  are constant subexpressions.
533
 
534
  `noexcept(S)` is equal to
535
  `is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>`.
536
+ - Otherwise, `ranges::swap(E1, E2)` is ill-formed. \[*Note 3*: This case
537
  can result in substitution failure when `ranges::swap(E1, E2)` appears
538
  in the immediate context of a template instantiation. — *end note*]
539
 
540
+ [*Note 4*: Whenever `ranges::swap(E1, E2)` is a valid expression, it
541
  exchanges the values denoted by `E1` and `E2` and has type
542
  `void`. — *end note*]
543
 
544
  ``` cpp
545
  template<class T>
 
556
  ranges::swap(std::forward<T>(t), std::forward<U>(u));
557
  ranges::swap(std::forward<U>(u), std::forward<T>(t));
558
  };
559
  ```
560
 
561
+ [*Note 5*: The semantics of the `swappable` and `swappable_with`
562
+ concepts are fully defined by the `ranges::swap` customization point
563
+ object. — *end note*]
564
 
565
  [*Example 1*:
566
 
567
  User code can ensure that the evaluation of `swap` calls is performed in
568
  an appropriate context under the various conditions as follows:
 
637
 
638
  ### Concept <a id="concept.default.init">[[concept.default.init]]</a>
639
 
640
  ``` cpp
641
  template<class T>
642
+ constexpr bool is-default-initializable = see below; // exposition only
643
 
644
  template<class T>
645
  concept default_initializable = constructible_from<T> &&
646
  requires { T{}; } &&
647
  is-default-initializable<T>;
 
684
  constructible_from<T, T&> && convertible_to<T&, T> &&
685
  constructible_from<T, const T&> && convertible_to<const T&, T> &&
686
  constructible_from<T, const T> && convertible_to<const T, T>;
687
  ```
688
 
689
+ If `T` is an object type, then let `v` be an lvalue of type `T` or
690
+ `const T` or an rvalue of type `const T`. `T` models
691
  `copy_constructible` only if
692
 
693
  - After the definition `T u = v;`, `u` is equal to `v`
694
  [[concepts.equality]] and `v` is not modified.
695
  - `T(v)` is equal to `v` and does not modify `v`.
 
700
 
701
  Subclause [[concepts.compare]] describes concepts that establish
702
  relationships and orderings on values of possibly differing object
703
  types.
704
 
705
+ Given an expression `E` and a type `C`, let `CONVERT_TO_LVALUE<C>(E)`
706
+ be:
707
+
708
+ - `static_cast<const C&>(as_const(E))` if that is a valid expression,
709
+ and
710
+ - `static_cast<const C&>(std::move(E))` otherwise.
711
+
712
  ### Boolean testability <a id="concept.booleantestable">[[concept.booleantestable]]</a>
713
 
714
  The exposition-only `boolean-testable` concept specifies the
715
  requirements on expressions that are convertible to `bool` and for which
716
+ the logical operators
717
+ [[expr.log.and]], [[expr.log.or]], [[expr.unary.op]] have the
718
+ conventional semantics.
719
 
720
  ``` cpp
721
  template<class T>
722
  concept boolean-testable-impl = convertible_to<T, bool>; // exposition only
723
  ```
724
 
725
  Let `e` be an expression such that `decltype((e))` is `T`. `T` models
726
  `boolean-testable-impl` only if:
727
 
728
+ - either `remove_cvref_t<T>` is not a class type, or a search for the
729
+ names `operator&&` and `operator||` in the scope of
730
+ `remove_cvref_t<T>` finds nothing; and
731
+ - argument-dependent lookup [[basic.lookup.argdep]] for the names
732
+ `operator&&` and `operator||` with `T` as the only argument type finds
733
+ no disqualifying declaration (defined below).
 
734
 
735
  A *disqualifying parameter* is a function parameter whose declared type
736
  `P`
737
 
738
  - is not dependent on a template parameter, and there exists an implicit
 
744
  arguments in a function call [[temp.deduct.call]] and `e` as the
745
  argument succeeds.
746
 
747
  A *key parameter* of a function template `D` is a function parameter of
748
  type cv `X` or reference thereto, where `X` names a specialization of a
749
+ class template that has the same innermost enclosing non-inline
750
+ namespace as `D`, and `X` contains at least one template parameter that
751
+ participates in template argument deduction.
752
 
753
  [*Example 1*:
754
 
755
  In
756
 
 
775
  disqualifying parameter; or
776
  - a function template declaration that contains at least one
777
  disqualifying parameter, where
778
  - at least one disqualifying parameter is a key parameter; or
779
  - the declaration contains no key parameters; or
780
+ - the declaration declares a function template to which no name is
781
+ bound [[dcl.meaning]].
782
 
783
  [*Note 1*: The intention is to ensure that given two types `T1` and
784
  `T2` that each model `boolean-testable-impl`, the `&&` and `||`
785
  operators within the expressions `declval<T1>() && declval<T2>()` and
786
  `declval<T1>() || declval<T2>()` resolve to the corresponding built-in
 
797
  Let `e` be an expression such that `decltype((e))` is `T`. `T` models
798
  `boolean-testable` only if `bool(e) == !bool(!e)`.
799
 
800
  [*Example 2*: The types `bool`, `true_type` [[meta.type.synop]],
801
  `int*`, and `bitset<N>::reference` [[template.bitset]] model
802
+ `boolean-testable`. — *end example*]
803
+
804
+ ### Comparison common types <a id="concept.comparisoncommontype">[[concept.comparisoncommontype]]</a>
805
+
806
+ ``` cpp
807
+ template<class T, class U, class C = common_reference_t<const T&, const U&>>
808
+ concept comparison-common-type-with-impl = // exposition only
809
+ same_as<common_reference_t<const T&, const U&>,
810
+ common_reference_t<const U&, const T&>> &&
811
+ requires {
812
+ requires convertible_to<const T&, const C&> || convertible_to<T, const C&>;
813
+ requires convertible_to<const U&, const C&> || convertible_to<U, const C&>;
814
+ };
815
+
816
+ template<class T, class U>
817
+ concept comparison-common-type-with = // exposition only
818
+ comparison-common-type-with-impl<remove_cvref_t<T>, remove_cvref_t<U>>;
819
+ ```
820
+
821
+ Let `C` be `common_reference_t<const T&, const U&>`. Let `t1` and `t2`
822
+ be equality-preserving expressions that are lvalues of type
823
+ `remove_cvref_t<T>`, and let `u1` and `u2` be equality-preserving
824
+ expressions that are lvalues of type `remove_cvref_t<U>`. `T` and `U`
825
+ model `comparison-common-type-with<T, U>` only if:
826
+
827
+ - `CONVERT_TO_LVALUE<C>(t1)` equals `CONVERT_TO_LVALUE<C>(t2)` if and
828
+ only if `t1` equals `t2`, and
829
+ - `CONVERT_TO_LVALUE<C>(u1)` equals `CONVERT_TO_LVALUE<C>(u2)` if and
830
+ only if `u1` equals `u2`
831
 
832
  ### Concept <a id="concept.equalitycomparable">[[concept.equalitycomparable]]</a>
833
 
834
  ``` cpp
835
  template<class T, class U>
 
843
  };
844
  ```
845
 
846
  Given types `T` and `U`, let `t` and `u` be lvalues of types
847
  `const remove_reference_t<T>` and `const remove_reference_t<U>`
848
+ respectively. `T` and `U` model `weakly-equality-comparable-with<T, U>`
849
+ only if
850
 
851
  - `t == u`, `u == t`, `t != u`, and `u != t` have the same domain.
852
  - `bool(u == t) == bool(t == u)`.
853
  - `bool(t != u) == !bool(t == u)`.
854
  - `bool(u != t) == bool(t != u)`.
 
868
 
869
  ``` cpp
870
  template<class T, class U>
871
  concept equality_comparable_with =
872
  equality_comparable<T> && equality_comparable<U> &&
873
+ comparison-common-type-with<T, U> &&
874
  equality_comparable<
875
  common_reference_t<
876
  const remove_reference_t<T>&,
877
  const remove_reference_t<U>&>> &&
878
  weakly-equality-comparable-with<T, U>;
879
  ```
880
 
881
+ Given types `T` and `U`, let `t` and `t2` be lvalues denoting distinct
882
+ equal objects of types `const remove_reference_t<T>` and
883
+ `remove_cvref_t<T>`, respectively, let `u` and `u2` be lvalues denoting
884
+ distinct equal objects of types `const remove_reference_t<U>` and
885
+ `remove_cvref_t<U>`, respectively, and let `C` be:
886
 
887
  ``` cpp
888
  common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&>
889
  ```
890
 
891
  `T` and `U` model `equality_comparable_with<T, U>` only if
892
+
893
+ ``` cpp
894
+ bool(t == u) == bool(CONVERT_TO_LVALUE<C>(t2) == CONVERT_TO_LVALUE<C>(u2))
895
+ ```
896
 
897
  ### Concept <a id="concept.totallyordered">[[concept.totallyordered]]</a>
898
 
899
  ``` cpp
900
  template<class T>
 
921
  const remove_reference_t<T>&,
922
  const remove_reference_t<U>&>> &&
923
  partially-ordered-with<T, U>;
924
  ```
925
 
926
+ Given types `T` and `U`, let `t` and `t2` be lvalues denoting distinct
927
+ equal objects of types `const remove_reference_t<T>` and
928
+ `remove_cvref_t<T>`, respectively, let `u` and `u2` be lvalues denoting
929
+ distinct equal objects of types `const remove_reference_t<U>` and
930
+ `remove_cvref_t<U>`, respectively, and let `C` be:
931
 
932
  ``` cpp
933
  common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&>
934
  ```
935
 
936
  `T` and `U` model `totally_ordered_with<T, U>` only if
937
 
938
+ - `bool(t < u) == bool(`*`CONVERT_TO_LVALUE`*`<C>(t2) < `*`CONVERT_TO_LVALUE`*`<C>(u2))`.
939
+ - `bool(t > u) == bool(`*`CONVERT_TO_LVALUE`*`<C>(t2) > `*`CONVERT_TO_LVALUE`*`<C>(u2))`.
940
+ - `bool(t <= u) == bool(`*`CONVERT_TO_LVALUE`*`<C>(t2) <= `*`CONVERT_TO_LVALUE`*`<C>(u2))`.
941
+ - `bool(t >= u) == bool(`*`CONVERT_TO_LVALUE`*`<C>(t2) >= `*`CONVERT_TO_LVALUE`*`<C>(u2))`.
942
+ - `bool(u < t) == bool(`*`CONVERT_TO_LVALUE`*`<C>(u2) < `*`CONVERT_TO_LVALUE`*`<C>(t2))`.
943
+ - `bool(u > t) == bool(`*`CONVERT_TO_LVALUE`*`<C>(u2) > `*`CONVERT_TO_LVALUE`*`<C>(t2))`.
944
+ - `bool(u <= t) == bool(`*`CONVERT_TO_LVALUE`*`<C>(u2) <= `*`CONVERT_TO_LVALUE`*`<C>(t2))`.
945
+ - `bool(u >= t) == bool(`*`CONVERT_TO_LVALUE`*`<C>(u2) >= `*`CONVERT_TO_LVALUE`*`<C>(t2))`.
946
 
947
  ## Object concepts <a id="concepts.object">[[concepts.object]]</a>
948
 
949
  This subclause describes concepts that specify the basis of the
950
  value-oriented programming style on which the library is based.
 
961
  template<class T>
962
  concept regular = semiregular<T> && equality_comparable<T>;
963
  ```
964
 
965
  [*Note 1*: The `semiregular` concept is modeled by types that behave
966
+ similarly to fundamental types like `int`, except that they need not be
967
  comparable with `==`. — *end note*]
968
 
969
  [*Note 2*: The `regular` concept is modeled by types that behave
970
+ similarly to fundamental types like `int` and that are comparable with
971
  `==`. — *end note*]
972
 
973
  ## Callable concepts <a id="concepts.callable">[[concepts.callable]]</a>
974
 
975
  ### General <a id="concepts.callable.general">[[concepts.callable.general]]</a>
 
1075
 
1076
  <!-- Link reference definitions -->
1077
  [basic.compound]: basic.md#basic.compound
1078
  [basic.fundamental]: basic.md#basic.fundamental
1079
  [basic.lookup.argdep]: basic.md#basic.lookup.argdep
 
 
1080
  [concept.assignable]: #concept.assignable
1081
  [concept.booleantestable]: #concept.booleantestable
1082
  [concept.common]: #concept.common
1083
  [concept.commonref]: #concept.commonref
1084
+ [concept.comparisoncommontype]: #concept.comparisoncommontype
1085
  [concept.constructible]: #concept.constructible
1086
  [concept.convertible]: #concept.convertible
1087
  [concept.copyconstructible]: #concept.copyconstructible
1088
  [concept.default.init]: #concept.default.init
1089
  [concept.derived]: #concept.derived
 
1112
  [concepts.object]: #concepts.object
1113
  [concepts.summary]: #concepts.summary
1114
  [concepts.syn]: #concepts.syn
1115
  [cpp17.destructible]: #cpp17.destructible
1116
  [customization.point.object]: library.md#customization.point.object
1117
+ [dcl.meaning]: dcl.md#dcl.meaning
1118
  [declval]: utilities.md#declval
1119
+ [defns.const.subexpr]: intro.md#defns.const.subexpr
1120
  [expr.log.and]: expr.md#expr.log.and
1121
  [expr.log.or]: expr.md#expr.log.or
1122
  [expr.prim.id]: expr.md#expr.prim.id
1123
  [expr.unary.op]: expr.md#expr.unary.op
1124
  [forward]: utilities.md#forward
1125
  [func.def]: utilities.md#func.def
1126
  [func.invoke]: utilities.md#func.invoke
1127
  [function.objects]: utilities.md#function.objects
1128
  [lib.types.movedfrom]: library.md#lib.types.movedfrom
1129
+ [meta.trans.other]: meta.md#meta.trans.other
1130
+ [meta.type.synop]: meta.md#meta.type.synop
 
1131
  [over.best.ics]: over.md#over.best.ics
1132
  [structure.requirements]: library.md#structure.requirements
1133
  [temp.deduct.call]: temp.md#temp.deduct.call
1134
  [temp.deduct.type]: temp.md#temp.deduct.type
1135
+ [temp.func.order]: temp.md#temp.func.order
1136
  [template.bitset]: utilities.md#template.bitset
1137
+ [term.literal.type]: basic.md#term.literal.type
1138
 
1139
  [^1]: The name `swap` is used here unqualified.