acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
unit.h
1// Created by camilo on 2023-02-07 20:55 BRT <3ThomasBorregaardSorensen!!
2#pragma once
3
4
5template < typename ENUM >
6class unit_base
7{
8protected:
9
10
11 union
12 {
13
14 ::f64 m_f64;
15
16 ::i64 m_hi;
17
18 };
19
20
21 ENUM m_eunit;
22 bool m_bFloating : 1;
23
24
25public:
26
27
28 constexpr unit_base()
29 {
30 m_hi = 0;
31 m_eunit = (ENUM)0;
32 m_bFloating = false;
33 }
34
35 template < prototype_integral INTEGRAL >
36 constexpr unit_base(INTEGRAL i, ENUM eunit)
37 {
38 m_hi = (::i64)i;
39 m_eunit = eunit;
40 clear_floating();
41 }
42
43 template < prototype_floating FLOATING >
44 constexpr unit_base(FLOATING f, ENUM eunit)
45 {
46 m_f64 = (::f64)f;
47 m_eunit = eunit;
48 set_floating();
49 }
50
51 template < prototype_floating FLOATING >
52 constexpr unit_base(FLOATING f)
53 {
54 m_f64 = (::f64)f;
55 m_eunit = rate_unit();
56 set_floating();
57 }
58
59 constexpr unit_base(const unit_base & unit):
60 m_hi(unit.m_hi),
61 m_eunit(unit.m_eunit),
62 m_bFloating(unit.m_bFloating)
63 { }
64
65
66 constexpr bool is_rate()const { return m_eunit == rate_unit(); }
67 constexpr bool is_floating()const { return m_bFloating; }
68 constexpr void set_floating() { m_bFloating = true; }
69 constexpr void clear_floating() { m_bFloating = false; }
70
71 constexpr ::i64 as_i64() const { return is_floating() ? (::i64)m_f64 : m_hi; }
72 constexpr ::f64 as_f64() const { return is_floating() ? m_f64 : (::f64)m_hi; }
73 constexpr ::i32 as_i32() const { return (::i32) this->as_i64(); }
74 constexpr ::f32 as_f32() const { return (::f32) this->as_f64(); }
75 constexpr ENUM eunit() const { return m_eunit; }
76
77 constexpr bool is_null_or_negative() { return is_floating() ? m_f64 <= 0.0 : m_hi <= 0; }
78 constexpr bool is_negative() { return is_floating() ? m_f64 < 0.0 : m_hi < 0; }
79 constexpr bool is_null_or_positive() { return is_floating() ? m_f64 >= 0.0 : m_hi >= 0; }
80 constexpr bool is_positive() { return is_floating() ? m_f64 > 0.0 : m_hi > 0; }
81
82// constexpr operator ::i64()const { return i64; }
83// constexpr operator ::f64() const { return ::f64(); }
84// constexpr operator ENUM() const { return eunit(); }
85
86 //template < prototype_integral INTEGRAL >
87 //constexpr unit_base & operator = (INTEGRAL i) { m_hi = (::i64)i; clear_floating(); return *this; }
88
89
90 bool operator ==(const unit_base & unit) const
91 {
92
93 return m_hi == unit.m_hi && m_eunit == unit.m_eunit;
94
95 }
96
97 template < prototype_floating FLOATING >
98 constexpr unit_base & operator = (FLOATING f)
99 {
100
101 m_f64 = (::f64)f;
102
103 m_eunit = rate_unit();
104
105 set_floating();
106
107 return *this;
108
109 }
110
111
112 constexpr unit_base & operator = (const unit_base & unit)
113 {
114
115 m_hi = unit.m_hi;
116
117 m_eunit = unit.m_eunit;
118
119 m_bFloating = unit.m_bFloating;
120
121 return *this;
122
123 }
124
125
126 //constexpr ENUM raw_unit() const { return (ENUM) (m_eunit & ~INT_MIN); }
127 //constexpr ENUM floating_unit() const { return (ENUM)(m_eunit & INT_MIN); }
128
129
130 constexpr static ENUM rate_unit() { return (ENUM)-1; }
131
132
133 constexpr void set_unit(ENUM eunit) { m_eunit = eunit; }
134
135
136 template < prototype_floating FLOATING >
137 unit_base & operator *= (FLOATING f)
138 {
139
140 m_f64 = this->as_f64() * f;
141
142 set_floating();
143
144 return *this;
145
146 }
147
148
149 template < prototype_floating FLOATING >
150 unit_base & operator /= (FLOATING f)
151 {
152
153 m_f64 = this->as_f64() / f;
154
155 set_floating();
156
157 return *this;
158
159 }
160
161
162 template < prototype_floating FLOATING >
163 unit_base operator * (FLOATING f) const
164 {
165
166 unit_base < ENUM > unitResult(this->as_f64() * f, this->eunit());
167
168 return unitResult;
169
170 }
171
172
173 template < prototype_floating FLOATING >
174 unit_base operator / (FLOATING f) const
175 {
176
177 unit_base < ENUM > unitResult(this->as_f64() / f, this->eunit());
178
179 return *this;
180
181 }
182
183
184};
185
186
187template < prototype_floating FLOATING, typename ENUM >
188inline unit_base < ENUM > operator * (FLOATING f, const unit_base < ENUM > & unit)
189{
190
191 unit_base < ENUM > unitResult(unit.as_f64() * f, unit.eunit());
192
193 return unitResult;
194
195}
196
197using unit = unit_base < enum_unit >;
198
199template < prototype_number NUMBER >
200constexpr auto pixel_unit(NUMBER n)
201{
202
203 return unit(n, e_unit_pixel);
204
205}
206
207
208constexpr auto operator ""_px(::u64 i)
209{
210
211 return pixel_unit(i);
212
213}
214
215
216constexpr auto operator ""_px(::f128 d)
217{
218
219 return pixel_unit(d);
220
221}
222
223
224//struct point_unit_t {};
225
226//template < prototype_number NUMBER >
227//constexpr auto operator *(NUMBER n, point_unit_t) { return unit(n, e_unit_point); }
228
229
230template < prototype_number NUMBER >
231constexpr auto point_unit(NUMBER n)
232{
233
234 return unit(n, e_unit_point);
235
236}
237
238
239constexpr auto operator ""_pt(::u64 i)
240{
241
242 return point_unit(i);
243
244}
245
246
247constexpr auto operator ""_pt(::f128 d)
248{
249
250 return point_unit(d);
251
252}
253
254
255