HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
compare.hpp
1// Copyright Take Vos 2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
8#pragma once
9
10#include "type_traits.hpp"
11#include "../macros.hpp"
12#include "concepts.hpp"
13#include <concepts>
14#include <compare>
15
16hi_export_module(hikogui.utility.compare);
17
18hi_export namespace hi { inline namespace v1 {
19
22template<typename Lhs, typename Rhs>
24
25template<std::unsigned_integral Lhs, std::unsigned_integral Rhs>
26struct three_way_comparison<Lhs, Rhs> {
27 [[nodiscard]] constexpr std::strong_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
28 {
29 return lhs <=> rhs;
30 }
31};
32
33template<std::signed_integral Lhs, std::signed_integral Rhs>
34struct three_way_comparison<Lhs, Rhs> {
35 [[nodiscard]] constexpr std::strong_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
36 {
37 return lhs <=> rhs;
38 }
39};
40
41template<std::floating_point Lhs, std::floating_point Rhs>
42struct three_way_comparison<Lhs, Rhs> {
43 [[nodiscard]] constexpr std::partial_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
44 {
45 return lhs <=> rhs;
46 }
47};
48
49template<std::signed_integral Lhs, std::unsigned_integral Rhs>
50struct three_way_comparison<Lhs, Rhs> {
51 [[nodiscard]] constexpr std::strong_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
52 requires(sizeof(Rhs) < sizeof(long long))
53 {
54 return lhs <=> static_cast<long long>(rhs);
55 }
56
57 [[nodiscard]] constexpr std::strong_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
58 requires(sizeof(Rhs) == sizeof(long long))
59 {
60 if (lhs < 0) {
61 return std::strong_ordering::less;
62 } else {
63 return static_cast<unsigned long long>(lhs) <=> rhs;
64 }
65 }
66};
67
68template<std::unsigned_integral Lhs, std::signed_integral Rhs>
69struct three_way_comparison<Lhs, Rhs> {
70 [[nodiscard]] constexpr std::strong_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
71 requires(sizeof(Lhs) < sizeof(long long))
72 {
73 return static_cast<long long>(lhs) <=> rhs;
74 }
75
76 [[nodiscard]] constexpr std::strong_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
77 requires(sizeof(Lhs) == sizeof(long long))
78 {
79 if (rhs < 0) {
80 return std::strong_ordering::greater;
81 } else {
82 return lhs <=> static_cast<unsigned long long>(rhs);
83 }
84 }
85};
86
87template<std::floating_point Lhs, std::integral Rhs>
88struct three_way_comparison<Lhs, Rhs> {
89 [[nodiscard]] constexpr std::partial_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
90 {
91 if constexpr (sizeof(Rhs) < sizeof(float)) {
92 // All 16-bit integers can be exactly represented as float.
93 return lhs <=> static_cast<float>(rhs);
94 } else if constexpr (sizeof(Rhs) < sizeof(double)) {
95 // All 32-bit integers can be exactly represented as double.
96 return lhs <=> static_cast<double>(rhs);
97 } else {
98 return lhs <=> static_cast<long double>(rhs);
99 }
100 }
101};
102
103template<std::integral Lhs, std::floating_point Rhs>
104struct three_way_comparison<Lhs, Rhs> {
105 [[nodiscard]] constexpr std::partial_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
106 {
107 if constexpr (sizeof(Lhs) < sizeof(float)) {
108 // All 16-bit integers can be exactly represented as float.
109 return static_cast<float>(lhs) <=> rhs;
110 } else if constexpr (sizeof(Lhs) < sizeof(double)) {
111 // All 32-bit integers can be exactly represented as double.
112 return static_cast<double>(lhs) <=> rhs;
113 } else {
114 return static_cast<long double>(lhs) <=> rhs;
115 }
116 }
117};
118
125template<arithmetic Lhs, arithmetic Rhs>
126[[nodiscard]] constexpr auto three_way_compare(Lhs const& lhs, Rhs const& rhs) noexcept
127{
128 return three_way_comparison<Lhs, Rhs>{}(lhs, rhs);
129}
130
131}} // namespace hi::v1
The HikoGUI namespace.
Definition array_generic.hpp:20
constexpr auto three_way_compare(Lhs const &lhs, Rhs const &rhs) noexcept
Safely compare two arithmetic values to each other.
Definition compare.hpp:126
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
A functor to safely compare two arithmetic values.
Definition compare.hpp:23