From Jason Turner

[concepts.compare]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp50n7iwv5/{from.md → to.md} +75 -33
tmp/tmp50n7iwv5/{from.md → to.md} RENAMED
@@ -4,32 +4,39 @@
4
 
5
  Subclause [[concepts.compare]] describes concepts that establish
6
  relationships and orderings on values of possibly differing object
7
  types.
8
 
 
 
 
 
 
 
 
9
  ### Boolean testability <a id="concept.booleantestable">[[concept.booleantestable]]</a>
10
 
11
  The exposition-only `boolean-testable` concept specifies the
12
  requirements on expressions that are convertible to `bool` and for which
13
- the logical operators  ([[expr.log.and]], [[expr.log.or]],
14
- [[expr.unary.op]]) have the conventional semantics.
 
15
 
16
  ``` cpp
17
  template<class T>
18
  concept boolean-testable-impl = convertible_to<T, bool>; // exposition only
19
  ```
20
 
21
  Let `e` be an expression such that `decltype((e))` is `T`. `T` models
22
  `boolean-testable-impl` only if:
23
 
24
- - either `remove_cvref_t<T>` is not a class type, or name lookup for the
25
- names `operator&&` and `operator||` within the scope of
26
- `remove_cvref_t<T>` as if by class member access lookup
27
- [[class.member.lookup]] results in an empty declaration set; and
28
- - name lookup for the names `operator&&` and `operator||` in the
29
- associated namespaces and entities of `T` [[basic.lookup.argdep]]
30
- finds no disqualifying declaration (defined below).
31
 
32
  A *disqualifying parameter* is a function parameter whose declared type
33
  `P`
34
 
35
  - is not dependent on a template parameter, and there exists an implicit
@@ -41,13 +48,13 @@ A *disqualifying parameter* is a function parameter whose declared type
41
  arguments in a function call [[temp.deduct.call]] and `e` as the
42
  argument succeeds.
43
 
44
  A *key parameter* of a function template `D` is a function parameter of
45
  type cv `X` or reference thereto, where `X` names a specialization of a
46
- class template that is a member of the same namespace as `D`, and `X`
47
- contains at least one template parameter that participates in template
48
- argument deduction.
49
 
