1#![allow(dead_code)]
2
3use std::ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign};
4use std::ops::{BitAnd, BitOr, BitXor, Shl, Shr, BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign, Not};
5use std::ops::{Rem, RemAssign};
6
7
8use std::cmp::Ordering;
9
10use std::fmt::{self, Display, Formatter};
11
12use crate::mod_i24::i24;
13
14#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
16#[allow(non_camel_case_types)]
17#[repr(C)]
18pub struct u24(pub u8, pub u8, pub u8);
19
20impl u24{
21 pub const MAX: u24 = u24(0xFF, 0xFF, 0xFF);
22 pub const MIN: u24 = u24(0x00, 0x00, 0x00);
23 #[inline(always)]
24 pub fn from_le_bytes(bytes: [u8; 3]) -> Self {
25 Self(bytes[0], bytes[1], bytes[2])
26 }
27 #[inline(always)]
28 pub fn from_be_bytes(bytes: [u8; 3]) -> Self {
29 Self(bytes[2], bytes[1], bytes[0])
30 }
31 #[inline(always)]
32 pub fn to_le_bytes(self) -> [u8; 3] {
33 [self.0, self.1, self.2]
34 }
35 #[inline(always)]
36 pub fn to_be_bytes(self) -> [u8; 3] {
37 [self.2, self.1, self.0]
38 }
39 #[inline(always)]
40 pub fn as_i128(self) -> i128 {
41 i128::from_le_bytes([self.0, self.1, self.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
42 }
43 #[inline(always)]
44 pub fn as_i64(self) -> i64 {
45 i64::from_le_bytes([self.0, self.1, self.2, 0, 0, 0, 0, 0])
46 }
47 #[inline(always)]
48 pub fn as_i32(self) -> i32 {
49 i32::from_le_bytes([self.0, self.1, self.2, 0])
50 }
51 #[inline(always)]
52 pub fn as_i16(self) -> i16 {
53 i16::from_le_bytes([self.0, self.1])
54 }
55 #[inline(always)]
56 pub fn as_i8(self) -> i8 {
57 self.0 as i8
58 }
59 #[inline(always)]
60 pub fn as_u128(self) -> u128 {
61 u128::from_le_bytes([self.0, self.1, self.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
62 }
63 #[inline(always)]
64 pub fn as_u64(self) -> u64 {
65 u64::from_le_bytes([self.0, self.1, self.2, 0, 0, 0, 0, 0])
66 }
67 #[inline(always)]
68 pub fn as_u32(self) -> u32 {
69 u32::from_le_bytes([self.0, self.1, self.2, 0])
70 }
71 #[inline(always)]
72 pub fn as_u16(self) -> u16 {
73 u16::from_le_bytes([self.0, self.1])
74 }
75 #[inline(always)]
76 pub fn as_u8(self) -> u8 {
77 self.0
78 }
79 #[inline(always)]
80 pub fn as_f32(self) -> f32 {
81 self.as_u32() as f32
82 }
83 #[inline(always)]
84 pub fn as_f64(self) -> f64 {
85 self.as_u32() as f64
86 }
87 #[inline(always)]
88 pub fn clamp(self, min: Self, max: Self) -> Self {
89 assert!(min <= max);
90 if self < min {
91 min
92 } else if self > max {
93 max
94 } else {
95 self
96 }
97 }
98}
99
100impl PartialOrd for u24 {
101 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
102 Some(self.as_u32().cmp(&other.as_u32()))
103 }
104}
105
106impl Ord for u24 {
107 fn cmp(&self, other: &Self) -> Ordering {
108 self.as_u32().cmp(&other.as_u32())
109 }
110}
111
112impl From<i8> for u24 {
113 #[inline(always)]
114 fn from(v: i8) -> Self {
115 Self::from(v as i32)
116 }
117}
118impl From<i16> for u24 {
119 #[inline(always)]
120 fn from(v: i16) -> Self {
121 Self::from(v as i32)
122 }
123}
124impl From<i24> for u24 {
125 #[inline(always)]
126 fn from(v: i24) -> Self {
127 Self::from(v.as_i32())
128 }
129}
130impl From<i32> for u24 {
131 #[inline(always)]
132 fn from(v: i32) -> Self {
133 let bytes = v.to_le_bytes();
134 Self(bytes[0], bytes[1], bytes[2])
135 }
136}
137impl From<i64> for u24 {
138 #[inline(always)]
139 fn from(v: i64) -> Self {
140 Self::from(v as i32)
141 }
142}
143impl From<i128> for u24 {
144 #[inline(always)]
145 fn from(v: i128) -> Self {
146 Self::from(v as i32)
147 }
148}
149impl From<u8> for u24 {
150 #[inline(always)]
151 fn from(v: u8) -> Self {
152 Self::from(v as u32)
153 }
154}
155impl From<u16> for u24 {
156 #[inline(always)]
157 fn from(v: u16) -> Self {
158 Self::from(v as u32)
159 }
160}
161impl From<u32> for u24 {
162 #[inline(always)]
163 fn from(v: u32) -> Self {
164 let bytes = v.to_le_bytes();
165 Self(bytes[0], bytes[1], bytes[2])
166 }
167}
168impl From<u64> for u24 {
169 #[inline(always)]
170 fn from(v: u64) -> Self {
171 Self::from(v as u32)
172 }
173}
174impl From<u128> for u24 {
175 #[inline(always)]
176 fn from(v: u128) -> Self {
177 Self::from(v as u32)
178 }
179}
180impl From<f32> for u24 {
181 #[inline(always)]
182 fn from(v: f32) -> Self {
183 Self::from(v as u32)
184 }
185}
186impl From<f64> for u24 {
187 #[inline(always)]
188 fn from(v: f64) -> Self {
189 Self::from(v as u32)
190 }
191}
192impl Into<i8> for u24 {
193 #[inline(always)]
194 fn into(self) -> i8 {
195 self.as_i8()
196 }
197}
198impl Into<i16> for u24 {
199 #[inline(always)]
200 fn into(self) -> i16 {
201 self.as_i16()
202 }
203}
204impl Into<i32> for u24 {
205 #[inline(always)]
206 fn into(self) -> i32 {
207 self.as_i32()
208 }
209}
210impl Into<i64> for u24 {
211 #[inline(always)]
212 fn into(self) -> i64 {
213 self.as_i64()
214 }
215}
216impl Into<i128> for u24 {
217 #[inline(always)]
218 fn into(self) -> i128 {
219 self.as_i128()
220 }
221}
222impl Into<u8> for u24 {
223 #[inline(always)]
224 fn into(self) -> u8 {
225 self.as_u8()
226 }
227}
228impl Into<u16> for u24 {
229 #[inline(always)]
230 fn into(self) -> u16 {
231 self.as_u16()
232 }
233}
234impl Into<u32> for u24 {
235 #[inline(always)]
236 fn into(self) -> u32 {
237 self.as_u32()
238 }
239}
240impl Into<u64> for u24 {
241 #[inline(always)]
242 fn into(self) -> u64 {
243 self.as_u64()
244 }
245}
246impl Into<u128> for u24 {
247 #[inline(always)]
248 fn into(self) -> u128 {
249 self.as_u128()
250 }
251}
252impl Into<f32> for u24 {
253 #[inline(always)]
254 fn into(self) -> f32 {
255 self.as_f32()
256 }
257}
258impl Into<f64> for u24 {
259 #[inline(always)]
260 fn into(self) -> f64 {
261 self.as_f64()
262 }
263}
264
265impl Add for u24 {
266 type Output = Self;
267 #[inline(always)]
268 fn add(self, rhs: Self) -> Self::Output {
269 Self::from(self.as_u32() + rhs.as_u32())
270 }
271}
272impl Sub for u24 {
273 type Output = Self;
274 #[inline(always)]
275 fn sub(self, rhs: Self) -> Self::Output {
276 Self::from(self.as_u32() - rhs.as_u32())
277 }
278}
279impl Mul for u24 {
280 type Output = Self;
281 #[inline(always)]
282 fn mul(self, rhs: Self) -> Self::Output {
283 Self::from(self.as_u32() * rhs.as_u32())
284 }
285}
286impl Div for u24 {
287 type Output = Self;
288 #[inline(always)]
289 fn div(self, rhs: Self) -> Self::Output {
290 Self::from(self.as_u32() / rhs.as_u32())
291 }
292}
293impl AddAssign for u24 {
294 #[inline(always)]
295 fn add_assign(&mut self, rhs: Self) {
296 *self = self.add(rhs);
297 }
298}
299impl SubAssign for u24 {
300 #[inline(always)]
301 fn sub_assign(&mut self, rhs: Self) {
302 *self = self.sub(rhs);
303 }
304}
305impl MulAssign for u24 {
306 #[inline(always)]
307 fn mul_assign(&mut self, rhs: Self) {
308 *self = self.mul(rhs);
309 }
310}
311impl DivAssign for u24 {
312 #[inline(always)]
313 fn div_assign(&mut self, rhs: Self) {
314 *self = self.div(rhs);
315 }
316}
317impl BitAnd for u24 {
318 type Output = Self;
319 #[inline(always)]
320 fn bitand(self, rhs: Self) -> Self::Output {
321 Self(self.0 & rhs.0, self.1 & rhs.1, self.2 & rhs.2)
322 }
323}
324impl BitOr for u24 {
325 type Output = Self;
326 #[inline(always)]
327 fn bitor(self, rhs: Self) -> Self::Output {
328 Self(self.0 | rhs.0, self.1 | rhs.1, self.2 | rhs.2)
329 }
330}
331impl BitXor for u24 {
332 type Output = Self;
333 #[inline(always)]
334 fn bitxor(self, rhs: Self) -> Self::Output {
335 Self(self.0 ^ rhs.0, self.1 ^ rhs.1, self.2 ^ rhs.2)
336 }
337}
338impl Shl for u24 {
339 type Output = Self;
340 #[inline(always)]
341 fn shl(self, rhs: Self) -> Self::Output {
342 Self::from(self.as_u32() << rhs.as_u32())
343 }
344}
345impl Shr for u24 {
346 type Output = Self;
347 #[inline(always)]
348 fn shr(self, rhs: Self) -> Self::Output {
349 Self::from(self.as_u32() >> rhs.as_u32())
350 }
351}
352impl BitAndAssign for u24 {
353 #[inline(always)]
354 fn bitand_assign(&mut self, rhs: Self) {
355 *self = self.bitand(rhs);
356 }
357}
358impl BitOrAssign for u24 {
359 #[inline(always)]
360 fn bitor_assign(&mut self, rhs: Self) {
361 *self = self.bitor(rhs);
362 }
363}
364impl BitXorAssign for u24 {
365 #[inline(always)]
366 fn bitxor_assign(&mut self, rhs: Self) {
367 *self = self.bitxor(rhs);
368 }
369}
370impl ShlAssign for u24 {
371 #[inline(always)]
372 fn shl_assign(&mut self, rhs: Self) {
373 *self = self.shl(rhs);
374 }
375}
376impl ShrAssign for u24 {
377 #[inline(always)]
378 fn shr_assign(&mut self, rhs: Self) {
379 *self = self.shr(rhs);
380 }
381}
382impl Rem for u24 {
383 type Output = Self;
384 #[inline(always)]
385 fn rem(self, rhs: Self) -> Self::Output {
386 Self::from(self.as_u32() % rhs.as_u32())
387 }
388}
389impl RemAssign for u24 {
390 #[inline(always)]
391 fn rem_assign(&mut self, rhs: Self) {
392 *self = self.rem(rhs);
393 }
394}
395impl Not for u24 {
396 type Output = Self;
397 #[inline(always)]
398 fn not(self) -> Self::Output {
399 Self(!self.0, !self.1, !self.2)
400 }
401}
402
403impl Default for u24 {
404 fn default() -> Self {
405 Self(0, 0, 0)
406 }
407}
408
409impl Display for u24 {
410 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
411 write!(f, "{}", self.as_u32())
412 }
413}