1pub mod f32;
6pub mod f64;
7mod u128;
8pub mod u16;
9pub mod u32;
10pub mod u64;
11pub mod u8;
12mod wrapping;
13
14use crate::f64::FloatExt;
15use core::fmt::{Debug, Display};
16use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
17use core::str::FromStr;
18use irox_bits::{Error, MutBits, WriteToBEBits};
19pub use wrapping::*;
20
21#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
24pub enum IntegerValue {
25 U8(u8),
26 U16(u16),
27 U32(u32),
28 U64(u64),
29 U128(u128),
30
31 I8(i8),
32 I16(i16),
33 I32(i32),
34 I64(i64),
35 I128(i128),
36}
37
38impl IntegerValue {
39 pub const fn to_be_u128(&self) -> u128 {
40 match self {
41 IntegerValue::U8(i) => *i as u128,
42 IntegerValue::U16(i) => *i as u128,
43 IntegerValue::U32(i) => *i as u128,
44 IntegerValue::U64(i) => *i as u128,
45 IntegerValue::U128(i) => *i,
46 IntegerValue::I8(i) => *i as u128,
47 IntegerValue::I16(i) => *i as u128,
48 IntegerValue::I32(i) => *i as u128,
49 IntegerValue::I64(i) => *i as u128,
50 IntegerValue::I128(i) => *i as u128,
51 }
52 }
53 pub const fn to_be_u64(&self) -> u64 {
54 match self {
55 IntegerValue::U8(i) => *i as u64,
56 IntegerValue::U16(i) => *i as u64,
57 IntegerValue::U32(i) => *i as u64,
58 IntegerValue::U64(i) => *i,
59 IntegerValue::U128(i) => *i as u64,
60 IntegerValue::I8(i) => *i as u64,
61 IntegerValue::I16(i) => *i as u64,
62 IntegerValue::I32(i) => *i as u64,
63 IntegerValue::I64(i) => *i as u64,
64 IntegerValue::I128(i) => *i as u64,
65 }
66 }
67 pub const fn to_be_u32(&self) -> u32 {
68 self.to_be_u64() as u32
69 }
70
71 #[must_use]
72 pub const fn to_le(&self) -> Self {
73 match self {
74 IntegerValue::U8(_) | IntegerValue::I8(_) => *self,
75 IntegerValue::U16(b) => IntegerValue::U16(b.to_le()),
76 IntegerValue::U32(b) => IntegerValue::U32(b.to_le()),
77 IntegerValue::U64(b) => IntegerValue::U64(b.to_le()),
78 IntegerValue::U128(b) => IntegerValue::U128(b.to_le()),
79 IntegerValue::I16(b) => IntegerValue::I16(b.to_le()),
80 IntegerValue::I32(b) => IntegerValue::I32(b.to_le()),
81 IntegerValue::I64(b) => IntegerValue::I64(b.to_le()),
82 IntegerValue::I128(b) => IntegerValue::I128(b.to_le()),
83 }
84 }
85}
86impl WriteToBEBits for IntegerValue {
87 fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
88 match self {
89 IntegerValue::U8(i) => i.write_be_to(bits),
90 IntegerValue::U16(i) => i.write_be_to(bits),
91 IntegerValue::U32(i) => i.write_be_to(bits),
92 IntegerValue::U64(i) => i.write_be_to(bits),
93 IntegerValue::U128(i) => i.write_be_to(bits),
94 IntegerValue::I8(i) => i.write_be_to(bits),
95 IntegerValue::I16(i) => i.write_be_to(bits),
96 IntegerValue::I32(i) => i.write_be_to(bits),
97 IntegerValue::I64(i) => i.write_be_to(bits),
98 IntegerValue::I128(i) => i.write_be_to(bits),
99 }
100 }
101}
102
103macro_rules! impl_from_integer {
104 ($typ:ty, $($elem:tt)+) => {
105 impl From<$typ> for IntegerValue {
106 fn from(value: $typ) -> Self {
107 $($elem)+(value)
108 }
109 }
110 impl From<&$typ> for IntegerValue {
111 fn from(value: &$typ) -> Self {
112 $($elem)+(*value)
113 }
114 }
115 impl From<&mut $typ> for IntegerValue {
116 fn from(value: &mut $typ) -> Self {
117 $($elem)+(*value)
118 }
119 }
120 };
121}
122impl_from_integer!(u8, IntegerValue::U8);
123impl_from_integer!(i8, IntegerValue::I8);
124impl_from_integer!(u16, IntegerValue::U16);
125impl_from_integer!(i16, IntegerValue::I16);
126impl_from_integer!(u32, IntegerValue::U32);
127impl_from_integer!(i32, IntegerValue::I32);
128impl_from_integer!(u64, IntegerValue::U64);
129impl_from_integer!(i64, IntegerValue::I64);
130impl_from_integer!(u128, IntegerValue::U128);
131impl_from_integer!(i128, IntegerValue::I128);
132
133pub trait ToF64 {
136 fn to_f64(&self) -> f64;
137}
138
139pub trait FromF64 {
140 fn from_f64(value: f64) -> Self;
141}
142
143pub trait ToSigned {
146 type Output;
147 fn to_signed(self) -> Self::Output;
148 fn negative_one() -> Self::Output;
149}
150
151macro_rules! impl_to_signed {
152 ($src:ty, $dst:ty) => {
153 impl ToSigned for $src {
154 type Output = $dst;
155 fn to_signed(self) -> Self::Output {
156 self as $dst
157 }
158 fn negative_one() -> Self::Output {
159 -1 as $dst
160 }
161 }
162 impl ToSigned for $dst {
163 type Output = $dst;
164 fn to_signed(self) -> Self::Output {
165 self
166 }
167 fn negative_one() -> Self::Output {
168 -1 as $dst
169 }
170 }
171 };
172}
173impl_to_signed!(u8, i8);
174impl_to_signed!(u16, i16);
175impl_to_signed!(u32, i32);
176impl_to_signed!(u64, i64);
177impl_to_signed!(u128, i128);
178
179pub trait ToUnsigned {
182 type Output;
183 fn to_unsigned(self) -> Self::Output;
184}
185
186macro_rules! impl_to_unsigned {
187 ($src:ty, $dst:ty) => {
188 impl ToUnsigned for $src {
189 type Output = $dst;
190 fn to_unsigned(self) -> Self::Output {
191 self as $dst
192 }
193 }
194 impl ToUnsigned for $dst {
195 type Output = $dst;
196 fn to_unsigned(self) -> Self::Output {
197 self
198 }
199 }
200 };
201}
202impl_to_unsigned!(i8, u8);
203impl_to_unsigned!(i16, u16);
204impl_to_unsigned!(i32, u32);
205impl_to_unsigned!(i64, u64);
206impl_to_unsigned!(i128, u128);
207
208pub trait ToU64 {
209 fn to_u64(&self) -> u64;
210}
211macro_rules! impl_to_u64 {
212 ($ty:ty) => {
213 impl ToU64 for $ty {
214 fn to_u64(&self) -> u64 {
215 *self as u64
216 }
217 }
218 };
219}
220impl_to_u64!(u8);
221impl_to_u64!(i8);
222impl_to_u64!(u16);
223impl_to_u64!(i16);
224impl_to_u64!(u32);
225impl_to_u64!(i32);
226impl_to_u64!(u64);
227impl_to_u64!(i64);
228impl_to_u64!(u128);
229impl_to_u64!(i128);
230impl_to_u64!(f32);
231impl_to_u64!(f64);
232impl_to_u64!(bool);
233impl_to_u64!(char);
234
235pub trait One {
236 const ONE: Self;
237}
238pub trait Zero {
239 const ZERO: Self;
240}
241
242macro_rules! impl_onezero_f {
243 ($typ:ty) => {
244 impl One for $typ {
245 const ONE: Self = 1.0;
246 }
247 impl Zero for $typ {
248 const ZERO: Self = 0.0;
249 }
250 };
251}
252impl_onezero_f!(f32);
253impl_onezero_f!(f64);
254
255macro_rules! impl_onezero_i {
256 ($typ:ty) => {
257 impl One for $typ {
258 const ONE: Self = 1;
259 }
260 impl Zero for $typ {
261 const ZERO: Self = 0;
262 }
263 };
264}
265impl_onezero_i!(u8);
266impl_onezero_i!(i8);
267impl_onezero_i!(u16);
268impl_onezero_i!(i16);
269impl_onezero_i!(u32);
270impl_onezero_i!(i32);
271impl_onezero_i!(u64);
272impl_onezero_i!(i64);
273impl_onezero_i!(u128);
274impl_onezero_i!(i128);
275
276pub trait PrimitiveMath:
277 Sized
278 + Add<Output = Self>
279 + Sub<Output = Self>
280 + Mul<Output = Self>
281 + Div<Output = Self>
282 + AddAssign
283 + SubAssign
284 + MulAssign
285 + DivAssign
286{
287}
288
289pub trait FloatIsh:
290 One
291 + Zero
292 + ToF64
293 + FromF64
294 + FromStr
295 + ToSigned
296 + FloatExt<Type = Self>
297 + Sized
298 + Copy
299 + Clone
300 + PartialEq
301 + PartialOrd
302 + Default
303 + PrimitiveMath
304 + Debug
305 + Display
306{
307}
308
309pub trait Cast<Output = Self> {
310 fn cast(self) -> Output;
311}
312macro_rules! impl_cast {
313 ($src:ty, $($dst:ty)*) => {
314 $(
315 impl Cast<$dst> for $src {
316
317 fn cast(self) -> $dst {
318 self as $dst
319 }
320 }
321 )*
322 };
323}
324impl_cast!(u8 , u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64);
325impl_cast!(i8 , u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64);
326impl_cast!(u16, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64);
327impl_cast!(i16, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64);
328impl_cast!(u32, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64);
329impl_cast!(i32, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64);
330impl_cast!(u64, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64);
331impl_cast!(i64, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64);
332impl_cast!(u128, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64);
333impl_cast!(i128, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64);
334impl_cast!(f32, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64);
335impl_cast!(f64, u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64);