xref: /netbsd-src/external/apache2/llvm/dist/libcxx/include/compare (revision 4d6fc14bc9b0c5bf3e30be318c143ee82cadd108)
1*4d6fc14bSjoerg// -*- C++ -*-
2*4d6fc14bSjoerg//===-------------------------- compare -----------------------------------===//
3*4d6fc14bSjoerg//
4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information.
6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*4d6fc14bSjoerg//
8*4d6fc14bSjoerg//===----------------------------------------------------------------------===//
9*4d6fc14bSjoerg
10*4d6fc14bSjoerg#ifndef _LIBCPP_COMPARE
11*4d6fc14bSjoerg#define _LIBCPP_COMPARE
12*4d6fc14bSjoerg
13*4d6fc14bSjoerg/*
14*4d6fc14bSjoerg    compare synopsis
15*4d6fc14bSjoerg
16*4d6fc14bSjoergnamespace std {
17*4d6fc14bSjoerg  // [cmp.categories], comparison category types
18*4d6fc14bSjoerg  class partial_ordering;
19*4d6fc14bSjoerg  class weak_ordering;
20*4d6fc14bSjoerg  class strong_ordering;
21*4d6fc14bSjoerg
22*4d6fc14bSjoerg  // named comparison functions
23*4d6fc14bSjoerg  constexpr bool is_eq  (partial_ordering cmp) noexcept    { return cmp == 0; }
24*4d6fc14bSjoerg  constexpr bool is_neq (partial_ordering cmp) noexcept    { return cmp != 0; }
25*4d6fc14bSjoerg  constexpr bool is_lt  (partial_ordering cmp) noexcept { return cmp < 0; }
26*4d6fc14bSjoerg  constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; }
27*4d6fc14bSjoerg  constexpr bool is_gt  (partial_ordering cmp) noexcept { return cmp > 0; }
28*4d6fc14bSjoerg  constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; }
29*4d6fc14bSjoerg
30*4d6fc14bSjoerg  // [cmp.common], common comparison category type
31*4d6fc14bSjoerg  template<class... Ts>
32*4d6fc14bSjoerg  struct common_comparison_category {
33*4d6fc14bSjoerg    using type = see below;
34*4d6fc14bSjoerg  };
35*4d6fc14bSjoerg  template<class... Ts>
36*4d6fc14bSjoerg    using common_comparison_category_t = typename common_comparison_category<Ts...>::type;
37*4d6fc14bSjoerg
38*4d6fc14bSjoerg  // [cmp.alg], comparison algorithms
39*4d6fc14bSjoerg  template<class T> constexpr strong_ordering strong_order(const T& a, const T& b);
40*4d6fc14bSjoerg  template<class T> constexpr weak_ordering weak_order(const T& a, const T& b);
41*4d6fc14bSjoerg  template<class T> constexpr partial_ordering partial_order(const T& a, const T& b);
42*4d6fc14bSjoerg
43*4d6fc14bSjoerg  // [cmp.partialord], Class partial_ordering
44*4d6fc14bSjoerg  class partial_ordering {
45*4d6fc14bSjoerg  public:
46*4d6fc14bSjoerg    // valid values
47*4d6fc14bSjoerg    static const partial_ordering less;
48*4d6fc14bSjoerg    static const partial_ordering equivalent;
49*4d6fc14bSjoerg    static const partial_ordering greater;
50*4d6fc14bSjoerg    static const partial_ordering unordered;
51*4d6fc14bSjoerg
52*4d6fc14bSjoerg    // comparisons
53*4d6fc14bSjoerg    friend constexpr bool operator==(partial_ordering v, unspecified) noexcept;
54*4d6fc14bSjoerg    friend constexpr bool operator==(partial_ordering v, partial_ordering w) noexcept = default;
55*4d6fc14bSjoerg    friend constexpr bool operator< (partial_ordering v, unspecified) noexcept;
56*4d6fc14bSjoerg    friend constexpr bool operator> (partial_ordering v, unspecified) noexcept;
57*4d6fc14bSjoerg    friend constexpr bool operator<=(partial_ordering v, unspecified) noexcept;
58*4d6fc14bSjoerg    friend constexpr bool operator>=(partial_ordering v, unspecified) noexcept;
59*4d6fc14bSjoerg    friend constexpr bool operator< (unspecified, partial_ordering v) noexcept;
60*4d6fc14bSjoerg    friend constexpr bool operator> (unspecified, partial_ordering v) noexcept;
61*4d6fc14bSjoerg    friend constexpr bool operator<=(unspecified, partial_ordering v) noexcept;
62*4d6fc14bSjoerg    friend constexpr bool operator>=(unspecified, partial_ordering v) noexcept;
63*4d6fc14bSjoerg    friend constexpr partial_ordering operator<=>(partial_ordering v, unspecified) noexcept;
64*4d6fc14bSjoerg    friend constexpr partial_ordering operator<=>(unspecified, partial_ordering v) noexcept;
65*4d6fc14bSjoerg  };
66*4d6fc14bSjoerg
67*4d6fc14bSjoerg  // [cmp.weakord], Class weak_ordering
68*4d6fc14bSjoerg  class weak_ordering {
69*4d6fc14bSjoerg  public:
70*4d6fc14bSjoerg    // valid values
71*4d6fc14bSjoerg    static const weak_ordering less;
72*4d6fc14bSjoerg    static const weak_ordering equivalent;
73*4d6fc14bSjoerg    static const weak_ordering greater;
74*4d6fc14bSjoerg
75*4d6fc14bSjoerg    // conversions
76*4d6fc14bSjoerg    constexpr operator partial_ordering() const noexcept;
77*4d6fc14bSjoerg
78*4d6fc14bSjoerg    // comparisons
79*4d6fc14bSjoerg    friend constexpr bool operator==(weak_ordering v, unspecified) noexcept;
80*4d6fc14bSjoerg    friend constexpr bool operator==(weak_ordering v, weak_ordering w) noexcept = default;
81*4d6fc14bSjoerg    friend constexpr bool operator< (weak_ordering v, unspecified) noexcept;
82*4d6fc14bSjoerg    friend constexpr bool operator> (weak_ordering v, unspecified) noexcept;
83*4d6fc14bSjoerg    friend constexpr bool operator<=(weak_ordering v, unspecified) noexcept;
84*4d6fc14bSjoerg    friend constexpr bool operator>=(weak_ordering v, unspecified) noexcept;
85*4d6fc14bSjoerg    friend constexpr bool operator< (unspecified, weak_ordering v) noexcept;
86*4d6fc14bSjoerg    friend constexpr bool operator> (unspecified, weak_ordering v) noexcept;
87*4d6fc14bSjoerg    friend constexpr bool operator<=(unspecified, weak_ordering v) noexcept;
88*4d6fc14bSjoerg    friend constexpr bool operator>=(unspecified, weak_ordering v) noexcept;
89*4d6fc14bSjoerg    friend constexpr weak_ordering operator<=>(weak_ordering v, unspecified) noexcept;
90*4d6fc14bSjoerg    friend constexpr weak_ordering operator<=>(unspecified, weak_ordering v) noexcept;
91*4d6fc14bSjoerg  };
92*4d6fc14bSjoerg
93*4d6fc14bSjoerg  // [cmp.strongord], Class strong_ordering
94*4d6fc14bSjoerg  class strong_ordering {
95*4d6fc14bSjoerg  public:
96*4d6fc14bSjoerg    // valid values
97*4d6fc14bSjoerg    static const strong_ordering less;
98*4d6fc14bSjoerg    static const strong_ordering equal;
99*4d6fc14bSjoerg    static const strong_ordering equivalent;
100*4d6fc14bSjoerg    static const strong_ordering greater;
101*4d6fc14bSjoerg
102*4d6fc14bSjoerg    // conversions
103*4d6fc14bSjoerg    constexpr operator partial_ordering() const noexcept;
104*4d6fc14bSjoerg    constexpr operator weak_ordering() const noexcept;
105*4d6fc14bSjoerg
106*4d6fc14bSjoerg    // comparisons
107*4d6fc14bSjoerg    friend constexpr bool operator==(strong_ordering v, unspecified) noexcept;
108*4d6fc14bSjoerg    friend constexpr bool operator==(strong_ordering v, strong_ordering w) noexcept = default;
109*4d6fc14bSjoerg    friend constexpr bool operator< (strong_ordering v, unspecified) noexcept;
110*4d6fc14bSjoerg    friend constexpr bool operator> (strong_ordering v, unspecified) noexcept;
111*4d6fc14bSjoerg    friend constexpr bool operator<=(strong_ordering v, unspecified) noexcept;
112*4d6fc14bSjoerg    friend constexpr bool operator>=(strong_ordering v, unspecified) noexcept;
113*4d6fc14bSjoerg    friend constexpr bool operator< (unspecified, strong_ordering v) noexcept;
114*4d6fc14bSjoerg    friend constexpr bool operator> (unspecified, strong_ordering v) noexcept;
115*4d6fc14bSjoerg    friend constexpr bool operator<=(unspecified, strong_ordering v) noexcept;
116*4d6fc14bSjoerg    friend constexpr bool operator>=(unspecified, strong_ordering v) noexcept;
117*4d6fc14bSjoerg    friend constexpr strong_ordering operator<=>(strong_ordering v, unspecified) noexcept;
118*4d6fc14bSjoerg    friend constexpr strong_ordering operator<=>(unspecified, strong_ordering v) noexcept;
119*4d6fc14bSjoerg  };
120*4d6fc14bSjoerg}
121*4d6fc14bSjoerg*/
122*4d6fc14bSjoerg
123*4d6fc14bSjoerg#include <__config>
124*4d6fc14bSjoerg#include <type_traits>
125*4d6fc14bSjoerg
126*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
127*4d6fc14bSjoerg#pragma GCC system_header
128*4d6fc14bSjoerg#endif
129*4d6fc14bSjoerg
130*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_STD
131*4d6fc14bSjoerg
132*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR)
133*4d6fc14bSjoerg// exposition only
134*4d6fc14bSjoergenum class _LIBCPP_ENUM_VIS _EqResult : unsigned char {
135*4d6fc14bSjoerg  __zero = 0,
136*4d6fc14bSjoerg  __equal = __zero,
137*4d6fc14bSjoerg  __equiv = __equal,
138*4d6fc14bSjoerg  __nonequal = 1,
139*4d6fc14bSjoerg  __nonequiv = __nonequal
140*4d6fc14bSjoerg};
141*4d6fc14bSjoerg
142*4d6fc14bSjoergenum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
143*4d6fc14bSjoerg  __less = -1,
144*4d6fc14bSjoerg  __greater = 1
145*4d6fc14bSjoerg};
146*4d6fc14bSjoerg
147*4d6fc14bSjoergenum class _LIBCPP_ENUM_VIS _NCmpResult : signed char {
148*4d6fc14bSjoerg  __unordered = -127
149*4d6fc14bSjoerg};
150*4d6fc14bSjoerg
151*4d6fc14bSjoergclass partial_ordering;
152*4d6fc14bSjoergclass weak_ordering;
153*4d6fc14bSjoergclass strong_ordering;
154*4d6fc14bSjoerg
155*4d6fc14bSjoergtemplate<class _Tp, class... _Args>
156*4d6fc14bSjoerginline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...);
157*4d6fc14bSjoerg
158*4d6fc14bSjoergstruct _CmpUnspecifiedParam {
159*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEVAL
160*4d6fc14bSjoerg  _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
161*4d6fc14bSjoerg
162*4d6fc14bSjoerg  template<class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>>
163*4d6fc14bSjoerg  _CmpUnspecifiedParam(_Tp) = delete;
164*4d6fc14bSjoerg};
165*4d6fc14bSjoerg
166*4d6fc14bSjoergclass partial_ordering {
167*4d6fc14bSjoerg  using _ValueT = signed char;
168*4d6fc14bSjoerg
169*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
170*4d6fc14bSjoerg  explicit constexpr partial_ordering(_EqResult __v) noexcept
171*4d6fc14bSjoerg      : __value_(_ValueT(__v)) {}
172*4d6fc14bSjoerg
173*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
174*4d6fc14bSjoerg  explicit constexpr partial_ordering(_OrdResult __v) noexcept
175*4d6fc14bSjoerg      : __value_(_ValueT(__v)) {}
176*4d6fc14bSjoerg
177*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
178*4d6fc14bSjoerg  explicit constexpr partial_ordering(_NCmpResult __v) noexcept
179*4d6fc14bSjoerg      : __value_(_ValueT(__v)) {}
180*4d6fc14bSjoerg
181*4d6fc14bSjoerg  constexpr bool __is_ordered() const noexcept {
182*4d6fc14bSjoerg    return __value_ != _ValueT(_NCmpResult::__unordered);
183*4d6fc14bSjoerg  }
184*4d6fc14bSjoergpublic:
185*4d6fc14bSjoerg  // valid values
186*4d6fc14bSjoerg  static const partial_ordering less;
187*4d6fc14bSjoerg  static const partial_ordering equivalent;
188*4d6fc14bSjoerg  static const partial_ordering greater;
189*4d6fc14bSjoerg  static const partial_ordering unordered;
190*4d6fc14bSjoerg
191*4d6fc14bSjoerg  // comparisons
192*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
193*4d6fc14bSjoerg
194*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
195*4d6fc14bSjoerg    return __v.__is_ordered() && __v.__value_ == 0;
196*4d6fc14bSjoerg  }
197*4d6fc14bSjoerg
198*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
199*4d6fc14bSjoerg    return __v.__is_ordered() && __v.__value_ < 0;
200*4d6fc14bSjoerg  }
201*4d6fc14bSjoerg
202*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept  {
203*4d6fc14bSjoerg    return __v.__is_ordered() && __v.__value_ <= 0;
204*4d6fc14bSjoerg  }
205*4d6fc14bSjoerg
206*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept  {
207*4d6fc14bSjoerg    return __v.__is_ordered() && __v.__value_ > 0;
208*4d6fc14bSjoerg  }
209*4d6fc14bSjoerg
210*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept  {
211*4d6fc14bSjoerg    return __v.__is_ordered() && __v.__value_ >= 0;
212*4d6fc14bSjoerg  }
213*4d6fc14bSjoerg
214*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
215*4d6fc14bSjoerg    return __v.__is_ordered() && 0 < __v.__value_;
216*4d6fc14bSjoerg  }
217*4d6fc14bSjoerg
218*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
219*4d6fc14bSjoerg    return __v.__is_ordered() && 0 <= __v.__value_;
220*4d6fc14bSjoerg  }
221*4d6fc14bSjoerg
222*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
223*4d6fc14bSjoerg    return __v.__is_ordered() && 0 > __v.__value_;
224*4d6fc14bSjoerg  }
225*4d6fc14bSjoerg
226*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
227*4d6fc14bSjoerg    return __v.__is_ordered() && 0 >= __v.__value_;
228*4d6fc14bSjoerg  }
229*4d6fc14bSjoerg
230*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept  {
231*4d6fc14bSjoerg    return __v;
232*4d6fc14bSjoerg  }
233*4d6fc14bSjoerg
234*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
235*4d6fc14bSjoerg    return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
236*4d6fc14bSjoerg  }
237*4d6fc14bSjoergprivate:
238*4d6fc14bSjoerg  _ValueT __value_;
239*4d6fc14bSjoerg};
240*4d6fc14bSjoerg
241*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
242*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv);
243*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
244*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
245*4d6fc14bSjoerg
246*4d6fc14bSjoergclass weak_ordering {
247*4d6fc14bSjoerg  using _ValueT = signed char;
248*4d6fc14bSjoerg
249*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
250*4d6fc14bSjoerg  explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
251*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
252*4d6fc14bSjoerg  explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
253*4d6fc14bSjoerg
254*4d6fc14bSjoergpublic:
255*4d6fc14bSjoerg  static const weak_ordering less;
256*4d6fc14bSjoerg  static const weak_ordering equivalent;
257*4d6fc14bSjoerg  static const weak_ordering greater;
258*4d6fc14bSjoerg
259*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
260*4d6fc14bSjoerg  constexpr operator partial_ordering() const noexcept {
261*4d6fc14bSjoerg    return __value_ == 0 ? partial_ordering::equivalent
262*4d6fc14bSjoerg        : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
263*4d6fc14bSjoerg  }
264*4d6fc14bSjoerg
265*4d6fc14bSjoerg  // comparisons
266*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
267*4d6fc14bSjoerg
268*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
269*4d6fc14bSjoerg    return __v.__value_ == 0;
270*4d6fc14bSjoerg  }
271*4d6fc14bSjoerg
272*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
273*4d6fc14bSjoerg    return __v.__value_ < 0;
274*4d6fc14bSjoerg  }
275*4d6fc14bSjoerg
276*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
277*4d6fc14bSjoerg    return __v.__value_ <= 0;
278*4d6fc14bSjoerg  }
279*4d6fc14bSjoerg
280*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
281*4d6fc14bSjoerg    return __v.__value_ > 0;
282*4d6fc14bSjoerg  }
283*4d6fc14bSjoerg
284*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
285*4d6fc14bSjoerg    return __v.__value_ >= 0;
286*4d6fc14bSjoerg  }
287*4d6fc14bSjoerg
288*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
289*4d6fc14bSjoerg    return 0 < __v.__value_;
290*4d6fc14bSjoerg  }
291*4d6fc14bSjoerg
292*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
293*4d6fc14bSjoerg    return 0 <= __v.__value_;
294*4d6fc14bSjoerg  }
295*4d6fc14bSjoerg
296*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
297*4d6fc14bSjoerg    return 0 > __v.__value_;
298*4d6fc14bSjoerg  }
299*4d6fc14bSjoerg
300*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
301*4d6fc14bSjoerg    return 0 >= __v.__value_;
302*4d6fc14bSjoerg  }
303*4d6fc14bSjoerg
304*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
305*4d6fc14bSjoerg    return __v;
306*4d6fc14bSjoerg  }
307*4d6fc14bSjoerg
308*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
309*4d6fc14bSjoerg    return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
310*4d6fc14bSjoerg  }
311*4d6fc14bSjoerg
312*4d6fc14bSjoergprivate:
313*4d6fc14bSjoerg  _ValueT __value_;
314*4d6fc14bSjoerg};
315*4d6fc14bSjoerg
316*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
317*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv);
318*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
319*4d6fc14bSjoergclass strong_ordering {
320*4d6fc14bSjoerg  using _ValueT = signed char;
321*4d6fc14bSjoerg
322*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
323*4d6fc14bSjoerg  explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
324*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
325*4d6fc14bSjoerg  explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
326*4d6fc14bSjoerg
327*4d6fc14bSjoergpublic:
328*4d6fc14bSjoerg  static const strong_ordering less;
329*4d6fc14bSjoerg  static const strong_ordering equal;
330*4d6fc14bSjoerg  static const strong_ordering equivalent;
331*4d6fc14bSjoerg  static const strong_ordering greater;
332*4d6fc14bSjoerg
333*4d6fc14bSjoerg  // conversions
334*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
335*4d6fc14bSjoerg  constexpr operator partial_ordering() const noexcept {
336*4d6fc14bSjoerg    return __value_ == 0 ? partial_ordering::equivalent
337*4d6fc14bSjoerg        : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
338*4d6fc14bSjoerg  }
339*4d6fc14bSjoerg
340*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
341*4d6fc14bSjoerg  constexpr operator weak_ordering() const noexcept {
342*4d6fc14bSjoerg    return __value_ == 0 ? weak_ordering::equivalent
343*4d6fc14bSjoerg        : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
344*4d6fc14bSjoerg  }
345*4d6fc14bSjoerg
346*4d6fc14bSjoerg  // comparisons
347*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
348*4d6fc14bSjoerg
349*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
350*4d6fc14bSjoerg    return __v.__value_ == 0;
351*4d6fc14bSjoerg  }
352*4d6fc14bSjoerg
353*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
354*4d6fc14bSjoerg    return __v.__value_ < 0;
355*4d6fc14bSjoerg  }
356*4d6fc14bSjoerg
357*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
358*4d6fc14bSjoerg    return __v.__value_ <= 0;
359*4d6fc14bSjoerg  }
360*4d6fc14bSjoerg
361*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
362*4d6fc14bSjoerg    return __v.__value_ > 0;
363*4d6fc14bSjoerg  }
364*4d6fc14bSjoerg
365*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
366*4d6fc14bSjoerg    return __v.__value_ >= 0;
367*4d6fc14bSjoerg  }
368*4d6fc14bSjoerg
369*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
370*4d6fc14bSjoerg    return 0 < __v.__value_;
371*4d6fc14bSjoerg  }
372*4d6fc14bSjoerg
373*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
374*4d6fc14bSjoerg    return 0 <= __v.__value_;
375*4d6fc14bSjoerg  }
376*4d6fc14bSjoerg
377*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
378*4d6fc14bSjoerg    return 0 > __v.__value_;
379*4d6fc14bSjoerg  }
380*4d6fc14bSjoerg
381*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
382*4d6fc14bSjoerg    return 0 >= __v.__value_;
383*4d6fc14bSjoerg  }
384*4d6fc14bSjoerg
385*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
386*4d6fc14bSjoerg    return __v;
387*4d6fc14bSjoerg  }
388*4d6fc14bSjoerg
389*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
390*4d6fc14bSjoerg    return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
391*4d6fc14bSjoerg  }
392*4d6fc14bSjoerg
393*4d6fc14bSjoergprivate:
394*4d6fc14bSjoerg  _ValueT __value_;
395*4d6fc14bSjoerg};
396*4d6fc14bSjoerg
397*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
398*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::__equal);
399*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv);
400*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
401*4d6fc14bSjoerg
402*4d6fc14bSjoerg// named comparison functions
403*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
404*4d6fc14bSjoergconstexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; }
405*4d6fc14bSjoerg
406*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
407*4d6fc14bSjoergconstexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; }
408*4d6fc14bSjoerg
409*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
410*4d6fc14bSjoergconstexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; }
411*4d6fc14bSjoerg
412*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
413*4d6fc14bSjoergconstexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; }
414*4d6fc14bSjoerg
415*4d6fc14bSjoergnamespace __comp_detail {
416*4d6fc14bSjoerg
417*4d6fc14bSjoergenum _ClassifyCompCategory : unsigned{
418*4d6fc14bSjoerg  _None,
419*4d6fc14bSjoerg  _PartialOrd,
420*4d6fc14bSjoerg  _WeakOrd,
421*4d6fc14bSjoerg  _StrongOrd,
422*4d6fc14bSjoerg  _CCC_Size
423*4d6fc14bSjoerg};
424*4d6fc14bSjoerg
425*4d6fc14bSjoergtemplate <class _Tp>
426*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
427*4d6fc14bSjoergconstexpr _ClassifyCompCategory __type_to_enum() noexcept {
428*4d6fc14bSjoerg  if (is_same_v<_Tp, partial_ordering>)
429*4d6fc14bSjoerg    return _PartialOrd;
430*4d6fc14bSjoerg  if (is_same_v<_Tp, weak_ordering>)
431*4d6fc14bSjoerg    return _WeakOrd;
432*4d6fc14bSjoerg  if (is_same_v<_Tp, strong_ordering>)
433*4d6fc14bSjoerg    return _StrongOrd;
434*4d6fc14bSjoerg  return _None;
435*4d6fc14bSjoerg}
436*4d6fc14bSjoerg
437*4d6fc14bSjoergtemplate <size_t _Size>
438*4d6fc14bSjoergconstexpr _ClassifyCompCategory
439*4d6fc14bSjoerg__compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) {
440*4d6fc14bSjoerg  int __seen[_CCC_Size] = {};
441*4d6fc14bSjoerg  for (auto __type : __types)
442*4d6fc14bSjoerg    ++__seen[__type];
443*4d6fc14bSjoerg  if (__seen[_None])
444*4d6fc14bSjoerg    return _None;
445*4d6fc14bSjoerg  if (__seen[_PartialOrd])
446*4d6fc14bSjoerg    return _PartialOrd;
447*4d6fc14bSjoerg  if (__seen[_WeakOrd])
448*4d6fc14bSjoerg    return _WeakOrd;
449*4d6fc14bSjoerg  return _StrongOrd;
450*4d6fc14bSjoerg}
451*4d6fc14bSjoerg
452*4d6fc14bSjoergtemplate <class ..._Ts>
453*4d6fc14bSjoergconstexpr auto __get_comp_type() {
454*4d6fc14bSjoerg  using _CCC = _ClassifyCompCategory;
455*4d6fc14bSjoerg  constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...};
456*4d6fc14bSjoerg  constexpr _CCC _Cat = __compute_comp_type(__type_kinds);
457*4d6fc14bSjoerg  if constexpr (_Cat == _None)
458*4d6fc14bSjoerg    return void();
459*4d6fc14bSjoerg  else if constexpr (_Cat == _PartialOrd)
460*4d6fc14bSjoerg    return partial_ordering::equivalent;
461*4d6fc14bSjoerg  else if constexpr (_Cat == _WeakOrd)
462*4d6fc14bSjoerg    return weak_ordering::equivalent;
463*4d6fc14bSjoerg  else if constexpr (_Cat == _StrongOrd)
464*4d6fc14bSjoerg    return strong_ordering::equivalent;
465*4d6fc14bSjoerg  else
466*4d6fc14bSjoerg    static_assert(_Cat != _Cat, "unhandled case");
467*4d6fc14bSjoerg}
468*4d6fc14bSjoerg} // namespace __comp_detail
469*4d6fc14bSjoerg
470*4d6fc14bSjoerg// [cmp.common], common comparison category type
471*4d6fc14bSjoergtemplate<class... _Ts>
472*4d6fc14bSjoergstruct _LIBCPP_TEMPLATE_VIS common_comparison_category {
473*4d6fc14bSjoerg  using type = decltype(__comp_detail::__get_comp_type<_Ts...>());
474*4d6fc14bSjoerg};
475*4d6fc14bSjoerg
476*4d6fc14bSjoergtemplate<class... _Ts>
477*4d6fc14bSjoergusing common_comparison_category_t = typename common_comparison_category<_Ts...>::type;
478*4d6fc14bSjoerg
479*4d6fc14bSjoerg// [cmp.alg], comparison algorithms
480*4d6fc14bSjoerg// TODO: unimplemented
481*4d6fc14bSjoergtemplate<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs);
482*4d6fc14bSjoergtemplate<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs);
483*4d6fc14bSjoergtemplate<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs);
484*4d6fc14bSjoerg
485*4d6fc14bSjoerg#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR)
486*4d6fc14bSjoerg
487*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_STD
488*4d6fc14bSjoerg
489*4d6fc14bSjoerg#endif // _LIBCPP_COMPARE
490