/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #pragma once #include #include #include namespace std { namespace __cmp_dtl { using type = signed char; enum order : type { less = -1, equivalent = 0, greater = 1, unordered = 2 }; struct __unspecified { consteval __unspecified(__unspecified *) noexcept {} }; }; class partial_ordering { private: __cmp_dtl::type value; constexpr explicit partial_ordering(__cmp_dtl::order v) noexcept : value(__cmp_dtl::type(v)) {} friend class weak_ordering; friend class strong_ordering; public: static const partial_ordering less; static const partial_ordering equivalent; static const partial_ordering greater; static const partial_ordering unordered; friend constexpr bool operator==(partial_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value == 0; } friend constexpr bool operator==(partial_ordering v, partial_ordering w) noexcept = default; friend constexpr bool operator<(partial_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value == -1; } friend constexpr bool operator<(__cmp_dtl::__unspecified u, partial_ordering v) noexcept { return v.value == 1; } friend constexpr bool operator<=(partial_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value <= 0; } friend constexpr bool operator<=(__cmp_dtl::__unspecified u, partial_ordering v) noexcept { return __cmp_dtl::type(v.value & 1) == v.value; } friend constexpr bool operator>(partial_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value == 1; } friend constexpr bool operator>(__cmp_dtl::__unspecified u, partial_ordering v) noexcept { return v.value == -1; } friend constexpr bool operator>=(partial_ordering v, __cmp_dtl::__unspecified u) noexcept { return __cmp_dtl::type(v.value & 1) == v.value; } friend constexpr bool operator>=(__cmp_dtl::__unspecified u, partial_ordering v) noexcept { return 0 >= v.value; } friend constexpr partial_ordering operator<=>(partial_ordering v, __cmp_dtl::__unspecified u) noexcept { return v; } friend constexpr partial_ordering operator<=>(__cmp_dtl::__unspecified u, partial_ordering v) noexcept { if (v.value & 1) return partial_ordering(__cmp_dtl::order(-v.value)); else return v; } }; inline constexpr partial_ordering partial_ordering::less(__cmp_dtl::order::less); inline constexpr partial_ordering partial_ordering::equivalent(__cmp_dtl::order::equivalent); inline constexpr partial_ordering partial_ordering::greater(__cmp_dtl::order::greater); inline constexpr partial_ordering partial_ordering::unordered(__cmp_dtl::order::unordered); class weak_ordering { private: __cmp_dtl::type value; constexpr explicit weak_ordering(__cmp_dtl::order v) noexcept : value(__cmp_dtl::type(v)) {} friend class strong_ordering; public: static const weak_ordering less; static const weak_ordering equivalent; static const weak_ordering greater; constexpr operator partial_ordering() const noexcept { return partial_ordering(__cmp_dtl::order(value)); } friend constexpr bool operator==(weak_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value == 0; } friend constexpr bool operator==(weak_ordering v, weak_ordering w) noexcept = default; friend constexpr bool operator<(weak_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value < 0; } friend constexpr bool operator<(__cmp_dtl::__unspecified u, weak_ordering v) noexcept { return 0 < v.value; } friend constexpr bool operator<=(weak_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value <= 0; } friend constexpr bool operator<=(__cmp_dtl::__unspecified u, weak_ordering v) noexcept { return 0 <= v.value; } friend constexpr bool operator>(weak_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value > 0; } friend constexpr bool operator>(__cmp_dtl::__unspecified u, weak_ordering v) noexcept { return 0 > v.value; } friend constexpr bool operator>=(weak_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value >= 0; } friend constexpr bool operator>=(__cmp_dtl::__unspecified u, weak_ordering v) noexcept { return 0 >= v.value; } friend constexpr weak_ordering operator<=>(weak_ordering v, __cmp_dtl::__unspecified u) noexcept { return v; } friend constexpr weak_ordering operator<=>(__cmp_dtl::__unspecified u, weak_ordering v) noexcept { return weak_ordering(__cmp_dtl::order(-v.value)); } }; inline constexpr weak_ordering weak_ordering::less(__cmp_dtl::order::less); inline constexpr weak_ordering weak_ordering::equivalent(__cmp_dtl::order::equivalent); inline constexpr weak_ordering weak_ordering::greater(__cmp_dtl::order::greater); class strong_ordering { private: __cmp_dtl::type value; constexpr explicit strong_ordering(__cmp_dtl::order v) noexcept : value(__cmp_dtl::type(v)) {} public: static const strong_ordering less; static const strong_ordering equivalent; static const strong_ordering equal; static const strong_ordering greater; constexpr operator partial_ordering() const noexcept { return partial_ordering(__cmp_dtl::order(value)); } constexpr operator weak_ordering() const noexcept { return weak_ordering(__cmp_dtl::order(value)); } friend constexpr bool operator==(strong_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value == 0; } friend constexpr bool operator==(strong_ordering v, strong_ordering w) noexcept = default; friend constexpr bool operator<(strong_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value < 0; } friend constexpr bool operator<(__cmp_dtl::__unspecified u, strong_ordering v) noexcept { return 0 < v.value; } friend constexpr bool operator<=(strong_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value <= 0; } friend constexpr bool operator<=(__cmp_dtl::__unspecified u, strong_ordering v) noexcept { return 0 <= v.value; } friend constexpr bool operator>(strong_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value > 0; } friend constexpr bool operator>(__cmp_dtl::__unspecified u, strong_ordering v) noexcept { return 0 > v.value; } friend constexpr bool operator>=(strong_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value >= 0; } friend constexpr bool operator>=(__cmp_dtl::__unspecified u, strong_ordering v) noexcept { return 0 >= v.value; } friend constexpr strong_ordering operator<=>(strong_ordering v, __cmp_dtl::__unspecified u) noexcept { return v; } friend constexpr strong_ordering operator<=>(__cmp_dtl::__unspecified u, strong_ordering v) noexcept { return strong_ordering(__cmp_dtl::order(-v.value)); } }; inline constexpr strong_ordering strong_ordering::less(__cmp_dtl::order::less); inline constexpr strong_ordering strong_ordering::equivalent(__cmp_dtl::order::equivalent); inline constexpr strong_ordering strong_ordering::equal(__cmp_dtl::order::equivalent); inline constexpr strong_ordering strong_ordering::greater(__cmp_dtl::order::greater); constexpr bool is_eq(partial_ordering cmp) noexcept { return cmp == 0; } constexpr bool is_neq(partial_ordering cmp) noexcept { return cmp != 0; } constexpr bool is_lt(partial_ordering cmp) noexcept { return cmp < 0; } constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; } constexpr bool is_gt(partial_ordering cmp) noexcept { return cmp > 0; } constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; } namespace detail { template struct common_cmpcat_base { using type = void; }; template <> struct common_cmpcat_base<0u> { using type = std::strong_ordering; }; template <> struct common_cmpcat_base<2u> { using type = std::partial_ordering; }; template <> struct common_cmpcat_base<4u> { using type = std::weak_ordering; }; template <> struct common_cmpcat_base<6u> { using type = std::partial_ordering; }; } template struct common_comparison_category : detail::common_cmpcat_base<(0u | ... | (std::is_same_v ? 0u : std::is_same_v ? 4u : std::is_same_v ? 2u : 1u))> { }; template using common_comparison_category_t = common_comparison_category::type; template using compare_three_way_result_t = decltype(std::declval &>() <=> std::declval &>()); template struct compare_three_way_result { }; template requires requires { typename compare_three_way_result_t; } struct compare_three_way_result { using type = compare_three_way_result_t; }; struct compare_three_way { template constexpr auto operator()(T &&t, U &&u) const { return std::forward(t) <=> std::forward(u); } using is_transparent = void; }; inline constexpr struct strong_order_fn { } strong_order; inline constexpr struct weak_order_fn { } weak_order; inline constexpr struct partial_order_fn { } partial_order; inline constexpr struct compare_strong_order_fallback_fn { } compare_strong_order_fallback; inline constexpr struct compare_weak_order_fallback_fn { } compare_weak_order_fallback; inline constexpr struct compare_partial_order_fallback_fn { } compare_partial_order_fallback; inline constexpr struct __SynthThreeWayCompare { template constexpr auto operator()(const T &lhs, const U &rhs) const { if (lhs < rhs) return weak_ordering::less; else if (rhs < lhs) return weak_ordering::greater; else return weak_ordering::equivalent; } } __synth_three_way = {}; }