xref: /freebsd-12.1/contrib/libc++/include/compare (revision 4ba319b5)
1*4ba319b5SDimitry Andric// -*- C++ -*-
2*4ba319b5SDimitry Andric//===-------------------------- compare -----------------------------------===//
3*4ba319b5SDimitry Andric//
4*4ba319b5SDimitry Andric//                     The LLVM Compiler Infrastructure
5*4ba319b5SDimitry Andric//
6*4ba319b5SDimitry Andric// This file is dual licensed under the MIT and the University of Illinois Open
7*4ba319b5SDimitry Andric// Source Licenses. See LICENSE.TXT for details.
8*4ba319b5SDimitry Andric//
9*4ba319b5SDimitry Andric//===----------------------------------------------------------------------===//
10*4ba319b5SDimitry Andric
11*4ba319b5SDimitry Andric#ifndef _LIBCPP_COMPARE
12*4ba319b5SDimitry Andric#define _LIBCPP_COMPARE
13*4ba319b5SDimitry Andric
14*4ba319b5SDimitry Andric/*
15*4ba319b5SDimitry Andric    compare synopsis
16*4ba319b5SDimitry Andric
17*4ba319b5SDimitry Andricnamespace std {
18*4ba319b5SDimitry Andric  // [cmp.categories], comparison category types
19*4ba319b5SDimitry Andric  class weak_equality;
20*4ba319b5SDimitry Andric  class strong_equality;
21*4ba319b5SDimitry Andric  class partial_ordering;
22*4ba319b5SDimitry Andric  class weak_ordering;
23*4ba319b5SDimitry Andric  class strong_ordering;
24*4ba319b5SDimitry Andric
25*4ba319b5SDimitry Andric  // named comparison functions
26*4ba319b5SDimitry Andric  constexpr bool is_eq  (weak_equality cmp) noexcept    { return cmp == 0; }
27*4ba319b5SDimitry Andric  constexpr bool is_neq (weak_equality cmp) noexcept    { return cmp != 0; }
28*4ba319b5SDimitry Andric  constexpr bool is_lt  (partial_ordering cmp) noexcept { return cmp < 0; }
29*4ba319b5SDimitry Andric  constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; }
30*4ba319b5SDimitry Andric  constexpr bool is_gt  (partial_ordering cmp) noexcept { return cmp > 0; }
31*4ba319b5SDimitry Andric  constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; }
32*4ba319b5SDimitry Andric
33*4ba319b5SDimitry Andric  // [cmp.common], common comparison category type
34*4ba319b5SDimitry Andric  template<class... Ts>
35*4ba319b5SDimitry Andric  struct common_comparison_category {
36*4ba319b5SDimitry Andric    using type = see below;
37*4ba319b5SDimitry Andric  };
38*4ba319b5SDimitry Andric  template<class... Ts>
39*4ba319b5SDimitry Andric    using common_comparison_category_t = typename common_comparison_category<Ts...>::type;
40*4ba319b5SDimitry Andric
41*4ba319b5SDimitry Andric  // [cmp.alg], comparison algorithms
42*4ba319b5SDimitry Andric  template<class T> constexpr strong_ordering strong_order(const T& a, const T& b);
43*4ba319b5SDimitry Andric  template<class T> constexpr weak_ordering weak_order(const T& a, const T& b);
44*4ba319b5SDimitry Andric  template<class T> constexpr partial_ordering partial_order(const T& a, const T& b);
45*4ba319b5SDimitry Andric  template<class T> constexpr strong_equality strong_equal(const T& a, const T& b);
46*4ba319b5SDimitry Andric  template<class T> constexpr weak_equality weak_equal(const T& a, const T& b);
47*4ba319b5SDimitry Andric}
48*4ba319b5SDimitry Andric*/
49*4ba319b5SDimitry Andric
50*4ba319b5SDimitry Andric#include <__config>
51*4ba319b5SDimitry Andric#include <type_traits>
52*4ba319b5SDimitry Andric#include <array>
53*4ba319b5SDimitry Andric
54*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
55*4ba319b5SDimitry Andric#pragma GCC system_header
56*4ba319b5SDimitry Andric#endif
57*4ba319b5SDimitry Andric
58*4ba319b5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
59*4ba319b5SDimitry Andric
60*4ba319b5SDimitry Andric#if _LIBCPP_STD_VER > 17
61*4ba319b5SDimitry Andric
62*4ba319b5SDimitry Andric// exposition only
63*4ba319b5SDimitry Andricenum class _LIBCPP_ENUM_VIS _EqResult : unsigned char {
64*4ba319b5SDimitry Andric  __zero = 0,
65*4ba319b5SDimitry Andric  __equal = __zero,
66*4ba319b5SDimitry Andric  __equiv = __equal,
67*4ba319b5SDimitry Andric  __nonequal = 1,
68*4ba319b5SDimitry Andric  __nonequiv = __nonequal
69*4ba319b5SDimitry Andric};
70*4ba319b5SDimitry Andric
71*4ba319b5SDimitry Andricenum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
72*4ba319b5SDimitry Andric  __less = -1,
73*4ba319b5SDimitry Andric  __greater = 1
74*4ba319b5SDimitry Andric};
75*4ba319b5SDimitry Andric
76*4ba319b5SDimitry Andricenum class _LIBCPP_ENUM_VIS _NCmpResult : signed char {
77*4ba319b5SDimitry Andric  __unordered = -127
78*4ba319b5SDimitry Andric};
79*4ba319b5SDimitry Andric
80*4ba319b5SDimitry Andricstruct _CmpUnspecifiedType;
81*4ba319b5SDimitry Andricusing _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)();
82*4ba319b5SDimitry Andric
83*4ba319b5SDimitry Andricclass  weak_equality {
84*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
85*4ba319b5SDimitry Andric  constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {}
86*4ba319b5SDimitry Andric
87*4ba319b5SDimitry Andricpublic:
88*4ba319b5SDimitry Andric  static const weak_equality equivalent;
89*4ba319b5SDimitry Andric  static const weak_equality nonequivalent;
90*4ba319b5SDimitry Andric
91*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept;
92*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept;
93*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept;
94*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept;
95*4ba319b5SDimitry Andric
96*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
97*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept;
98*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept;
99*4ba319b5SDimitry Andric#endif
100*4ba319b5SDimitry Andric
101*4ba319b5SDimitry Andricprivate:
102*4ba319b5SDimitry Andric  _EqResult __value_;
103*4ba319b5SDimitry Andric};
104*4ba319b5SDimitry Andric
105*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv);
106*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv);
107*4ba319b5SDimitry Andric
108*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
109*4ba319b5SDimitry Andricinline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept {
110*4ba319b5SDimitry Andric  return __v.__value_ == _EqResult::__zero;
111*4ba319b5SDimitry Andric}
112*4ba319b5SDimitry Andric
113*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
114*4ba319b5SDimitry Andricinline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept {
115*4ba319b5SDimitry Andric  return __v.__value_ == _EqResult::__zero;
116*4ba319b5SDimitry Andric}
117*4ba319b5SDimitry Andric
118*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
119*4ba319b5SDimitry Andricinline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept {
120*4ba319b5SDimitry Andric  return __v.__value_ != _EqResult::__zero;
121*4ba319b5SDimitry Andric}
122*4ba319b5SDimitry Andric
123*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
124*4ba319b5SDimitry Andricinline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept {
125*4ba319b5SDimitry Andric  return __v.__value_ != _EqResult::__zero;
126*4ba319b5SDimitry Andric}
127*4ba319b5SDimitry Andric
128*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
129*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
130*4ba319b5SDimitry Andricinline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept {
131*4ba319b5SDimitry Andric  return __v;
132*4ba319b5SDimitry Andric}
133*4ba319b5SDimitry Andric
134*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
135*4ba319b5SDimitry Andricinline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept {
136*4ba319b5SDimitry Andric  return __v;
137*4ba319b5SDimitry Andric}
138*4ba319b5SDimitry Andric#endif
139*4ba319b5SDimitry Andric
140*4ba319b5SDimitry Andricclass strong_equality {
141*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
142*4ba319b5SDimitry Andric  explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {}
143*4ba319b5SDimitry Andric
144*4ba319b5SDimitry Andricpublic:
145*4ba319b5SDimitry Andric  static const strong_equality equal;
146*4ba319b5SDimitry Andric  static const strong_equality nonequal;
147*4ba319b5SDimitry Andric  static const strong_equality equivalent;
148*4ba319b5SDimitry Andric  static const strong_equality nonequivalent;
149*4ba319b5SDimitry Andric
150*4ba319b5SDimitry Andric  // conversion
151*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept {
152*4ba319b5SDimitry Andric    return __value_ == _EqResult::__zero ? weak_equality::equivalent
153*4ba319b5SDimitry Andric          : weak_equality::nonequivalent;
154*4ba319b5SDimitry Andric  }
155*4ba319b5SDimitry Andric
156*4ba319b5SDimitry Andric  // comparisons
157*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept;
158*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept;
159*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept;
160*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept;
161*4ba319b5SDimitry Andric
162*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
163*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept;
164*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept;
165*4ba319b5SDimitry Andric#endif
166*4ba319b5SDimitry Andricprivate:
167*4ba319b5SDimitry Andric  _EqResult __value_;
168*4ba319b5SDimitry Andric};
169*4ba319b5SDimitry Andric
170*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equal(_EqResult::__equal);
171*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal);
172*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv);
173*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv);
174*4ba319b5SDimitry Andric
175*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
176*4ba319b5SDimitry Andricconstexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept {
177*4ba319b5SDimitry Andric  return __v.__value_ == _EqResult::__zero;
178*4ba319b5SDimitry Andric}
179*4ba319b5SDimitry Andric
180*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
181*4ba319b5SDimitry Andricconstexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept {
182*4ba319b5SDimitry Andric  return __v.__value_ == _EqResult::__zero;
183*4ba319b5SDimitry Andric}
184*4ba319b5SDimitry Andric
185*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
186*4ba319b5SDimitry Andricconstexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept {
187*4ba319b5SDimitry Andric  return __v.__value_ != _EqResult::__zero;
188*4ba319b5SDimitry Andric}
189*4ba319b5SDimitry Andric
190*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
191*4ba319b5SDimitry Andricconstexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept {
192*4ba319b5SDimitry Andric  return __v.__value_ != _EqResult::__zero;
193*4ba319b5SDimitry Andric}
194*4ba319b5SDimitry Andric
195*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
196*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
197*4ba319b5SDimitry Andricconstexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept {
198*4ba319b5SDimitry Andric  return __v;
199*4ba319b5SDimitry Andric}
200*4ba319b5SDimitry Andric
201*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
202*4ba319b5SDimitry Andricconstexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept {
203*4ba319b5SDimitry Andric  return __v;
204*4ba319b5SDimitry Andric}
205*4ba319b5SDimitry Andric#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
206*4ba319b5SDimitry Andric
207*4ba319b5SDimitry Andricclass partial_ordering {
208*4ba319b5SDimitry Andric  using _ValueT = signed char;
209*4ba319b5SDimitry Andric
210*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
211*4ba319b5SDimitry Andric  explicit constexpr partial_ordering(_EqResult __v) noexcept
212*4ba319b5SDimitry Andric      : __value_(_ValueT(__v)) {}
213*4ba319b5SDimitry Andric
214*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
215*4ba319b5SDimitry Andric  explicit constexpr partial_ordering(_OrdResult __v) noexcept
216*4ba319b5SDimitry Andric      : __value_(_ValueT(__v)) {}
217*4ba319b5SDimitry Andric
218*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
219*4ba319b5SDimitry Andric  explicit constexpr partial_ordering(_NCmpResult __v) noexcept
220*4ba319b5SDimitry Andric      : __value_(_ValueT(__v)) {}
221*4ba319b5SDimitry Andric
222*4ba319b5SDimitry Andric  constexpr bool __is_ordered() const noexcept {
223*4ba319b5SDimitry Andric    return __value_ != _ValueT(_NCmpResult::__unordered);
224*4ba319b5SDimitry Andric  }
225*4ba319b5SDimitry Andricpublic:
226*4ba319b5SDimitry Andric  // valid values
227*4ba319b5SDimitry Andric  static const partial_ordering less;
228*4ba319b5SDimitry Andric  static const partial_ordering equivalent;
229*4ba319b5SDimitry Andric  static const partial_ordering greater;
230*4ba319b5SDimitry Andric  static const partial_ordering unordered;
231*4ba319b5SDimitry Andric
232*4ba319b5SDimitry Andric  // conversion
233*4ba319b5SDimitry Andric  constexpr operator weak_equality() const noexcept {
234*4ba319b5SDimitry Andric    return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent;
235*4ba319b5SDimitry Andric  }
236*4ba319b5SDimitry Andric
237*4ba319b5SDimitry Andric  // comparisons
238*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
239*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
240*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
241*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
242*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
243*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
244*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
245*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
246*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
247*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
248*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
249*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
250*4ba319b5SDimitry Andric
251*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
252*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
253*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
254*4ba319b5SDimitry Andric#endif
255*4ba319b5SDimitry Andric
256*4ba319b5SDimitry Andricprivate:
257*4ba319b5SDimitry Andric  _ValueT __value_;
258*4ba319b5SDimitry Andric};
259*4ba319b5SDimitry Andric
260*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
261*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv);
262*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
263*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
264*4ba319b5SDimitry Andric
265*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
266*4ba319b5SDimitry Andricconstexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
267*4ba319b5SDimitry Andric  return __v.__is_ordered() && __v.__value_ == 0;
268*4ba319b5SDimitry Andric}
269*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
270*4ba319b5SDimitry Andricconstexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
271*4ba319b5SDimitry Andric  return __v.__is_ordered() && __v.__value_ < 0;
272*4ba319b5SDimitry Andric}
273*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
274*4ba319b5SDimitry Andricconstexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
275*4ba319b5SDimitry Andric  return __v.__is_ordered() && __v.__value_ <= 0;
276*4ba319b5SDimitry Andric}
277*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
278*4ba319b5SDimitry Andricconstexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
279*4ba319b5SDimitry Andric  return __v.__is_ordered() && __v.__value_ > 0;
280*4ba319b5SDimitry Andric}
281*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
282*4ba319b5SDimitry Andricconstexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
283*4ba319b5SDimitry Andric  return __v.__is_ordered() && __v.__value_ >= 0;
284*4ba319b5SDimitry Andric}
285*4ba319b5SDimitry Andric
286*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
287*4ba319b5SDimitry Andricconstexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
288*4ba319b5SDimitry Andric  return __v.__is_ordered() && 0 == __v.__value_;
289*4ba319b5SDimitry Andric}
290*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
291*4ba319b5SDimitry Andricconstexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
292*4ba319b5SDimitry Andric  return __v.__is_ordered() && 0 < __v.__value_;
293*4ba319b5SDimitry Andric}
294*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
295*4ba319b5SDimitry Andricconstexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
296*4ba319b5SDimitry Andric  return __v.__is_ordered() && 0 <= __v.__value_;
297*4ba319b5SDimitry Andric}
298*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
299*4ba319b5SDimitry Andricconstexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
300*4ba319b5SDimitry Andric  return __v.__is_ordered() && 0 > __v.__value_;
301*4ba319b5SDimitry Andric}
302*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
303*4ba319b5SDimitry Andricconstexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
304*4ba319b5SDimitry Andric  return __v.__is_ordered() && 0 >= __v.__value_;
305*4ba319b5SDimitry Andric}
306*4ba319b5SDimitry Andric
307*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
308*4ba319b5SDimitry Andricconstexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
309*4ba319b5SDimitry Andric  return !__v.__is_ordered() || __v.__value_ != 0;
310*4ba319b5SDimitry Andric}
311*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
312*4ba319b5SDimitry Andricconstexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
313*4ba319b5SDimitry Andric  return !__v.__is_ordered() || __v.__value_ != 0;
314*4ba319b5SDimitry Andric}
315*4ba319b5SDimitry Andric
316*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
317*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
318*4ba319b5SDimitry Andricconstexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
319*4ba319b5SDimitry Andric  return __v;
320*4ba319b5SDimitry Andric}
321*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
322*4ba319b5SDimitry Andricconstexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
323*4ba319b5SDimitry Andric  return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
324*4ba319b5SDimitry Andric}
325*4ba319b5SDimitry Andric#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
326*4ba319b5SDimitry Andric
327*4ba319b5SDimitry Andricclass weak_ordering {
328*4ba319b5SDimitry Andric  using _ValueT = signed char;
329*4ba319b5SDimitry Andric
330*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
331*4ba319b5SDimitry Andric  explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
332*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
333*4ba319b5SDimitry Andric  explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
334*4ba319b5SDimitry Andric
335*4ba319b5SDimitry Andricpublic:
336*4ba319b5SDimitry Andric  static const weak_ordering less;
337*4ba319b5SDimitry Andric  static const weak_ordering equivalent;
338*4ba319b5SDimitry Andric  static const weak_ordering greater;
339*4ba319b5SDimitry Andric
340*4ba319b5SDimitry Andric  // conversions
341*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
342*4ba319b5SDimitry Andric  constexpr operator weak_equality() const noexcept {
343*4ba319b5SDimitry Andric    return __value_ == 0 ? weak_equality::equivalent
344*4ba319b5SDimitry Andric                         : weak_equality::nonequivalent;
345*4ba319b5SDimitry Andric  }
346*4ba319b5SDimitry Andric
347*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
348*4ba319b5SDimitry Andric  constexpr operator partial_ordering() const noexcept {
349*4ba319b5SDimitry Andric    return __value_ == 0 ? partial_ordering::equivalent
350*4ba319b5SDimitry Andric        : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
351*4ba319b5SDimitry Andric  }
352*4ba319b5SDimitry Andric
353*4ba319b5SDimitry Andric  // comparisons
354*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
355*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
356*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
357*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
358*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
359*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
360*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
361*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
362*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
363*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
364*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
365*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
366*4ba319b5SDimitry Andric
367*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
368*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
369*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
370*4ba319b5SDimitry Andric#endif
371*4ba319b5SDimitry Andric
372*4ba319b5SDimitry Andricprivate:
373*4ba319b5SDimitry Andric  _ValueT __value_;
374*4ba319b5SDimitry Andric};
375*4ba319b5SDimitry Andric
376*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
377*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv);
378*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
379*4ba319b5SDimitry Andric
380*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
381*4ba319b5SDimitry Andricconstexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
382*4ba319b5SDimitry Andric  return __v.__value_ == 0;
383*4ba319b5SDimitry Andric}
384*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
385*4ba319b5SDimitry Andricconstexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
386*4ba319b5SDimitry Andric  return __v.__value_ != 0;
387*4ba319b5SDimitry Andric}
388*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
389*4ba319b5SDimitry Andricconstexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
390*4ba319b5SDimitry Andric  return __v.__value_ < 0;
391*4ba319b5SDimitry Andric}
392*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
393*4ba319b5SDimitry Andricconstexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
394*4ba319b5SDimitry Andric  return __v.__value_ <= 0;
395*4ba319b5SDimitry Andric}
396*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
397*4ba319b5SDimitry Andricconstexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
398*4ba319b5SDimitry Andric  return __v.__value_ > 0;
399*4ba319b5SDimitry Andric}
400*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
401*4ba319b5SDimitry Andricconstexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
402*4ba319b5SDimitry Andric  return __v.__value_ >= 0;
403*4ba319b5SDimitry Andric}
404*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
405*4ba319b5SDimitry Andricconstexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
406*4ba319b5SDimitry Andric  return 0 == __v.__value_;
407*4ba319b5SDimitry Andric}
408*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
409*4ba319b5SDimitry Andricconstexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
410*4ba319b5SDimitry Andric  return 0 != __v.__value_;
411*4ba319b5SDimitry Andric}
412*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
413*4ba319b5SDimitry Andricconstexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
414*4ba319b5SDimitry Andric  return 0 < __v.__value_;
415*4ba319b5SDimitry Andric}
416*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
417*4ba319b5SDimitry Andricconstexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
418*4ba319b5SDimitry Andric  return 0 <= __v.__value_;
419*4ba319b5SDimitry Andric}
420*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
421*4ba319b5SDimitry Andricconstexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
422*4ba319b5SDimitry Andric  return 0 > __v.__value_;
423*4ba319b5SDimitry Andric}
424*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
425*4ba319b5SDimitry Andricconstexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
426*4ba319b5SDimitry Andric  return 0 >= __v.__value_;
427*4ba319b5SDimitry Andric}
428*4ba319b5SDimitry Andric
429*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
430*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
431*4ba319b5SDimitry Andricconstexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
432*4ba319b5SDimitry Andric  return __v;
433*4ba319b5SDimitry Andric}
434*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
435*4ba319b5SDimitry Andricconstexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
436*4ba319b5SDimitry Andric  return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
437*4ba319b5SDimitry Andric}
438*4ba319b5SDimitry Andric#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
439*4ba319b5SDimitry Andric
440*4ba319b5SDimitry Andricclass strong_ordering {
441*4ba319b5SDimitry Andric  using _ValueT = signed char;
442*4ba319b5SDimitry Andric
443*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
444*4ba319b5SDimitry Andric  explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
445*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
446*4ba319b5SDimitry Andric  explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
447*4ba319b5SDimitry Andric
448*4ba319b5SDimitry Andricpublic:
449*4ba319b5SDimitry Andric  static const strong_ordering less;
450*4ba319b5SDimitry Andric  static const strong_ordering equal;
451*4ba319b5SDimitry Andric  static const strong_ordering equivalent;
452*4ba319b5SDimitry Andric  static const strong_ordering greater;
453*4ba319b5SDimitry Andric
454*4ba319b5SDimitry Andric  // conversions
455*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
456*4ba319b5SDimitry Andric  constexpr operator weak_equality() const noexcept {
457*4ba319b5SDimitry Andric    return __value_ == 0 ? weak_equality::equivalent
458*4ba319b5SDimitry Andric                         : weak_equality::nonequivalent;
459*4ba319b5SDimitry Andric  }
460*4ba319b5SDimitry Andric
461*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
462*4ba319b5SDimitry Andric  constexpr operator strong_equality() const noexcept {
463*4ba319b5SDimitry Andric    return __value_ == 0 ? strong_equality::equal
464*4ba319b5SDimitry Andric                         : strong_equality::nonequal;
465*4ba319b5SDimitry Andric  }
466*4ba319b5SDimitry Andric
467*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
468*4ba319b5SDimitry Andric  constexpr operator partial_ordering() const noexcept {
469*4ba319b5SDimitry Andric    return __value_ == 0 ? partial_ordering::equivalent
470*4ba319b5SDimitry Andric        : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
471*4ba319b5SDimitry Andric  }
472*4ba319b5SDimitry Andric
473*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
474*4ba319b5SDimitry Andric  constexpr operator weak_ordering() const noexcept {
475*4ba319b5SDimitry Andric    return __value_ == 0 ? weak_ordering::equivalent
476*4ba319b5SDimitry Andric        : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
477*4ba319b5SDimitry Andric  }
478*4ba319b5SDimitry Andric
479*4ba319b5SDimitry Andric  // comparisons
480*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
481*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
482*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
483*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
484*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
485*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
486*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
487*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
488*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
489*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
490*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
491*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
492*4ba319b5SDimitry Andric
493*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
494*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
495*4ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
496*4ba319b5SDimitry Andric#endif
497*4ba319b5SDimitry Andric
498*4ba319b5SDimitry Andricprivate:
499*4ba319b5SDimitry Andric  _ValueT __value_;
500*4ba319b5SDimitry Andric};
501*4ba319b5SDimitry Andric
502*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
503*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::__equal);
504*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv);
505*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
506*4ba319b5SDimitry Andric
507*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
508*4ba319b5SDimitry Andricconstexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
509*4ba319b5SDimitry Andric  return __v.__value_ == 0;
510*4ba319b5SDimitry Andric}
511*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
512*4ba319b5SDimitry Andricconstexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
513*4ba319b5SDimitry Andric  return __v.__value_ != 0;
514*4ba319b5SDimitry Andric}
515*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
516*4ba319b5SDimitry Andricconstexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
517*4ba319b5SDimitry Andric  return __v.__value_ < 0;
518*4ba319b5SDimitry Andric}
519*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
520*4ba319b5SDimitry Andricconstexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
521*4ba319b5SDimitry Andric  return __v.__value_ <= 0;
522*4ba319b5SDimitry Andric}
523*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
524*4ba319b5SDimitry Andricconstexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
525*4ba319b5SDimitry Andric  return __v.__value_ > 0;
526*4ba319b5SDimitry Andric}
527*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
528*4ba319b5SDimitry Andricconstexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
529*4ba319b5SDimitry Andric  return __v.__value_ >= 0;
530*4ba319b5SDimitry Andric}
531*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
532*4ba319b5SDimitry Andricconstexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
533*4ba319b5SDimitry Andric  return 0 == __v.__value_;
534*4ba319b5SDimitry Andric}
535*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
536*4ba319b5SDimitry Andricconstexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
537*4ba319b5SDimitry Andric  return 0 != __v.__value_;
538*4ba319b5SDimitry Andric}
539*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
540*4ba319b5SDimitry Andricconstexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
541*4ba319b5SDimitry Andric  return 0 < __v.__value_;
542*4ba319b5SDimitry Andric}
543*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
544*4ba319b5SDimitry Andricconstexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
545*4ba319b5SDimitry Andric  return 0 <= __v.__value_;
546*4ba319b5SDimitry Andric}
547*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
548*4ba319b5SDimitry Andricconstexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
549*4ba319b5SDimitry Andric  return 0 > __v.__value_;
550*4ba319b5SDimitry Andric}
551*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
552*4ba319b5SDimitry Andricconstexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
553*4ba319b5SDimitry Andric  return 0 >= __v.__value_;
554*4ba319b5SDimitry Andric}
555*4ba319b5SDimitry Andric
556*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
557*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
558*4ba319b5SDimitry Andricconstexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
559*4ba319b5SDimitry Andric  return __v;
560*4ba319b5SDimitry Andric}
561*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
562*4ba319b5SDimitry Andricconstexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
563*4ba319b5SDimitry Andric  return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
564*4ba319b5SDimitry Andric}
565*4ba319b5SDimitry Andric#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
566*4ba319b5SDimitry Andric
567*4ba319b5SDimitry Andric// named comparison functions
568*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
569*4ba319b5SDimitry Andricconstexpr bool is_eq(weak_equality __cmp) noexcept    { return __cmp == 0; }
570*4ba319b5SDimitry Andric
571*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
572*4ba319b5SDimitry Andricconstexpr bool is_neq(weak_equality __cmp) noexcept    { return __cmp != 0; }
573*4ba319b5SDimitry Andric
574*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
575*4ba319b5SDimitry Andricconstexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; }
576*4ba319b5SDimitry Andric
577*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
578*4ba319b5SDimitry Andricconstexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; }
579*4ba319b5SDimitry Andric
580*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
581*4ba319b5SDimitry Andricconstexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; }
582*4ba319b5SDimitry Andric
583*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
584*4ba319b5SDimitry Andricconstexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; }
585*4ba319b5SDimitry Andric
586*4ba319b5SDimitry Andricnamespace __comp_detail {
587*4ba319b5SDimitry Andric
588*4ba319b5SDimitry Andricenum _ClassifyCompCategory : unsigned{
589*4ba319b5SDimitry Andric  _None,
590*4ba319b5SDimitry Andric  _WeakEq,
591*4ba319b5SDimitry Andric  _StrongEq,
592*4ba319b5SDimitry Andric  _PartialOrd,
593*4ba319b5SDimitry Andric  _WeakOrd,
594*4ba319b5SDimitry Andric  _StrongOrd,
595*4ba319b5SDimitry Andric  _CCC_Size
596*4ba319b5SDimitry Andric};
597*4ba319b5SDimitry Andric
598*4ba319b5SDimitry Andrictemplate <class _Tp>
599*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
600*4ba319b5SDimitry Andricconstexpr _ClassifyCompCategory __type_to_enum() noexcept {
601*4ba319b5SDimitry Andric  if (is_same_v<_Tp, weak_equality>)
602*4ba319b5SDimitry Andric    return _WeakEq;
603*4ba319b5SDimitry Andric  if (is_same_v<_Tp, strong_equality>)
604*4ba319b5SDimitry Andric    return _StrongEq;
605*4ba319b5SDimitry Andric  if (is_same_v<_Tp, partial_ordering>)
606*4ba319b5SDimitry Andric    return _PartialOrd;
607*4ba319b5SDimitry Andric  if (is_same_v<_Tp, weak_ordering>)
608*4ba319b5SDimitry Andric    return _WeakOrd;
609*4ba319b5SDimitry Andric  if (is_same_v<_Tp, strong_ordering>)
610*4ba319b5SDimitry Andric    return _StrongOrd;
611*4ba319b5SDimitry Andric  return _None;
612*4ba319b5SDimitry Andric}
613*4ba319b5SDimitry Andric
614*4ba319b5SDimitry Andrictemplate <size_t _Size>
615*4ba319b5SDimitry Andricconstexpr _ClassifyCompCategory
616*4ba319b5SDimitry Andric__compute_comp_type(std::array<_ClassifyCompCategory, _Size> __types) {
617*4ba319b5SDimitry Andric  std::array<int, _CCC_Size> __seen = {};
618*4ba319b5SDimitry Andric  for (auto __type : __types)
619*4ba319b5SDimitry Andric    ++__seen[__type];
620*4ba319b5SDimitry Andric  if (__seen[_None])
621*4ba319b5SDimitry Andric    return _None;
622*4ba319b5SDimitry Andric  if (__seen[_WeakEq])
623*4ba319b5SDimitry Andric    return _WeakEq;
624*4ba319b5SDimitry Andric  if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd]))
625*4ba319b5SDimitry Andric    return _WeakEq;
626*4ba319b5SDimitry Andric  if (__seen[_StrongEq])
627*4ba319b5SDimitry Andric    return _StrongEq;
628*4ba319b5SDimitry Andric  if (__seen[_PartialOrd])
629*4ba319b5SDimitry Andric    return _PartialOrd;
630*4ba319b5SDimitry Andric  if (__seen[_WeakOrd])
631*4ba319b5SDimitry Andric    return _WeakOrd;
632*4ba319b5SDimitry Andric  return _StrongOrd;
633*4ba319b5SDimitry Andric}
634*4ba319b5SDimitry Andric
635*4ba319b5SDimitry Andrictemplate <class ..._Ts>
636*4ba319b5SDimitry Andricconstexpr auto __get_comp_type() {
637*4ba319b5SDimitry Andric  using _CCC = _ClassifyCompCategory;
638*4ba319b5SDimitry Andric  constexpr array<_CCC, sizeof...(_Ts)> __type_kinds{{__comp_detail::__type_to_enum<_Ts>()...}};
639*4ba319b5SDimitry Andric  constexpr _CCC _Cat = sizeof...(_Ts) == 0 ? _StrongOrd
640*4ba319b5SDimitry Andric      : __compute_comp_type(__type_kinds);
641*4ba319b5SDimitry Andric  if constexpr (_Cat == _None)
642*4ba319b5SDimitry Andric    return void();
643*4ba319b5SDimitry Andric  else if constexpr (_Cat == _WeakEq)
644*4ba319b5SDimitry Andric    return weak_equality::equivalent;
645*4ba319b5SDimitry Andric  else if constexpr (_Cat == _StrongEq)
646*4ba319b5SDimitry Andric    return strong_equality::equivalent;
647*4ba319b5SDimitry Andric  else if constexpr (_Cat == _PartialOrd)
648*4ba319b5SDimitry Andric    return partial_ordering::equivalent;
649*4ba319b5SDimitry Andric  else if constexpr (_Cat == _WeakOrd)
650*4ba319b5SDimitry Andric    return weak_ordering::equivalent;
651*4ba319b5SDimitry Andric  else if constexpr (_Cat == _StrongOrd)
652*4ba319b5SDimitry Andric    return strong_ordering::equivalent;
653*4ba319b5SDimitry Andric  else
654*4ba319b5SDimitry Andric    static_assert(_Cat != _Cat, "unhandled case");
655*4ba319b5SDimitry Andric}
656*4ba319b5SDimitry Andric} // namespace __comp_detail
657*4ba319b5SDimitry Andric
658*4ba319b5SDimitry Andric// [cmp.common], common comparison category type
659*4ba319b5SDimitry Andrictemplate<class... _Ts>
660*4ba319b5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS common_comparison_category {
661*4ba319b5SDimitry Andric  using type = decltype(__comp_detail::__get_comp_type<_Ts...>());
662*4ba319b5SDimitry Andric};
663*4ba319b5SDimitry Andric
664*4ba319b5SDimitry Andrictemplate<class... _Ts>
665*4ba319b5SDimitry Andricusing common_comparison_category_t = typename common_comparison_category<_Ts...>::type;
666*4ba319b5SDimitry Andric
667*4ba319b5SDimitry Andric// [cmp.alg], comparison algorithms
668*4ba319b5SDimitry Andric// TODO: unimplemented
669*4ba319b5SDimitry Andrictemplate<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs);
670*4ba319b5SDimitry Andrictemplate<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs);
671*4ba319b5SDimitry Andrictemplate<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs);
672*4ba319b5SDimitry Andrictemplate<class _Tp> constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs);
673*4ba319b5SDimitry Andrictemplate<class _Tp> constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs);
674*4ba319b5SDimitry Andric
675*4ba319b5SDimitry Andric#endif // _LIBCPP_STD_VER > 17
676*4ba319b5SDimitry Andric
677*4ba319b5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
678*4ba319b5SDimitry Andric
679*4ba319b5SDimitry Andric#endif // _LIBCPP_COMPARE
680