mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-25 22:14:34 +00:00
296 lines
10 KiB
Plaintext
296 lines
10 KiB
Plaintext
/*
|
|
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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <type_traits>
|
|
#include <utility>
|
|
#include <cmath>
|
|
|
|
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 <unsigned int>
|
|
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 <class... Ts>
|
|
struct common_comparison_category
|
|
: detail::common_cmpcat_base<(0u | ... |
|
|
(std::is_same_v<Ts, std::strong_ordering> ? 0u
|
|
: std::is_same_v<Ts, std::weak_ordering> ? 4u
|
|
: std::is_same_v<Ts, std::partial_ordering> ? 2u
|
|
: 1u))>
|
|
{
|
|
};
|
|
|
|
template <class... Ts>
|
|
using common_comparison_category_t = common_comparison_category<Ts...>::type;
|
|
|
|
template <class T, class U = T>
|
|
using compare_three_way_result_t = decltype(std::declval<const std::remove_reference_t<T> &>() <=> std::declval<const std::remove_reference_t<U> &>());
|
|
|
|
template <class T, class U = T>
|
|
struct compare_three_way_result
|
|
{
|
|
};
|
|
|
|
template <class T, class U>
|
|
requires requires { typename compare_three_way_result_t<T, U>; }
|
|
struct compare_three_way_result<T, U>
|
|
{
|
|
using type = compare_three_way_result_t<T, U>;
|
|
};
|
|
|
|
struct compare_three_way
|
|
{
|
|
template <class T, class U>
|
|
constexpr auto operator()(T &&t, U &&u) const
|
|
{
|
|
return std::forward<T>(t) <=> std::forward<U>(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 <typename T, typename U>
|
|
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 = {};
|
|
}
|