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   __equal = 0,
10   __equiv = __equal,
11 };
12 
13 enum class _OrdResult : signed char {
14   __less = -1,
15   __greater = 1
16 };
17 
18 enum class _NCmpResult : signed char {
19   __unordered = -127
20 };
21 
22 struct _CmpUnspecifiedType;
23 using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)();
24 
25 class partial_ordering {
26   using _ValueT = signed char;
partial_ordering(_EqResult __v)27   explicit constexpr partial_ordering(_EqResult __v) noexcept
28       : __value_(_ValueT(__v)) {}
partial_ordering(_OrdResult __v)29   explicit constexpr partial_ordering(_OrdResult __v) noexcept
30       : __value_(_ValueT(__v)) {}
partial_ordering(_NCmpResult __v)31   explicit constexpr partial_ordering(_NCmpResult __v) noexcept
32       : __value_(_ValueT(__v)) {}
33 
__is_ordered()34   constexpr bool __is_ordered() const noexcept {
35     return __value_ != _ValueT(_NCmpResult::__unordered);
36   }
37 
38 public:
39   // valid values
40   static const partial_ordering less;
41   static const partial_ordering equivalent;
42   static const partial_ordering greater;
43   static const partial_ordering unordered;
44 
45   // comparisons
46   friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
47   friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
48   friend constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
49   friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
50   friend constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
51   friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
52   friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
53   friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
54   friend constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
55   friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
56   friend constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
57   friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
58 
59   friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
60   friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
61 
62   // test helper
test_eq(partial_ordering const & other)63   constexpr bool test_eq(partial_ordering const &other) const noexcept {
64     return __value_ == other.__value_;
65   }
66 
67 private:
68   _ValueT __value_;
69 };
70 
71 inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
72 inline constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv);
73 inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
74 inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
75 constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
76   return __v.__is_ordered() && __v.__value_ == 0;
77 }
78 constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
79   return __v.__is_ordered() && __v.__value_ < 0;
80 }
81 constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
82   return __v.__is_ordered() && __v.__value_ <= 0;
83 }
84 constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
85   return __v.__is_ordered() && __v.__value_ > 0;
86 }
87 constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
88   return __v.__is_ordered() && __v.__value_ >= 0;
89 }
90 constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
91   return __v.__is_ordered() && 0 == __v.__value_;
92 }
93 constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
94   return __v.__is_ordered() && 0 < __v.__value_;
95 }
96 constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
97   return __v.__is_ordered() && 0 <= __v.__value_;
98 }
99 constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
100   return __v.__is_ordered() && 0 > __v.__value_;
101 }
102 constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
103   return __v.__is_ordered() && 0 >= __v.__value_;
104 }
105 constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
106   return !__v.__is_ordered() || __v.__value_ != 0;
107 }
108 constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
109   return !__v.__is_ordered() || __v.__value_ != 0;
110 }
111 
112 constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
113   return __v;
114 }
115 constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
116   return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
117 }
118 
119 class weak_ordering {
120   using _ValueT = signed char;
weak_ordering(_EqResult __v)121   explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
weak_ordering(_OrdResult __v)122   explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
123 
124 public:
125   static const weak_ordering less;
126   static const weak_ordering equivalent;
127   static const weak_ordering greater;
128 
129   // conversions
partial_ordering()130   constexpr operator partial_ordering() const noexcept {
131     return __value_ == 0 ? partial_ordering::equivalent
132                          : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
133   }
134 
135   // comparisons
136   friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
137   friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
138   friend constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
139   friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
140   friend constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
141   friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
142   friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
143   friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
144   friend constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
145   friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
146   friend constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
147   friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
148 
149   friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
150   friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
151 
152   // test helper
test_eq(weak_ordering const & other)153   constexpr bool test_eq(weak_ordering const &other) const noexcept {
154     return __value_ == other.__value_;
155   }
156 
157 private:
158   _ValueT __value_;
159 };
160 
161 inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
162 inline constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv);
163 inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
164 constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
165   return __v.__value_ == 0;
166 }
167 constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
168   return __v.__value_ != 0;
169 }
170 constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
171   return __v.__value_ < 0;
172 }
173 constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
174   return __v.__value_ <= 0;
175 }
176 constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
177   return __v.__value_ > 0;
178 }
179 constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
180   return __v.__value_ >= 0;
181 }
182 constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
183   return 0 == __v.__value_;
184 }
185 constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
186   return 0 != __v.__value_;
187 }
188 constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
189   return 0 < __v.__value_;
190 }
191 constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
192   return 0 <= __v.__value_;
193 }
194 constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
195   return 0 > __v.__value_;
196 }
197 constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
198   return 0 >= __v.__value_;
199 }
200 
201 constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
202   return __v;
203 }
204 constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
205   return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
206 }
207 
208 class strong_ordering {
209   using _ValueT = signed char;
strong_ordering(_EqResult __v)210   explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(static_cast<signed char>(__v)) {}
strong_ordering(_OrdResult __v)211   explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(static_cast<signed char>(__v)) {}
212 
213 public:
214   static const strong_ordering less;
215   static const strong_ordering equal;
216   static const strong_ordering equivalent;
217   static const strong_ordering greater;
218 
219   // conversions
partial_ordering()220   constexpr operator partial_ordering() const noexcept {
221     return __value_ == 0 ? partial_ordering::equivalent
222                          : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
223   }
weak_ordering()224   constexpr operator weak_ordering() const noexcept {
225     return __value_ == 0 ? weak_ordering::equivalent
226                          : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
227   }
228 
229   // comparisons
230   friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
231   friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
232   friend constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
233   friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
234   friend constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
235   friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
236   friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
237   friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
238   friend constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
239   friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
240   friend constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
241   friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
242 
243   friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
244   friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
245 
246   // test helper
test_eq(strong_ordering const & other)247   constexpr bool test_eq(strong_ordering const &other) const noexcept {
248     return __value_ == other.__value_;
249   }
250 
251 private:
252   _ValueT __value_;
253 };
254 
255 inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
256 inline constexpr strong_ordering strong_ordering::equal(_EqResult::__equal);
257 inline constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv);
258 inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
259 
260 constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
261   return __v.__value_ == 0;
262 }
263 constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
264   return __v.__value_ != 0;
265 }
266 constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
267   return __v.__value_ < 0;
268 }
269 constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
270   return __v.__value_ <= 0;
271 }
272 constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
273   return __v.__value_ > 0;
274 }
275 constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
276   return __v.__value_ >= 0;
277 }
278 constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
279   return 0 == __v.__value_;
280 }
281 constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
282   return 0 != __v.__value_;
283 }
284 constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
285   return 0 < __v.__value_;
286 }
287 constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
288   return 0 <= __v.__value_;
289 }
290 constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
291   return 0 > __v.__value_;
292 }
293 constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
294   return 0 >= __v.__value_;
295 }
296 
297 constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
298   return __v;
299 }
300 constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
301   return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
302 }
303 
304 } // namespace __1
305 } // end namespace std
306 
307 #endif // STD_COMPARE_H
308