HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
units.hpp
1// Copyright Take Vos 2023.
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
5#pragma once
6
7#include "cast.hpp"
8#include <ratio>
9#include <concepts>
10#include <compare>
11
12namespace hi { inline namespace v1 {
13
14template<typename Tag, typename T, typename Ratio = std::ratio<1>>
15class unit {
16public:
17 using value_type = T;
18 using ratio = Ratio;
19
20 constexpr unit(unit const&) noexcept = default;
21 constexpr unit(unit&&) noexcept = default;
22 constexpr unit& operator=(unit const&) noexcept = default;
23 constexpr unit& operator=(unit&&) noexcept = default;
24
25 constexpr explicit unit(value_type value) noexcept : _value(value) {}
26
27 template<typename OtherT, typename OtherRatio>
28 constexpr explicit unit(unit<Tag, OtherT, OtherRatio> const& other) noexcept
29 requires(not std::is_same_v<unit<Tag, OtherT, OtherRatio>, unit>)
30 {
31 using conversion = std::ratio_divide<Ratio, OtherRatio>;
32
33 auto tmp = wide_cast<std::common_type_t<T, OtherT>>(other.count());
34 tmp *= conversion::den;
35 tmp /= conversion::num;
36 _value = narrow_cast<T>(tmp);
37 }
38
39 template<typename OtherT, typename OtherRatio>
40 constexpr unit& operator=(unit<Tag, OtherT, OtherRatio> const& other) noexcept
41 requires(not std::is_same_v<unit<Tag, OtherT, OtherRatio>, unit>)
42 {
43 using conversion = std::ratio_divide<Ratio, OtherRatio>;
44
45 auto tmp = wide_cast<std::common_type_t<T, OtherT>>(other.count());
46 tmp *= conversion::den;
47 tmp /= conversion::num;
48 _value = narrow_cast<T>(tmp);
49 return *this;
50 }
51
52 [[nodiscard]] constexpr value_type count() const noexcept
53 {
54 return _value;
55 }
56
57 [[nodiscard]] constexpr unit& operator+=(unit const& rhs) noexcept
58 {
59 _value += rhs.count();
60 return *this;
61 }
62
63 [[nodiscard]] constexpr unit& operator-=(unit const& rhs) noexcept
64 {
65 _value -= rhs.count();
66 return *this;
67 }
68
69 [[nodiscard]] constexpr unit& operator*=(value_type const& rhs) noexcept
70 {
71 _value -= rhs;
72 return *this;
73 }
74
75 [[nodiscard]] constexpr unit& operator/=(value_type const& rhs) noexcept
76 {
77 _value -= rhs;
78 return *this;
79 }
80
81private:
82 value_type _value;
83};
84
85}} // namespace hi::v1
86
87template<typename Tag, typename T1, typename Ratio1, typename T2, typename Ratio2>
88struct std::common_type<hi::unit<Tag, T1, Ratio1>, hi::unit<Tag, T2, Ratio2>> {
89 // clang-format off
90 using type = hi::unit<
91 Tag,
92 std::common_type_t<T1, T2>,
93 std::conditional_t<std::ratio_less_v<Ratio1, Ratio2>, Ratio1, Ratio2>>;
94 // clang-format on
95};
96
97namespace hi { inline namespace v1 {
98
99template<typename Tag, typename T1, typename Ratio1, typename T2, typename Ratio2>
100[[nodiscard]] constexpr bool operator==(unit<Tag, T1, Ratio1> const& lhs, unit<Tag, T2, Ratio2> const& rhs) noexcept
101{
102 using common_type = std::common_type_t<unit<Tag, T1, Ratio1>, unit<Tag, T2, Ratio2>>;
103
104 hilet lhs_ = common_type{lhs};
105 hilet rhs_ = common_type{rhs};
106
107 return lhs_.count() == rhs_.count();
108}
109
110template<typename Tag, typename T1, typename Ratio1, typename T2, typename Ratio2>
111[[nodiscard]] constexpr auto operator<=>(unit<Tag, T1, Ratio1> const& lhs, unit<Tag, T2, Ratio2> const& rhs) noexcept
112{
113 using common_type = std::common_type_t<unit<Tag, T1, Ratio1>, unit<Tag, T2, Ratio2>>;
114
115 hilet lhs_ = common_type{lhs};
116 hilet rhs_ = common_type{rhs};
117
118 return lhs_.count() <=> rhs_.count();
119}
120
121template<typename Tag, typename T1, typename Ratio1, typename T2, typename Ratio2>
122[[nodiscard]] constexpr auto operator+(unit<Tag, T1, Ratio1> const& lhs, unit<Tag, T2, Ratio2> const& rhs) noexcept
123{
124 using common_type = std::common_type_t<unit<Tag, T1, Ratio1>, unit<Tag, T2, Ratio2>>;
125
126 hilet lhs_ = common_type{lhs};
127 hilet rhs_ = common_type{rhs};
128
129 return common_type{lhs_.count() + rhs_.count()};
130}
131
132template<typename Tag, typename T1, typename Ratio1, typename T2, typename Ratio2>
133[[nodiscard]] constexpr auto operator-(unit<Tag, T1, Ratio1> const& lhs, unit<Tag, T2, Ratio2> const& rhs) noexcept
134{
135 using common_type = std::common_type_t<unit<Tag, T1, Ratio1>, unit<Tag, T2, Ratio2>>;
136
137 hilet lhs_ = common_type{lhs};
138 hilet rhs_ = common_type{rhs};
139
140 return common_type{lhs_.count() - rhs_.count()};
141}
142
143template<typename Tag, typename T1, typename Ratio1, typename T2, typename Ratio2>
144[[nodiscard]] constexpr auto operator/(unit<Tag, T1, Ratio1> const& lhs, unit<Tag, T2, Ratio2> const& rhs) noexcept
145{
146 using common_type = std::common_type_t<unit<Tag, T1, Ratio1>, unit<Tag, T2, Ratio2>>;
147
148 hilet lhs_ = common_type{lhs};
149 hilet rhs_ = common_type{rhs};
150
151 return lhs_.count() / rhs_.count();
152}
153
154//[[nodiscard]] constexpr unit operator*(unit const& lhs, value_type const& rhs) noexcept
155//{
156// return unit{lhs.count() * rhs};
157//}
158//
159//[[nodiscard]] constexpr unit operator*(value_type const& lhs, unit const& rhs) noexcept
160//{
161// return unit{lhs * rhs.count()};
162//}
163//
164//[[nodiscard]] constexpr unit operator/(unit const& lhs, value_type const& rhs) noexcept
165//{
166// return unit{lhs.count() / rhs};
167//}
168
172
178
181using points = unit<si_length_tag, double, std::ratio<254, 720'000>::type>;
182
185using inches = unit<si_length_tag, double, std::ratio<254, 10'000>::type>;
186using feet = unit<si_length_tag, double, std::ratio<3'048, 10'000>::type>;
187using yards = unit<si_length_tag, double, std::ratio<9'144, 10'000>::type>;
188using miles = unit<si_length_tag, double, std::ratio<16'093'440, 10'000>::type>;
189
192using dips = unit<si_length_tag, double, std::ratio<254, 960'000>::type>;
193
197
201
202}} // namespace hi::v1
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
@ other
The gui_event does not have associated data.
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
Definition units.hpp:15
Definition units.hpp:169
Definition units.hpp:170
Definition units.hpp:171