161c35fb0SRuslan Arutyunyan //===----------------------------------------------------------------------===// 261c35fb0SRuslan Arutyunyan // 361c35fb0SRuslan Arutyunyan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 461c35fb0SRuslan Arutyunyan // See https://llvm.org/LICENSE.txt for license information. 561c35fb0SRuslan Arutyunyan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 661c35fb0SRuslan Arutyunyan // 761c35fb0SRuslan Arutyunyan //===----------------------------------------------------------------------===// 861c35fb0SRuslan Arutyunyan 961c35fb0SRuslan Arutyunyan #ifndef _LIBCPP___COMPARE_ORDERING_H 1061c35fb0SRuslan Arutyunyan #define _LIBCPP___COMPARE_ORDERING_H 1161c35fb0SRuslan Arutyunyan 1261c35fb0SRuslan Arutyunyan #include <__config> 13947dfc95SNikolas Klauser #include <__type_traits/enable_if.h> 14947dfc95SNikolas Klauser #include <__type_traits/is_same.h> 1561c35fb0SRuslan Arutyunyan 1661c35fb0SRuslan Arutyunyan #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1761c35fb0SRuslan Arutyunyan # pragma GCC system_header 1861c35fb0SRuslan Arutyunyan #endif 1961c35fb0SRuslan Arutyunyan 2061c35fb0SRuslan Arutyunyan _LIBCPP_BEGIN_NAMESPACE_STD 2161c35fb0SRuslan Arutyunyan 224f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 2361c35fb0SRuslan Arutyunyan 2461c35fb0SRuslan Arutyunyan // exposition only 259783f28cSLouis Dionne enum class _OrdResult : signed char { __less = -1, __equiv = 0, __greater = 1 }; 2661c35fb0SRuslan Arutyunyan 27b07730b9SNikolas Klauser enum class _PartialOrdResult : signed char { 28b07730b9SNikolas Klauser __less = static_cast<signed char>(_OrdResult::__less), 29b07730b9SNikolas Klauser __equiv = static_cast<signed char>(_OrdResult::__equiv), 30b07730b9SNikolas Klauser __greater = static_cast<signed char>(_OrdResult::__greater), 31b07730b9SNikolas Klauser __unordered = -127, 32b07730b9SNikolas Klauser }; 3361c35fb0SRuslan Arutyunyan 3461c35fb0SRuslan Arutyunyan class partial_ordering; 3561c35fb0SRuslan Arutyunyan class weak_ordering; 3661c35fb0SRuslan Arutyunyan class strong_ordering; 3761c35fb0SRuslan Arutyunyan 3861c35fb0SRuslan Arutyunyan struct _CmpUnspecifiedParam { 39aa088438SLouis Dionne // If anything other than a literal 0 is provided, the behavior is undefined by the Standard. 40aa088438SLouis Dionne // 41aa088438SLouis Dionne // The alternative to the `__enable_if__` attribute would be to use the fact that a pointer 42aa088438SLouis Dionne // can be constructed from literal 0, but this conflicts with `-Wzero-as-null-pointer-constant`. 43aa088438SLouis Dionne template <class _Tp, class = __enable_if_t<is_same_v<_Tp, int> > > 44aa088438SLouis Dionne _LIBCPP_HIDE_FROM_ABI consteval _CmpUnspecifiedParam(_Tp __zero) noexcept 45aa088438SLouis Dionne # if __has_attribute(__enable_if__) 46aa088438SLouis Dionne __attribute__((__enable_if__( 47aa088438SLouis Dionne __zero == 0, "Only literal 0 is allowed as the operand of a comparison with one of the ordering types"))) 48aa088438SLouis Dionne # endif 49aa088438SLouis Dionne { 50aa088438SLouis Dionne (void)__zero; 51aa088438SLouis Dionne } 5261c35fb0SRuslan Arutyunyan }; 5361c35fb0SRuslan Arutyunyan 5461c35fb0SRuslan Arutyunyan class partial_ordering { 55b07730b9SNikolas Klauser _LIBCPP_HIDE_FROM_ABI explicit constexpr partial_ordering(_PartialOrdResult __v) noexcept : __value_(__v) {} 569783f28cSLouis Dionne 5761c35fb0SRuslan Arutyunyan public: 5861c35fb0SRuslan Arutyunyan // valid values 5961c35fb0SRuslan Arutyunyan static const partial_ordering less; 6061c35fb0SRuslan Arutyunyan static const partial_ordering equivalent; 6161c35fb0SRuslan Arutyunyan static const partial_ordering greater; 6261c35fb0SRuslan Arutyunyan static const partial_ordering unordered; 6361c35fb0SRuslan Arutyunyan 6461c35fb0SRuslan Arutyunyan // comparisons 659783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; 6661c35fb0SRuslan Arutyunyan 679783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 68b07730b9SNikolas Klauser return __v.__value_ == _PartialOrdResult::__equiv; 6961c35fb0SRuslan Arutyunyan } 7061c35fb0SRuslan Arutyunyan 719783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 72b07730b9SNikolas Klauser return __v.__value_ == _PartialOrdResult::__less; 7361c35fb0SRuslan Arutyunyan } 7461c35fb0SRuslan Arutyunyan 759783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 76b07730b9SNikolas Klauser return __v.__value_ == _PartialOrdResult::__equiv || __v.__value_ == _PartialOrdResult::__less; 7761c35fb0SRuslan Arutyunyan } 7861c35fb0SRuslan Arutyunyan 799783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 80b07730b9SNikolas Klauser return __v.__value_ == _PartialOrdResult::__greater; 8161c35fb0SRuslan Arutyunyan } 8261c35fb0SRuslan Arutyunyan 839783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 84b07730b9SNikolas Klauser return __v.__value_ == _PartialOrdResult::__equiv || __v.__value_ == _PartialOrdResult::__greater; 8561c35fb0SRuslan Arutyunyan } 8661c35fb0SRuslan Arutyunyan 879783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 88b07730b9SNikolas Klauser return __v.__value_ == _PartialOrdResult::__greater; 8961c35fb0SRuslan Arutyunyan } 9061c35fb0SRuslan Arutyunyan 919783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 92b07730b9SNikolas Klauser return __v.__value_ == _PartialOrdResult::__equiv || __v.__value_ == _PartialOrdResult::__greater; 9361c35fb0SRuslan Arutyunyan } 9461c35fb0SRuslan Arutyunyan 959783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 96b07730b9SNikolas Klauser return __v.__value_ == _PartialOrdResult::__less; 9761c35fb0SRuslan Arutyunyan } 9861c35fb0SRuslan Arutyunyan 999783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 100b07730b9SNikolas Klauser return __v.__value_ == _PartialOrdResult::__equiv || __v.__value_ == _PartialOrdResult::__less; 10161c35fb0SRuslan Arutyunyan } 10261c35fb0SRuslan Arutyunyan 1039783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr partial_ordering 1049783f28cSLouis Dionne operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 10561c35fb0SRuslan Arutyunyan return __v; 10661c35fb0SRuslan Arutyunyan } 10761c35fb0SRuslan Arutyunyan 1089783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr partial_ordering 1099783f28cSLouis Dionne operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 11061c35fb0SRuslan Arutyunyan return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); 11161c35fb0SRuslan Arutyunyan } 1129783f28cSLouis Dionne 11361c35fb0SRuslan Arutyunyan private: 114b07730b9SNikolas Klauser _PartialOrdResult __value_; 11561c35fb0SRuslan Arutyunyan }; 11661c35fb0SRuslan Arutyunyan 117b07730b9SNikolas Klauser inline constexpr partial_ordering partial_ordering::less(_PartialOrdResult::__less); 118b07730b9SNikolas Klauser inline constexpr partial_ordering partial_ordering::equivalent(_PartialOrdResult::__equiv); 119b07730b9SNikolas Klauser inline constexpr partial_ordering partial_ordering::greater(_PartialOrdResult::__greater); 120b07730b9SNikolas Klauser inline constexpr partial_ordering partial_ordering::unordered(_PartialOrdResult::__unordered); 12161c35fb0SRuslan Arutyunyan 12261c35fb0SRuslan Arutyunyan class weak_ordering { 123*f6958523SNikolas Klauser using _ValueT _LIBCPP_NODEBUG = signed char; 12461c35fb0SRuslan Arutyunyan 1259783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 12661c35fb0SRuslan Arutyunyan 12761c35fb0SRuslan Arutyunyan public: 12861c35fb0SRuslan Arutyunyan static const weak_ordering less; 12961c35fb0SRuslan Arutyunyan static const weak_ordering equivalent; 13061c35fb0SRuslan Arutyunyan static const weak_ordering greater; 13161c35fb0SRuslan Arutyunyan 1329783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr operator partial_ordering() const noexcept { 13361c35fb0SRuslan Arutyunyan return __value_ == 0 ? partial_ordering::equivalent 13461c35fb0SRuslan Arutyunyan : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 13561c35fb0SRuslan Arutyunyan } 13661c35fb0SRuslan Arutyunyan 13761c35fb0SRuslan Arutyunyan // comparisons 1389783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; 13961c35fb0SRuslan Arutyunyan 1409783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 14161c35fb0SRuslan Arutyunyan return __v.__value_ == 0; 14261c35fb0SRuslan Arutyunyan } 14361c35fb0SRuslan Arutyunyan 1449783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 14561c35fb0SRuslan Arutyunyan return __v.__value_ < 0; 14661c35fb0SRuslan Arutyunyan } 14761c35fb0SRuslan Arutyunyan 1489783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 14961c35fb0SRuslan Arutyunyan return __v.__value_ <= 0; 15061c35fb0SRuslan Arutyunyan } 15161c35fb0SRuslan Arutyunyan 1529783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 15361c35fb0SRuslan Arutyunyan return __v.__value_ > 0; 15461c35fb0SRuslan Arutyunyan } 15561c35fb0SRuslan Arutyunyan 1569783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 15761c35fb0SRuslan Arutyunyan return __v.__value_ >= 0; 15861c35fb0SRuslan Arutyunyan } 15961c35fb0SRuslan Arutyunyan 1609783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 16161c35fb0SRuslan Arutyunyan return 0 < __v.__value_; 16261c35fb0SRuslan Arutyunyan } 16361c35fb0SRuslan Arutyunyan 1649783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 16561c35fb0SRuslan Arutyunyan return 0 <= __v.__value_; 16661c35fb0SRuslan Arutyunyan } 16761c35fb0SRuslan Arutyunyan 1689783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 16961c35fb0SRuslan Arutyunyan return 0 > __v.__value_; 17061c35fb0SRuslan Arutyunyan } 17161c35fb0SRuslan Arutyunyan 1729783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 17361c35fb0SRuslan Arutyunyan return 0 >= __v.__value_; 17461c35fb0SRuslan Arutyunyan } 17561c35fb0SRuslan Arutyunyan 1769783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 17761c35fb0SRuslan Arutyunyan return __v; 17861c35fb0SRuslan Arutyunyan } 17961c35fb0SRuslan Arutyunyan 1809783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 18161c35fb0SRuslan Arutyunyan return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); 18261c35fb0SRuslan Arutyunyan } 18361c35fb0SRuslan Arutyunyan 18461c35fb0SRuslan Arutyunyan private: 18561c35fb0SRuslan Arutyunyan _ValueT __value_; 18661c35fb0SRuslan Arutyunyan }; 18761c35fb0SRuslan Arutyunyan 18884d07f4dSLouis Dionne inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less); 189a7d084a1SArthur O'Dwyer inline constexpr weak_ordering weak_ordering::equivalent(_OrdResult::__equiv); 19084d07f4dSLouis Dionne inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); 19147481638SLouis Dionne 19261c35fb0SRuslan Arutyunyan class strong_ordering { 193*f6958523SNikolas Klauser using _ValueT _LIBCPP_NODEBUG = signed char; 19461c35fb0SRuslan Arutyunyan 1959783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 19661c35fb0SRuslan Arutyunyan 19761c35fb0SRuslan Arutyunyan public: 19861c35fb0SRuslan Arutyunyan static const strong_ordering less; 19961c35fb0SRuslan Arutyunyan static const strong_ordering equal; 20061c35fb0SRuslan Arutyunyan static const strong_ordering equivalent; 20161c35fb0SRuslan Arutyunyan static const strong_ordering greater; 20261c35fb0SRuslan Arutyunyan 20361c35fb0SRuslan Arutyunyan // conversions 2049783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr operator partial_ordering() const noexcept { 20561c35fb0SRuslan Arutyunyan return __value_ == 0 ? partial_ordering::equivalent 20661c35fb0SRuslan Arutyunyan : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 20761c35fb0SRuslan Arutyunyan } 20861c35fb0SRuslan Arutyunyan 2099783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr operator weak_ordering() const noexcept { 2109783f28cSLouis Dionne return __value_ == 0 ? weak_ordering::equivalent : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); 21161c35fb0SRuslan Arutyunyan } 21261c35fb0SRuslan Arutyunyan 21361c35fb0SRuslan Arutyunyan // comparisons 2149783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; 21561c35fb0SRuslan Arutyunyan 2169783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 21761c35fb0SRuslan Arutyunyan return __v.__value_ == 0; 21861c35fb0SRuslan Arutyunyan } 21961c35fb0SRuslan Arutyunyan 2209783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 22161c35fb0SRuslan Arutyunyan return __v.__value_ < 0; 22261c35fb0SRuslan Arutyunyan } 22361c35fb0SRuslan Arutyunyan 2249783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 22561c35fb0SRuslan Arutyunyan return __v.__value_ <= 0; 22661c35fb0SRuslan Arutyunyan } 22761c35fb0SRuslan Arutyunyan 2289783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 22961c35fb0SRuslan Arutyunyan return __v.__value_ > 0; 23061c35fb0SRuslan Arutyunyan } 23161c35fb0SRuslan Arutyunyan 2329783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 23361c35fb0SRuslan Arutyunyan return __v.__value_ >= 0; 23461c35fb0SRuslan Arutyunyan } 23561c35fb0SRuslan Arutyunyan 2369783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 23761c35fb0SRuslan Arutyunyan return 0 < __v.__value_; 23861c35fb0SRuslan Arutyunyan } 23961c35fb0SRuslan Arutyunyan 2409783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 24161c35fb0SRuslan Arutyunyan return 0 <= __v.__value_; 24261c35fb0SRuslan Arutyunyan } 24361c35fb0SRuslan Arutyunyan 2449783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 24561c35fb0SRuslan Arutyunyan return 0 > __v.__value_; 24661c35fb0SRuslan Arutyunyan } 24761c35fb0SRuslan Arutyunyan 2489783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 24961c35fb0SRuslan Arutyunyan return 0 >= __v.__value_; 25061c35fb0SRuslan Arutyunyan } 25161c35fb0SRuslan Arutyunyan 2529783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering 2539783f28cSLouis Dionne operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 25461c35fb0SRuslan Arutyunyan return __v; 25561c35fb0SRuslan Arutyunyan } 25661c35fb0SRuslan Arutyunyan 2579783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering 2589783f28cSLouis Dionne operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 25961c35fb0SRuslan Arutyunyan return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); 26061c35fb0SRuslan Arutyunyan } 26161c35fb0SRuslan Arutyunyan 26261c35fb0SRuslan Arutyunyan private: 26361c35fb0SRuslan Arutyunyan _ValueT __value_; 26461c35fb0SRuslan Arutyunyan }; 26561c35fb0SRuslan Arutyunyan 26684d07f4dSLouis Dionne inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less); 267a7d084a1SArthur O'Dwyer inline constexpr strong_ordering strong_ordering::equal(_OrdResult::__equiv); 268a7d084a1SArthur O'Dwyer inline constexpr strong_ordering strong_ordering::equivalent(_OrdResult::__equiv); 26984d07f4dSLouis Dionne inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); 27061c35fb0SRuslan Arutyunyan 2713818b4dfSMark de Wever /// [cmp.categories.pre]/1 2723818b4dfSMark de Wever /// The types partial_ordering, weak_ordering, and strong_ordering are 2733818b4dfSMark de Wever /// collectively termed the comparison category types. 2743818b4dfSMark de Wever template <class _Tp> 275aa088438SLouis Dionne concept __comparison_category = 276aa088438SLouis Dionne is_same_v<_Tp, partial_ordering> || is_same_v<_Tp, weak_ordering> || is_same_v<_Tp, strong_ordering>; 2773818b4dfSMark de Wever 2784f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 27961c35fb0SRuslan Arutyunyan 28061c35fb0SRuslan Arutyunyan _LIBCPP_END_NAMESPACE_STD 28161c35fb0SRuslan Arutyunyan 28261c35fb0SRuslan Arutyunyan #endif // _LIBCPP___COMPARE_ORDERING_H 283