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 "concepts.hpp"
11#include "type_traits.hpp"
12#include <concepts>
13#include <compare>
14
15namespace hi { inline namespace v1 {
16
19template<typename Lhs, typename Rhs>
21
22template<std::unsigned_integral Lhs, std::unsigned_integral Rhs>
23struct three_way_comparison<Lhs, Rhs> {
24 [[nodiscard]] constexpr std::strong_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
25 {
26 return lhs <=> rhs;
27 }
28};
29
30template<std::signed_integral Lhs, std::signed_integral Rhs>
31struct three_way_comparison<Lhs, Rhs> {
32 [[nodiscard]] constexpr std::strong_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
33 {
34 return lhs <=> rhs;
35 }
36};
37
38template<std::floating_point Lhs, std::floating_point Rhs>
39struct three_way_comparison<Lhs, Rhs> {
40 [[nodiscard]] constexpr std::partial_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
41 {
42 return lhs <=> rhs;
43 }
44};
45
46template<std::signed_integral Lhs, std::unsigned_integral Rhs>
47struct three_way_comparison<Lhs, Rhs> {
48 [[nodiscard]] constexpr std::strong_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
49 requires(sizeof(Rhs) < sizeof(long long))
50 {
51 return lhs <=> static_cast<long long>(rhs);
52 }
53
54 [[nodiscard]] constexpr std::strong_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
55 requires(sizeof(Rhs) == sizeof(long long))
56 {
57 if (lhs < 0) {
58 return std::strong_ordering::less;
59 } else {
60 return static_cast<unsigned long long>(lhs) <=> rhs;
61 }
62 }
63};
64
65template<std::unsigned_integral Lhs, std::signed_integral Rhs>
66struct three_way_comparison<Lhs, Rhs> {
67 [[nodiscard]] constexpr std::strong_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
68 requires(sizeof(Lhs) < sizeof(long long))
69 {
70 return static_cast<long long>(lhs) <=> rhs;
71 }
72
73 [[nodiscard]] constexpr std::strong_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
74 requires(sizeof(Lhs) == sizeof(long long))
75 {
76 if (rhs < 0) {
77 return std::strong_ordering::greater;
78 } else {
79 return lhs <=> static_cast<unsigned long long>(rhs);
80 }
81 }
82};
83
84template<std::floating_point Lhs, std::integral Rhs>
85struct three_way_comparison<Lhs, Rhs> {
86 [[nodiscard]] constexpr std::partial_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
87 {
88 if constexpr (sizeof(Rhs) < sizeof(float)) {
89 // All 16-bit integers can be exactly represented as float.
90 return lhs <=> static_cast<float>(rhs);
91 } else if constexpr (sizeof(Rhs) < sizeof(double)) {
92 // All 32-bit integers can be exactly represented as double.
93 return lhs <=> static_cast<double>(rhs);
94 } else {
95 return lhs <=> static_cast<long double>(rhs);
96 }
97 }
98};
99
100template<std::integral Lhs, std::floating_point Rhs>
101struct three_way_comparison<Lhs, Rhs> {
102 [[nodiscard]] constexpr std::partial_ordering operator()(Lhs const& lhs, Rhs const& rhs) const noexcept
103 {
104 if constexpr (sizeof(Lhs) < sizeof(float)) {
105 // All 16-bit integers can be exactly represented as float.
106 return static_cast<float>(lhs) <=> rhs;
107 } else if constexpr (sizeof(Lhs) < sizeof(double)) {
108 // All 32-bit integers can be exactly represented as double.
109 return static_cast<double>(lhs) <=> rhs;
110 } else {
111 return static_cast<long double>(lhs) <=> rhs;
112 }
113 }
114};
115
122template<arithmetic Lhs, arithmetic Rhs>
123[[nodiscard]] constexpr auto three_way_compare(Lhs const& lhs, Rhs const& rhs) noexcept
124{
125 return three_way_comparison<Lhs, Rhs>{}(lhs, rhs);
126}
127
128}} // namespace hi::v1
DOXYGEN BUG.
Definition algorithm.hpp:15
geometry/margins.hpp
Definition assert.hpp:18
constexpr auto three_way_compare(Lhs const &lhs, Rhs const &rhs) noexcept
Safely compare two arithmetic values to each other.
Definition compare.hpp:123
A functor to safely compare two arithmetic values.
Definition compare.hpp:20