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 = {};
}