1 #ifndef EAGINE_COMPARE_HPP
9 #define EAGINE_COMPARE_HPP
13 #include <type_traits>
18 template <
typename L,
typename R>
19 struct equal_cmp_any {
20 static constexpr
auto check(
const L& l,
const R& r) noexcept {
25 template <
typename L,
typename R,
bool LSign,
bool RSign>
28 template <
typename L,
typename R,
bool Sign>
29 struct equal_cmp_int<L, R, Sign, Sign> {
30 static constexpr
auto check(L l, R r) noexcept {
35 template <
typename L,
typename R>
36 struct equal_cmp_int<L, R, true, false> {
37 static constexpr
auto check(L l, R r) noexcept {
38 using Tmp = std::make_unsigned_t<L>;
39 return (l < 0) ? false : Tmp(l) == r;
43 template <
typename L,
typename R>
44 struct equal_cmp_int<L, R, false, true> : equal_cmp_int<R, L, true, false> {};
46 template <
typename L,
typename R>
47 using equal_cmp_pick = std::conditional_t<
48 std::is_integral_v<L> && std::is_integral_v<R>,
49 equal_cmp_int<L, R, std::is_signed_v<L>, std::is_signed_v<R>>,
52 template <
typename L,
typename R>
53 struct equal_cmp : equal_cmp_pick<L, R> {};
56 struct equal_cmp<float, float> {
57 static constexpr
auto check(
float l,
float r) noexcept {
58 return !((l - r) < 0.F || (l - r) > 0.F);
63 struct equal_cmp<double, double> {
64 static constexpr
auto check(
double l,
double r) noexcept {
65 return !((l - r) < 0.0 || (l - r) > 0.0);
69 template <
typename L,
typename R>
70 struct equal_cmp_obj : equal_cmp<L, R> {
71 constexpr equal_cmp_obj(L l, R r) noexcept
75 constexpr
explicit inline operator bool() const noexcept {
76 return equal_cmp<L, R>::check(_l, _r);
84 struct cmp_decay_to : type_identity<T> {};
86 using cmp_decay_to_t =
typename cmp_decay_to<T>::type;
88 template <
typename L,
typename R>
89 static constexpr
auto are_equal(
const L& l,
const R& r) noexcept {
90 return equal_cmp<cmp_decay_to_t<L>, cmp_decay_to_t<R>>::check(l, r);
95 #endif // EAGINE_COMPARE_HPP