1 | #ifndef STD_COMPARE_H |
2 | #define STD_COMPARE_H |
3 | |
4 | namespace std { |
5 | inline namespace __1 { |
6 | |
7 | // exposition only |
8 | enum class _EqResult : unsigned char { |
9 | __zero = 0, |
10 | __equal = __zero, |
11 | __equiv = __equal, |
12 | __nonequal = 1, |
13 | __nonequiv = __nonequal |
14 | }; |
15 | |
16 | enum class _OrdResult : signed char { |
17 | __less = -1, |
18 | __greater = 1 |
19 | }; |
20 | |
21 | enum class _NCmpResult : signed char { |
22 | __unordered = -127 |
23 | }; |
24 | |
25 | struct _CmpUnspecifiedType; |
26 | using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)(); |
27 | |
28 | class weak_equality { |
29 | constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {} |
30 | |
31 | public: |
32 | static const weak_equality equivalent; |
33 | static const weak_equality nonequivalent; |
34 | |
35 | friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept; |
36 | friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept; |
37 | friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept; |
38 | friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept; |
39 | friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept; |
40 | friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept; |
41 | |
42 | // test helper |
43 | constexpr bool test_eq(weak_equality const &other) const noexcept { |
44 | return __value_ == other.__value_; |
45 | } |
46 | |
47 | private: |
48 | _EqResult __value_; |
49 | }; |
50 | |
51 | inline constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv); |
52 | inline constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv); |
53 | inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept { |
54 | return __v.__value_ == _EqResult::__zero; |
55 | } |
56 | inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept { |
57 | return __v.__value_ == _EqResult::__zero; |
58 | } |
59 | inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept { |
60 | return __v.__value_ != _EqResult::__zero; |
61 | } |
62 | inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept { |
63 | return __v.__value_ != _EqResult::__zero; |
64 | } |
65 | |
66 | inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept { |
67 | return __v; |
68 | } |
69 | inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept { |
70 | return __v; |
71 | } |
72 | |
73 | class strong_equality { |
74 | explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {} |
75 | |
76 | public: |
77 | static const strong_equality equal; |
78 | static const strong_equality nonequal; |
79 | static const strong_equality equivalent; |
80 | static const strong_equality nonequivalent; |
81 | |
82 | // conversion |
83 | constexpr operator weak_equality() const noexcept { |
84 | return __value_ == _EqResult::__zero ? weak_equality::equivalent |
85 | : weak_equality::nonequivalent; |
86 | } |
87 | |
88 | // comparisons |
89 | friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept; |
90 | friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept; |
91 | friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept; |
92 | friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept; |
93 | |
94 | friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept; |
95 | friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept; |
96 | |
97 | // test helper |
98 | constexpr bool test_eq(strong_equality const &other) const noexcept { |
99 | return __value_ == other.__value_; |
100 | } |
101 | |
102 | private: |
103 | _EqResult __value_; |
104 | }; |
105 | |
106 | inline constexpr strong_equality strong_equality::equal(_EqResult::__equal); |
107 | inline constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal); |
108 | inline constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv); |
109 | inline constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv); |
110 | constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept { |
111 | return __v.__value_ == _EqResult::__zero; |
112 | } |
113 | constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept { |
114 | return __v.__value_ == _EqResult::__zero; |
115 | } |
116 | constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept { |
117 | return __v.__value_ != _EqResult::__zero; |
118 | } |
119 | constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept { |
120 | return __v.__value_ != _EqResult::__zero; |
121 | } |
122 | |
123 | constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept { |
124 | return __v; |
125 | } |
126 | constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept { |
127 | return __v; |
128 | } |
129 | |
130 | class partial_ordering { |
131 | using _ValueT = signed char; |
132 | explicit constexpr partial_ordering(_EqResult __v) noexcept |
133 | : __value_(_ValueT(__v)) {} |
134 | explicit constexpr partial_ordering(_OrdResult __v) noexcept |
135 | : __value_(_ValueT(__v)) {} |
136 | explicit constexpr partial_ordering(_NCmpResult __v) noexcept |
137 | : __value_(_ValueT(__v)) {} |
138 | |
139 | constexpr bool __is_ordered() const noexcept { |
140 | return __value_ != _ValueT(_NCmpResult::__unordered); |
141 | } |
142 | |
143 | public: |
144 | // valid values |
145 | static const partial_ordering less; |
146 | static const partial_ordering equivalent; |
147 | static const partial_ordering greater; |
148 | static const partial_ordering unordered; |
149 | |
150 | // conversion |
151 | constexpr operator weak_equality() const noexcept { |
152 | return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent; |
153 | } |
154 | |
155 | // comparisons |
156 | friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept; |
157 | friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; |
158 | friend constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept; |
159 | friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; |
160 | friend constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept; |
161 | friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; |
162 | friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept; |
163 | friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; |
164 | friend constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept; |
165 | friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; |
166 | friend constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept; |
167 | friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; |
168 | |
169 | friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept; |
170 | friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept; |
171 | |
172 | // test helper |
173 | constexpr bool test_eq(partial_ordering const &other) const noexcept { |
174 | return __value_ == other.__value_; |
175 | } |
176 | |
177 | private: |
178 | _ValueT __value_; |
179 | }; |
180 | |
181 | inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less); |
182 | inline constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv); |
183 | inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater); |
184 | inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered); |
185 | constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { |
186 | return __v.__is_ordered() && __v.__value_ == 0; |
187 | } |
188 | constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept { |
189 | return __v.__is_ordered() && __v.__value_ < 0; |
190 | } |
191 | constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { |
192 | return __v.__is_ordered() && __v.__value_ <= 0; |
193 | } |
194 | constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { |
195 | return __v.__is_ordered() && __v.__value_ > 0; |
196 | } |
197 | constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { |
198 | return __v.__is_ordered() && __v.__value_ >= 0; |
199 | } |
200 | constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept { |
201 | return __v.__is_ordered() && 0 == __v.__value_; |
202 | } |
203 | constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept { |
204 | return __v.__is_ordered() && 0 < __v.__value_; |
205 | } |
206 | constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { |
207 | return __v.__is_ordered() && 0 <= __v.__value_; |
208 | } |
209 | constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { |
210 | return __v.__is_ordered() && 0 > __v.__value_; |
211 | } |
212 | constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { |
213 | return __v.__is_ordered() && 0 >= __v.__value_; |
214 | } |
215 | constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { |
216 | return !__v.__is_ordered() || __v.__value_ != 0; |
217 | } |
218 | constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { |
219 | return !__v.__is_ordered() || __v.__value_ != 0; |
220 | } |
221 | |
222 | constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { |
223 | return __v; |
224 | } |
225 | constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { |
226 | return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); |
227 | } |
228 | |
229 | class weak_ordering { |
230 | using _ValueT = signed char; |
231 | explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {} |
232 | explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} |
233 | |
234 | public: |
235 | static const weak_ordering less; |
236 | static const weak_ordering equivalent; |
237 | static const weak_ordering greater; |
238 | |
239 | // conversions |
240 | constexpr operator weak_equality() const noexcept { |
241 | return __value_ == 0 ? weak_equality::equivalent |
242 | : weak_equality::nonequivalent; |
243 | } |
244 | constexpr operator partial_ordering() const noexcept { |
245 | return __value_ == 0 ? partial_ordering::equivalent |
246 | : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); |
247 | } |
248 | |
249 | // comparisons |
250 | friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept; |
251 | friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; |
252 | friend constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept; |
253 | friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; |
254 | friend constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept; |
255 | friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; |
256 | friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept; |
257 | friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; |
258 | friend constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept; |
259 | friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; |
260 | friend constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept; |
261 | friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; |
262 | |
263 | friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept; |
264 | friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept; |
265 | |
266 | // test helper |
267 | constexpr bool test_eq(weak_ordering const &other) const noexcept { |
268 | return __value_ == other.__value_; |
269 | } |
270 | |
271 | private: |
272 | _ValueT __value_; |
273 | }; |
274 | |
275 | inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less); |
276 | inline constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv); |
277 | inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); |
278 | constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { |
279 | return __v.__value_ == 0; |
280 | } |
281 | constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { |
282 | return __v.__value_ != 0; |
283 | } |
284 | constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept { |
285 | return __v.__value_ < 0; |
286 | } |
287 | constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { |
288 | return __v.__value_ <= 0; |
289 | } |
290 | constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { |
291 | return __v.__value_ > 0; |
292 | } |
293 | constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { |
294 | return __v.__value_ >= 0; |
295 | } |
296 | constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept { |
297 | return 0 == __v.__value_; |
298 | } |
299 | constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { |
300 | return 0 != __v.__value_; |
301 | } |
302 | constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept { |
303 | return 0 < __v.__value_; |
304 | } |
305 | constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { |
306 | return 0 <= __v.__value_; |
307 | } |
308 | constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { |
309 | return 0 > __v.__value_; |
310 | } |
311 | constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { |
312 | return 0 >= __v.__value_; |
313 | } |
314 | |
315 | constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { |
316 | return __v; |
317 | } |
318 | constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { |
319 | return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); |
320 | } |
321 | |
322 | class strong_ordering { |
323 | using _ValueT = signed char; |
324 | explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(static_cast<signed char>(__v)) {} |
325 | explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(static_cast<signed char>(__v)) {} |
326 | |
327 | public: |
328 | static const strong_ordering less; |
329 | static const strong_ordering equal; |
330 | static const strong_ordering equivalent; |
331 | static const strong_ordering greater; |
332 | |
333 | // conversions |
334 | constexpr operator weak_equality() const noexcept { |
335 | return __value_ == 0 ? weak_equality::equivalent |
336 | : weak_equality::nonequivalent; |
337 | } |
338 | constexpr operator strong_equality() const noexcept { |
339 | return __value_ == 0 ? strong_equality::equal |
340 | : strong_equality::nonequal; |
341 | } |
342 | constexpr operator partial_ordering() const noexcept { |
343 | return __value_ == 0 ? partial_ordering::equivalent |
344 | : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); |
345 | } |
346 | constexpr operator weak_ordering() const noexcept { |
347 | return __value_ == 0 ? weak_ordering::equivalent |
348 | : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); |
349 | } |
350 | |
351 | // comparisons |
352 | friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept; |
353 | friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; |
354 | friend constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept; |
355 | friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; |
356 | friend constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept; |
357 | friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; |
358 | friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept; |
359 | friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; |
360 | friend constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept; |
361 | friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; |
362 | friend constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept; |
363 | friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; |
364 | |
365 | friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept; |
366 | friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept; |
367 | |
368 | // test helper |
369 | constexpr bool test_eq(strong_ordering const &other) const noexcept { |
370 | return __value_ == other.__value_; |
371 | } |
372 | |
373 | private: |
374 | _ValueT __value_; |
375 | }; |
376 | |
377 | inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less); |
378 | inline constexpr strong_ordering strong_ordering::equal(_EqResult::__equal); |
379 | inline constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv); |
380 | inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); |
381 | |
382 | constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { |
383 | return __v.__value_ == 0; |
384 | } |
385 | constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { |
386 | return __v.__value_ != 0; |
387 | } |
388 | constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept { |
389 | return __v.__value_ < 0; |
390 | } |
391 | constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { |
392 | return __v.__value_ <= 0; |
393 | } |
394 | constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { |
395 | return __v.__value_ > 0; |
396 | } |
397 | constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { |
398 | return __v.__value_ >= 0; |
399 | } |
400 | constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept { |
401 | return 0 == __v.__value_; |
402 | } |
403 | constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { |
404 | return 0 != __v.__value_; |
405 | } |
406 | constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept { |
407 | return 0 < __v.__value_; |
408 | } |
409 | constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { |
410 | return 0 <= __v.__value_; |
411 | } |
412 | constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { |
413 | return 0 > __v.__value_; |
414 | } |
415 | constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { |
416 | return 0 >= __v.__value_; |
417 | } |
418 | |
419 | constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { |
420 | return __v; |
421 | } |
422 | constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { |
423 | return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); |
424 | } |
425 | |
426 | // named comparison functions |
427 | constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; } |
428 | constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; } |
429 | constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; } |
430 | constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; } |
431 | constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; } |
432 | constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; } |
433 | |
434 | } // namespace __1 |
435 | } // end namespace std |
436 | |
437 | #endif // STD_COMPARE_H |
438 | |