50
  [*Example 1*:
51
 
52
  In
53
 
@@ -72,12 +79,12 @@ A *disqualifying declaration* is
72
  disqualifying parameter; or
73
  - a function template declaration that contains at least one
74
  disqualifying parameter, where
75
  - at least one disqualifying parameter is a key parameter; or
76
  - the declaration contains no key parameters; or
77
- - the declaration declares a function template that is not visible in
78
- its namespace [[namespace.memdef]].
79
 
80
  [*Note 1*: The intention is to ensure that given two types `T1` and
81
  `T2` that each model `boolean-testable-impl`, the `&&` and `||`
82
  operators within the expressions `declval<T1>() && declval<T2>()` and
83
  `declval<T1>() || declval<T2>()` resolve to the corresponding built-in
@@ -94,11 +101,39 @@ template<class T>
94
  Let `e` be an expression such that `decltype((e))` is `T`. `T` models
95
  `boolean-testable` only if `bool(e) == !bool(!e)`.
96
 
97
  [*Example 2*: The types `bool`, `true_type` [[meta.type.synop]],
98
  `int*`, and `bitset<N>::reference` [[template.bitset]] model
99
- *`boolean-testable`*. — *end example*]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
  ### Concept <a id="concept.equalitycomparable">[[concept.equalitycomparable]]</a>
102
 
103
  ``` cpp
104
  template<class T, class U>
@@ -112,12 +147,12 @@ template<class T, class U>
112
  };
113
  ```
114
 
115
  Given types `T` and `U`, let `t` and `u` be lvalues of types
116
  `const remove_reference_t<T>` and `const remove_reference_t<U>`
117
- respectively. `T` and `U` model
118
- *`weakly-equality-comparable-with`*`<T, U>` only if
119
 
120
  - `t == u`, `u == t`, `t != u`, and `u != t` have the same domain.
121
  - `bool(u == t) == bool(t == u)`.
122
  - `bool(t != u) == !bool(t == u)`.
123
  - `bool(u != t) == bool(t != u)`.
@@ -137,28 +172,33 @@ symmetric. — *end note*]
137
 
138
  ``` cpp
139
  template<class T, class U>
140
  concept equality_comparable_with =
141
  equality_comparable<T> && equality_comparable<U> &&
142
- common_reference_with<const remove_reference_t<T>&, const remove_reference_t<U>&> &&
143
  equality_comparable<
144
  common_reference_t<
145
  const remove_reference_t<T>&,
146
  const remove_reference_t<U>&>> &&
147
  weakly-equality-comparable-with<T, U>;
148
  ```
149
 
150
- Given types `T` and `U`, let `t` be an lvalue of type
151
- `const remove_reference_t<T>`, `u` be an lvalue of type
152
- `const remove_reference_t<U>`, and `C` be:
 
 
153
 
154
  ``` cpp
155
  common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&>
156
  ```
157
 
158
  `T` and `U` model `equality_comparable_with<T, U>` only if
159
- `bool(t == u) == bool(C(t) == C(u))`.
 
 
 
160
 
161
  ### Concept <a id="concept.totallyordered">[[concept.totallyordered]]</a>
162
 
163
  ``` cpp
164
  template<class T>
@@ -185,24 +225,26 @@ template<class T, class U>
185
  const remove_reference_t<T>&,
186
  const remove_reference_t<U>&>> &&
187
  partially-ordered-with<T, U>;
188
  ```
189
 
190
- Given types `T` and `U`, let `t` be an lvalue of type
191
- `const remove_reference_t<T>`, `u` be an lvalue of type
192
- `const remove_reference_t<U>`, and `C` be:
 
 
193
 
194
  ``` cpp
195
  common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&>
196
  ```
197
 
198
  `T` and `U` model `totally_ordered_with<T, U>` only if
199
 
200
- - `bool(t < u) == bool(C(t) < C(u)).`
201
- - `bool(t > u) == bool(C(t) > C(u)).`
202
- - `bool(t <= u) == bool(C(t) <= C(u)).`
203
- - `bool(t >= u) == bool(C(t) >= C(u)).`
204
- - `bool(u < t) == bool(C(u) < C(t)).`
205
- - `bool(u > t) == bool(C(u) > C(t)).`
206
- - `bool(u <= t) == bool(C(u) <= C(t)).`
207
- - `bool(u >= t) == bool(C(u) >= C(t)).`
208
 
 
4
 
5
  Subclause [[concepts.compare]] describes concepts that establish
6
  relationships and orderings on values of possibly differing object
7
  types.
8
 
9
+ Given an expression `E` and a type `C`, let `CONVERT_TO_LVALUE<C>(E)`
10
+ be:
11
+
12
+ - `static_cast<const C&>(as_const(E))` if that is a valid expression,
13
+ and
14
+ - `static_cast<const C&>(std::move(E))` otherwise.
15
+
16
  ### Boolean testability <a id="concept.booleantestable">[[concept.booleantestable]]</a>
17
 
18
  The exposition-only `boolean-testable` concept specifies the
19
  requirements on expressions that are convertible to `bool` and for which
20
+ the logical operators
21
+ [[expr.log.and]], [[expr.log.or]], [[expr.unary.op]] have the
22
+ conventional semantics.
23
 
24
  ``` cpp
25
  template<class T>
26
  concept boolean-testable-impl = convertible_to<T, bool>; // exposition only
27
  ```
28
 
29
  Let `e` be an expression such that `decltype((e))` is `T`. `T` models
30
  `boolean-testable-impl` only if:
31
 
32
+ - either `remove_cvref_t<T>` is not a class type, or a search for the
33
+ names `operator&&` and `operator||` in the scope of
34
+ `remove_cvref_t<T>` finds nothing; and
35
+ - argument-dependent lookup [[basic.lookup.argdep]] for the names
36
+ `operator&&` and `operator||` with `T` as the only argument type finds
37
+ no disqualifying declaration (defined below).
 
38
 
39
  A *disqualifying parameter* is a function parameter whose declared type
40
  `P`
41
 
42
  - is not dependent on a template parameter, and there exists an implicit
 
48
  arguments in a function call [[temp.deduct.call]] and `e` as the
49
  argument succeeds.
50
 
51
  A *key parameter* of a function template `D` is a function parameter of
52
  type cv `X` or reference thereto, where `X` names a specialization of a
53
+ class template that has the same innermost enclosing non-inline
54
+ namespace as `D`, and `X` contains at least one template parameter that
55
+ participates in template argument deduction.
56
 
57
  [*Example 1*:
58
 
59
  In
60
 
 
79
  disqualifying parameter; or
80
  - a function template declaration that contains at least one
81
  disqualifying parameter, where
82
  - at least one disqualifying parameter is a key parameter; or
83
  - the declaration contains no key parameters; or
84
+ - the declaration declares a function template to which no name is
85
+ bound [[dcl.meaning]].
86
 
87
  [*Note 1*: The intention is to ensure that given two types `T1` and
88
  `T2` that each model `boolean-testable-impl`, the `&&` and `||`
89
  operators within the expressions `declval<T1>() && declval<T2>()` and
90
  `declval<T1>() || declval<T2>()` resolve to the corresponding built-in
 
101
  Let `e` be an expression such that `decltype((e))` is `T`. `T` models
102
  `boolean-testable` only if `bool(e) == !bool(!e)`.
103
 
104
  [*Example 2*: The types `bool`, `true_type` [[meta.type.synop]],
105
  `int*`, and `bitset<N>::reference` [[template.bitset]] model
106
+ `boolean-testable`. — *end example*]
107
+
108
+ ### Comparison common types <a id="concept.comparisoncommontype">[[concept.comparisoncommontype]]</a>
109
+
110
+ ``` cpp
111
+ template<class T, class U, class C = common_reference_t<const T&, const U&>>
112
+ concept comparison-common-type-with-impl = // exposition only
113
+ same_as<common_reference_t<const T&, const U&>,
114
+ common_reference_t<const U&, const T&>> &&
115
+ requires {
116
+ requires convertible_to<const T&, const C&> || convertible_to<T, const C&>;
117
+ requires convertible_to<const U&, const C&> || convertible_to<U, const C&>;
118
+ };
119
+
120
+ template<class T, class U>
121
+ concept comparison-common-type-with = // exposition only
122
+ comparison-common-type-with-impl<remove_cvref_t<T>, remove_cvref_t<U>>;
123
+ ```
124
+
125
+ Let `C` be `common_reference_t<const T&, const U&>`. Let `t1` and `t2`
126
+ be equality-preserving expressions that are lvalues of type
127
+ `remove_cvref_t<T>`, and let `u1` and `u2` be equality-preserving
128
+ expressions that are lvalues of type `remove_cvref_t<U>`. `T` and `U`
129
+ model `comparison-common-type-with<T, U>` only if:
130
+
131
+ - `CONVERT_TO_LVALUE<C>(t1)` equals `CONVERT_TO_LVALUE<C>(t2)` if and
132
+ only if `t1` equals `t2`, and
133
+ - `CONVERT_TO_LVALUE<C>(u1)` equals `CONVERT_TO_LVALUE<C>(u2)` if and
134
+ only if `u1` equals `u2`
135
 
136
  ### Concept <a id="concept.equalitycomparable">[[concept.equalitycomparable]]</a>
137
 
138
  ``` cpp
139
  template<class T, class U>
 
147
  };
148
  ```
149
 
150
  Given types `T` and `U`, let `t` and `u` be lvalues of types
151
  `const remove_reference_t<T>` and `const remove_reference_t<U>`
152
+ respectively. `T` and `U` model `weakly-equality-comparable-with<T, U>`
153
+ only if
154
 
155
  - `t == u`, `u == t`, `t != u`, and `u != t` have the same domain.
156
  - `bool(u == t) == bool(t == u)`.
157
  - `bool(t != u) == !bool(t == u)`.
158
  - `bool(u != t) == bool(t != u)`.
 
172
 
173
  ``` cpp
174
  template<class T, class U>
175
  concept equality_comparable_with =
176
  equality_comparable<T> && equality_comparable<U> &&
177
+ comparison-common-type-with<T, U> &&
178
  equality_comparable<
179
  common_reference_t<
180
  const remove_reference_t<T>&,
181
  const remove_reference_t<U>&>> &&
182
  weakly-equality-comparable-with<T, U>;
183
  ```
184
 
185
+ Given types `T` and `U`, let `t` and `t2` be lvalues denoting distinct
186
+ equal objects of types `const remove_reference_t<T>` and
187
+ `remove_cvref_t<T>`, respectively, let `u` and `u2` be lvalues denoting
188
+ distinct equal objects of types `const remove_reference_t<U>` and
189
+ `remove_cvref_t<U>`, respectively, and let `C` be:
190
 
191
  ``` cpp
192
  common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&>
193
  ```
194
 
195
  `T` and `U` model `equality_comparable_with<T, U>` only if
196
+
197
+ ``` cpp
198
+ bool(t == u) == bool(CONVERT_TO_LVALUE<C>(t2) == CONVERT_TO_LVALUE<C>(u2))
199
+ ```
200
 
201
  ### Concept <a id="concept.totallyordered">[[concept.totallyordered]]</a>
202
 
203
  ``` cpp
204
  template<class T>
 
225
  const remove_reference_t<T>&,
226
  const remove_reference_t<U>&>> &&
227
  partially-ordered-with<T, U>;
228
  ```
229
 
230
+ Given types `T` and `U`, let `t` and `t2` be lvalues denoting distinct
231
+ equal objects of types `const remove_reference_t<T>` and
232
+ `remove_cvref_t<T>`, respectively, let `u` and `u2` be lvalues denoting
233
+ distinct equal objects of types `const remove_reference_t<U>` and
234
+ `remove_cvref_t<U>`, respectively, and let `C` be:
235
 
236
  ``` cpp
237
  common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&>
238
  ```
239
 
240
  `T` and `U` model `totally_ordered_with<T, U>` only if
241
 
242
+ - `bool(t < u) == bool(`*`CONVERT_TO_LVALUE`*`<C>(t2) < `*`CONVERT_TO_LVALUE`*`<C>(u2))`.
243
+ - `bool(t > u) == bool(`*`CONVERT_TO_LVALUE`*`<C>(t2) > `*`CONVERT_TO_LVALUE`*`<C>(u2))`.
244
+ - `bool(t <= u) == bool(`*`CONVERT_TO_LVALUE`*`<C>(t2) <= `*`CONVERT_TO_LVALUE`*`<C>(u2))`.
245
+ - `bool(t >= u) == bool(`*`CONVERT_TO_LVALUE`*`<C>(t2) >= `*`CONVERT_TO_LVALUE`*`<C>(u2))`.
246
+ - `bool(u < t) == bool(`*`CONVERT_TO_LVALUE`*`<C>(u2) < `*`CONVERT_TO_LVALUE`*`<C>(t2))`.
247
+ - `bool(u > t) == bool(`*`CONVERT_TO_LVALUE`*`<C>(u2) > `*`CONVERT_TO_LVALUE`*`<C>(t2))`.
248
+ - `bool(u <= t) == bool(`*`CONVERT_TO_LVALUE`*`<C>(u2) <= `*`CONVERT_TO_LVALUE`*`<C>(t2))`.
249
+ - `bool(u >= t) == bool(`*`CONVERT_TO_LVALUE`*`<C>(u2) >= `*`CONVERT_TO_LVALUE`*`<C>(t2))`.
250