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