From Jason Turner

[class.compare]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpfy1p7l79/{from.md → to.md} +234 -0
tmp/tmpfy1p7l79/{from.md → to.md} RENAMED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Comparisons <a id="class.compare">[[class.compare]]</a>
2
+
3
+ ### Defaulted comparison operator functions <a id="class.compare.default">[[class.compare.default]]</a>
4
+
5
+ A defaulted comparison operator function [[over.binary]] for some class
6
+ `C` shall be a non-template function that is
7
+
8
+ - a non-static const non-volatile member of `C` having one parameter of
9
+ type `const C&` and either no *ref-qualifier* or the *ref-qualifier*
10
+ `&`, or
11
+ - a friend of `C` having either two parameters of type `const C&` or two
12
+ parameters of type `C`.
13
+
14
+ A comparison operator function for class `C` that is defaulted on its
15
+ first declaration and is not defined as deleted is *implicitly defined*
16
+ when it is odr-used or needed for constant evaluation. Name lookups in
17
+ the defaulted definition of a comparison operator function are performed
18
+ from a context equivalent to its *function-body*. A definition of a
19
+ comparison operator as defaulted that appears in a class shall be the
20
+ first declaration of that function.
21
+
22
+ A defaulted `<=>` or `==` operator function for class `C` is defined as
23
+ deleted if any non-static data member of `C` is of reference type or `C`
24
+ has variant members [[class.union.anon]].
25
+
26
+ A binary operator expression `a @ b` is *usable* if either
27
+
28
+ - `a` or `b` is of class or enumeration type and overload resolution
29
+ [[over.match]] as applied to `a @ b` results in a usable candidate, or
30
+ - neither `a` nor `b` is of class or enumeration type and `a @ b` is a
31
+ valid expression.
32
+
33
+ A defaulted comparison function is *constexpr-compatible* if it
34
+ satisfies the requirements for a constexpr function [[dcl.constexpr]]
35
+ and no overload resolution performed when determining whether to delete
36
+ the function results in a usable candidate that is a non-constexpr
37
+ function.
38
+
39
+ [*Note 1*:
40
+
41
+ This includes the overload resolutions performed:
42
+
43
+ - for an `operator<=>` whose return type is not `auto`, when determining
44
+ whether a synthesized three-way comparison is defined,
45
+ - for an `operator<=>` whose return type is `auto` or for an
46
+ `operator==`, for a comparison between an element of the expanded list
47
+ of subobjects and itself, or
48
+ - for a secondary comparison operator `@`, for the expression `x @ y`.
49
+
50
+ — *end note*]
51
+
52
+ If the *member-specification* does not explicitly declare any member or
53
+ friend named `operator==`, an `==` operator function is declared
54
+ implicitly for each three-way comparison operator function defined as
55
+ defaulted in the *member-specification*, with the same access and
56
+ *function-definition* and in the same class scope as the respective
57
+ three-way comparison operator function, except that the return type is
58
+ replaced with `bool` and the *declarator-id* is replaced with
59
+ `operator==`.
60
+
61
+ [*Note 2*: Such an implicitly-declared `==` operator for a class `X` is
62
+ defined as defaulted in the definition of `X` and has the same
63
+ *parameter-declaration-clause* and trailing *requires-clause* as the
64
+ respective three-way comparison operator. It is declared with `friend`,
65
+ `virtual`, `constexpr`, or `consteval` if the three-way comparison
66
+ operator function is so declared. If the three-way comparison operator
67
+ function has no *noexcept-specifier*, the implicitly-declared `==`
68
+ operator function has an implicit exception specification
69
+ [[except.spec]] that may differ from the implicit exception
70
+ specification of the three-way comparison operator
71
+ function. — *end note*]
72
+
73
+ [*Example 1*:
74
+
75
+ ``` cpp
76
+ template<typename T> struct X {
77
+ friend constexpr std::partial_ordering operator<=>(X, X) requires (sizeof(T) != 1) = default;
78
+ // implicitly declares: friend constexpr bool operator==(X, X) requires (sizeof(T) != 1) = default;
79
+
80
+ [[nodiscard]] virtual std::strong_ordering operator<=>(const X&) const = default;
81
+ // implicitly declares: [[nodiscard]] virtual bool operator==(const X&) const = default;
82
+ };
83
+ ```
84
+
85
+ — *end example*]
86
+
87
+ [*Note 3*: The `==` operator function is declared implicitly even if
88
+ the defaulted three-way comparison operator function is defined as
89
+ deleted. — *end note*]
90
+
91
+ The direct base class subobjects of `C`, in the order of their
92
+ declaration in the *base-specifier-list* of `C`, followed by the
93
+ non-static data members of `C`, in the order of their declaration in the
94
+ *member-specification* of `C`, form a list of subobjects. In that list,
95
+ any subobject of array type is recursively expanded to the sequence of
96
+ its elements, in the order of increasing subscript. Let `xᵢ` be an
97
+ lvalue denoting the iᵗʰ element in the expanded list of subobjects for
98
+ an object `x` (of length n), where `xᵢ` is formed by a sequence of
99
+ derived-to-base conversions [[over.best.ics]], class member access
100
+ expressions [[expr.ref]], and array subscript expressions [[expr.sub]]
101
+ applied to `x`.
102
+
103
+ ### Equality operator <a id="class.eq">[[class.eq]]</a>
104
+
105
+ A defaulted equality operator function [[over.binary]] shall have a
106
+ declared return type `bool`.
107
+
108
+ A defaulted `==` operator function for a class `C` is defined as deleted
109
+ unless, for each `xᵢ` in the expanded list of subobjects for an object
110
+ `x` of type `C`, `xᵢ`` == ``xᵢ` is usable [[class.compare.default]].
111
+
112
+ The return value `V` of a defaulted `==` operator function with
113
+ parameters `x` and `y` is determined by comparing corresponding elements
114
+ `xᵢ` and `yᵢ` in the expanded lists of subobjects for `x` and `y` (in
115
+ increasing index order) until the first index i where `xᵢ`` == ``yᵢ`
116
+ yields a result value which, when contextually converted to `bool`,
117
+ yields `false`. If no such index exists, `V` is `true`. Otherwise, `V`
118
+ is `false`.
119
+
120
+ [*Example 1*:
121
+
122
+ ``` cpp
123
+ struct D {
124
+ int i;
125
+ friend bool operator==(const D& x, const D& y) = default;
126
+ // OK, returns x.i == y.i
127
+ };
128
+ ```
129
+
130
+ — *end example*]
131
+
132
+ ### Three-way comparison <a id="class.spaceship">[[class.spaceship]]</a>
133
+
134
+ The *synthesized three-way comparison* of type `R` [[cmp.categories]] of
135
+ glvalues `a` and `b` of the same type is defined as follows:
136
+
137
+ - If `a <=> b` is usable [[class.compare.default]],
138
+ `static_cast<R>(a <=> b)`.
139
+ - Otherwise, if overload resolution for `a <=> b` is performed and finds
140
+ at least one viable candidate, the synthesized three-way comparison is
141
+ not defined.
142
+ - Otherwise, if `R` is not a comparison category type, or either the
143
+ expression `a == b` or the expression `a < b` is not usable, the
144
+ synthesized three-way comparison is not defined.
145
+ - Otherwise, if `R` is `strong_ordering`, then
146
+ ``` cpp
147
+ a == b ? strong_ordering::equal :
148
+ a < b ? strong_ordering::less :
149
+ strong_ordering::greater
150
+ ```
151
+ - Otherwise, if `R` is `weak_ordering`, then
152
+ ``` cpp
153
+ a == b ? weak_ordering::equivalent :
154
+ a < b ? weak_ordering::less :
155
+ weak_ordering::greater
156
+ ```
157
+ - Otherwise (when `R` is `partial_ordering`),
158
+ ``` cpp
159
+ a == b ? partial_ordering::equivalent :
160
+ a < b ? partial_ordering::less :
161
+ b < a ? partial_ordering::greater :
162
+ partial_ordering::unordered
163
+ ```
164
+
165
+ [*Note 1*: A synthesized three-way comparison may be ill-formed if
166
+ overload resolution finds usable candidates that do not otherwise meet
167
+ the requirements implied by the defined expression. — *end note*]
168
+
169
+ Let `R` be the declared return type of a defaulted three-way comparison
170
+ operator function, and let `xᵢ` be the elements of the expanded list of
171
+ subobjects for an object `x` of type `C`.
172
+
173
+ - If `R` is `auto`, then let cvᵢ~`Rᵢ` be the type of the expression
174
+ `xᵢ`` <=> ``xᵢ`. The operator function is defined as deleted if that
175
+ expression is not usable or if `Rᵢ` is not a comparison category type
176
+ [[cmp.categories.pre]] for any i. The return type is deduced as the
177
+ common comparison type (see below) of `R₀`, `R₁`, …, `R_n-1`.
178
+ - Otherwise, `R` shall not contain a placeholder type. If the
179
+ synthesized three-way comparison of type `R` between any objects `xᵢ`
180
+ and `xᵢ` is not defined, the operator function is defined as deleted.
181
+
182
+ The return value `V` of type `R` of the defaulted three-way comparison
183
+ operator function with parameters `x` and `y` of the same type is
184
+ determined by comparing corresponding elements `xᵢ` and `yᵢ` in the
185
+ expanded lists of subobjects for `x` and `y` (in increasing index order)
186
+ until the first index i where the synthesized three-way comparison of
187
+ type `R` between `xᵢ` and `yᵢ` yields a result value `vᵢ` where
188
+ `vᵢ` `!=` 0, contextually converted to `bool`, yields `true`; `V` is a
189
+ copy of `vᵢ`. If no such index exists, `V` is
190
+ `static_cast<R>(std::strong_ordering::equal)`.
191
+
192
+ The *common comparison type* `U` of a possibly-empty list of n
193
+ comparison category types `T₀`, `T₁`, …, `T_n-1` is defined as follows:
194
+
195
+ - If at least one `Tᵢ` is `std::partial_ordering`, `U` is
196
+ `std::partial_ordering` [[cmp.partialord]].
197
+ - Otherwise, if at least one `Tᵢ` is `std::weak_ordering`, `U` is
198
+ `std::weak_ordering` [[cmp.weakord]].
199
+ - Otherwise, `U` is `std::strong_ordering` [[cmp.strongord]].
200
+ \[*Note 2*: In particular, this is the result when n is
201
+ 0. — *end note*]
202
+
203
+ ### Secondary comparison operators <a id="class.compare.secondary">[[class.compare.secondary]]</a>
204
+
205
+ A *secondary comparison operator* is a relational operator [[expr.rel]]
206
+ or the `!=` operator. A defaulted operator function [[over.binary]] for
207
+ a secondary comparison operator `@` shall have a declared return type
208
+ `bool`.
209
+
210
+ The operator function with parameters `x` and `y` is defined as deleted
211
+ if
212
+
213
+ - overload resolution [[over.match]], as applied to `x @ y`, does not
214
+ result in a usable candidate, or
215
+ - the candidate selected by overload resolution is not a rewritten
216
+ candidate.
217
+
218
+ Otherwise, the operator function yields `x @ y`. The defaulted operator
219
+ function is not considered as a candidate in the overload resolution for
220
+ the `@` operator.
221
+
222
+ [*Example 1*:
223
+
224
+ ``` cpp
225
+ struct HasNoLessThan { };
226
+
227
+ struct C {
228
+ friend HasNoLessThan operator<=>(const C&, const C&);
229
+ bool operator<(const C&) const = default; // OK, function is deleted
230
+ };
231
+ ```
232
+
233
+ — *end example*]
234
+