Skip to main content

eunomia/casts/
primitives.rs

1use crate::traits::{CastFrom, FloatElement, NumericElement};
2use crate::types::{Bf16, Bf4, Bf8, F16, F32, F4, F64, F8, I16, I32, I8};
3
4// Implement CastFrom between all primitives
5macro_rules! impl_cast_primitive_between {
6    ($src:ty, $dst:ty) => {
7        impl CastFrom<$src> for $dst {
8            #[inline(always)]
9            fn cast_from(val: $src) -> Self {
10                val as $dst
11            }
12        }
13    };
14}
15
16impl_cast_primitive_between!(i8, i8);
17impl_cast_primitive_between!(i8, i16);
18impl_cast_primitive_between!(i8, i32);
19impl_cast_primitive_between!(i16, i8);
20impl_cast_primitive_between!(i16, i16);
21impl_cast_primitive_between!(i16, i32);
22impl_cast_primitive_between!(i32, i8);
23impl_cast_primitive_between!(i32, i16);
24impl_cast_primitive_between!(i32, i32);
25impl_cast_primitive_between!(i32, i64);
26impl_cast_primitive_between!(i32, u8);
27impl_cast_primitive_between!(i32, u16);
28impl_cast_primitive_between!(i32, u32);
29impl_cast_primitive_between!(i32, u64);
30impl_cast_primitive_between!(i32, usize);
31impl_cast_primitive_between!(i32, isize);
32
33impl_cast_primitive_between!(i64, i64);
34impl_cast_primitive_between!(i64, i8);
35impl_cast_primitive_between!(i64, i16);
36impl_cast_primitive_between!(i64, i32);
37
38impl_cast_primitive_between!(u8, u8);
39impl_cast_primitive_between!(u8, u16);
40impl_cast_primitive_between!(u8, u32);
41impl_cast_primitive_between!(u8, u64);
42impl_cast_primitive_between!(u8, i8);
43impl_cast_primitive_between!(u8, i16);
44impl_cast_primitive_between!(u8, i32);
45impl_cast_primitive_between!(u8, i64);
46
47impl_cast_primitive_between!(u16, u8);
48impl_cast_primitive_between!(u16, u16);
49impl_cast_primitive_between!(u16, u32);
50impl_cast_primitive_between!(u16, u64);
51impl_cast_primitive_between!(u16, i8);
52impl_cast_primitive_between!(u16, i16);
53impl_cast_primitive_between!(u16, i32);
54impl_cast_primitive_between!(u16, i64);
55
56impl_cast_primitive_between!(u32, u8);
57impl_cast_primitive_between!(u32, u16);
58impl_cast_primitive_between!(u32, u32);
59impl_cast_primitive_between!(u32, u64);
60impl_cast_primitive_between!(u32, i8);
61impl_cast_primitive_between!(u32, i16);
62impl_cast_primitive_between!(u32, i32);
63impl_cast_primitive_between!(u32, i64);
64
65impl_cast_primitive_between!(u64, u8);
66impl_cast_primitive_between!(u64, u16);
67impl_cast_primitive_between!(u64, u32);
68impl_cast_primitive_between!(u64, u64);
69impl_cast_primitive_between!(u64, i8);
70impl_cast_primitive_between!(u64, i16);
71impl_cast_primitive_between!(u64, i32);
72impl_cast_primitive_between!(u64, i64);
73
74impl_cast_primitive_between!(f32, f32);
75impl_cast_primitive_between!(f32, f64);
76impl_cast_primitive_between!(f64, f32);
77impl_cast_primitive_between!(f64, f64);
78
79macro_rules! impl_cast_primitive_float_int {
80    ($src:ty, $dst:ty) => {
81        impl CastFrom<$src> for $dst {
82            #[inline(always)]
83            fn cast_from(val: $src) -> Self {
84                val as $dst
85            }
86        }
87    };
88}
89impl_cast_primitive_float_int!(f32, i8);
90impl_cast_primitive_float_int!(f32, i16);
91impl_cast_primitive_float_int!(f32, i32);
92impl_cast_primitive_float_int!(f64, i8);
93impl_cast_primitive_float_int!(f64, i16);
94impl_cast_primitive_float_int!(f64, i32);
95impl_cast_primitive_float_int!(i8, f32);
96impl_cast_primitive_float_int!(i8, f64);
97impl_cast_primitive_float_int!(i16, f32);
98impl_cast_primitive_float_int!(i16, f64);
99impl_cast_primitive_float_int!(i32, f32);
100impl_cast_primitive_float_int!(i32, f64);
101impl_cast_primitive_float_int!(i64, f32);
102impl_cast_primitive_float_int!(i64, f64);
103impl_cast_primitive_float_int!(u8, f32);
104impl_cast_primitive_float_int!(u8, f64);
105impl_cast_primitive_float_int!(u16, f32);
106impl_cast_primitive_float_int!(u16, f64);
107impl_cast_primitive_float_int!(u32, f32);
108impl_cast_primitive_float_int!(u32, f64);
109impl_cast_primitive_float_int!(u64, f32);
110impl_cast_primitive_float_int!(u64, f64);
111
112impl_cast_primitive_float_int!(f32, i64);
113impl_cast_primitive_float_int!(f32, u8);
114impl_cast_primitive_float_int!(f32, u16);
115impl_cast_primitive_float_int!(f32, u32);
116impl_cast_primitive_float_int!(f32, u64);
117impl_cast_primitive_float_int!(f32, usize);
118impl_cast_primitive_float_int!(f64, i64);
119impl_cast_primitive_float_int!(f64, u8);
120impl_cast_primitive_float_int!(f64, u16);
121impl_cast_primitive_float_int!(f64, u32);
122impl_cast_primitive_float_int!(f64, u64);
123impl_cast_primitive_float_int!(f64, usize);
124
125// Casts between wrappers and primitives
126macro_rules! impl_cast_float_wrapper_primitive {
127    ($wrap:ident, $prim:ty) => {
128        impl CastFrom<$wrap> for $prim {
129            #[inline(always)]
130            fn cast_from(val: $wrap) -> Self {
131                <Self as CastFrom<f64>>::cast_from(val.to_f64())
132            }
133        }
134        impl CastFrom<$prim> for $wrap {
135            #[inline(always)]
136            fn cast_from(val: $prim) -> Self {
137                let f = <f64 as CastFrom<$prim>>::cast_from(val);
138                <$wrap as FloatElement>::from_f64(f)
139            }
140        }
141    };
142}
143
144macro_rules! impl_cast_int_wrapper_primitive {
145    ($wrap:ident, $inner:ty, $prim:ty) => {
146        impl CastFrom<$wrap> for $prim {
147            #[inline(always)]
148            fn cast_from(val: $wrap) -> Self {
149                <Self as CastFrom<$inner>>::cast_from(val.0)
150            }
151        }
152        impl CastFrom<$prim> for $wrap {
153            #[inline(always)]
154            fn cast_from(val: $prim) -> Self {
155                Self(<$inner as CastFrom<$prim>>::cast_from(val))
156            }
157        }
158    };
159}
160
161macro_rules! impl_cast_float_wrapper_primitives {
162    ($wrap:ident) => {
163        impl_cast_float_wrapper_primitive!($wrap, f32);
164        impl_cast_float_wrapper_primitive!($wrap, f64);
165        impl_cast_float_wrapper_primitive!($wrap, i8);
166        impl_cast_float_wrapper_primitive!($wrap, i16);
167        impl_cast_float_wrapper_primitive!($wrap, i32);
168    };
169}
170
171impl_cast_float_wrapper_primitives!(F16);
172impl_cast_float_wrapper_primitives!(F32);
173impl_cast_float_wrapper_primitives!(F64);
174impl_cast_float_wrapper_primitives!(Bf16);
175impl_cast_float_wrapper_primitives!(Bf8);
176impl_cast_float_wrapper_primitives!(Bf4);
177impl_cast_float_wrapper_primitives!(F8);
178impl_cast_float_wrapper_primitives!(F4);
179
180macro_rules! impl_cast_float_wrapper_to_index {
181    ($wrap:ident) => {
182        impl CastFrom<$wrap> for usize {
183            #[inline(always)]
184            fn cast_from(val: $wrap) -> Self {
185                val.to_f64() as usize
186            }
187        }
188    };
189}
190
191impl_cast_float_wrapper_to_index!(F16);
192impl_cast_float_wrapper_to_index!(F32);
193impl_cast_float_wrapper_to_index!(F64);
194impl_cast_float_wrapper_to_index!(Bf16);
195impl_cast_float_wrapper_to_index!(Bf8);
196impl_cast_float_wrapper_to_index!(Bf4);
197impl_cast_float_wrapper_to_index!(F8);
198impl_cast_float_wrapper_to_index!(F4);
199
200macro_rules! impl_cast_int_wrapper_primitives {
201    ($wrap:ident, $inner:ty) => {
202        impl_cast_int_wrapper_primitive!($wrap, $inner, f32);
203        impl_cast_int_wrapper_primitive!($wrap, $inner, f64);
204        impl_cast_int_wrapper_primitive!($wrap, $inner, i8);
205        impl_cast_int_wrapper_primitive!($wrap, $inner, i16);
206        impl_cast_int_wrapper_primitive!($wrap, $inner, i32);
207    };
208}
209
210impl_cast_int_wrapper_primitives!(I8, i8);
211impl_cast_int_wrapper_primitives!(I16, i16);
212impl_cast_int_wrapper_primitives!(I32, i32);
213
214// Float-to-Int wrapper casts
215macro_rules! impl_float_to_int {
216    ($src:ident, $dst:ident) => {
217        impl CastFrom<$src> for $dst {
218            #[inline(always)]
219            fn cast_from(val: $src) -> Self {
220                Self(val.to_f64() as _)
221            }
222        }
223    };
224}
225impl_float_to_int!(F16, I8);
226impl_float_to_int!(F16, I16);
227impl_float_to_int!(F16, I32);
228impl_float_to_int!(F32, I8);
229impl_float_to_int!(F32, I16);
230impl_float_to_int!(F32, I32);
231impl_float_to_int!(F64, I8);
232impl_float_to_int!(F64, I16);
233impl_float_to_int!(F64, I32);
234impl_float_to_int!(Bf16, I8);
235impl_float_to_int!(Bf16, I16);
236impl_float_to_int!(Bf16, I32);
237impl_float_to_int!(Bf8, I8);
238impl_float_to_int!(Bf8, I16);
239impl_float_to_int!(Bf8, I32);
240impl_float_to_int!(Bf4, I8);
241impl_float_to_int!(Bf4, I16);
242impl_float_to_int!(Bf4, I32);
243impl_float_to_int!(F8, I8);
244impl_float_to_int!(F8, I16);
245impl_float_to_int!(F8, I32);
246impl_float_to_int!(F4, I8);
247impl_float_to_int!(F4, I16);
248impl_float_to_int!(F4, I32);
249
250// Int-to-Float wrapper casts
251macro_rules! impl_int_to_float {
252    ($src:ident, $dst:ident) => {
253        impl CastFrom<$src> for $dst {
254            #[inline(always)]
255            fn cast_from(val: $src) -> Self {
256                Self::from_f64(val.0 as f64)
257            }
258        }
259    };
260}
261impl_int_to_float!(I8, F16);
262impl_int_to_float!(I8, F32);
263impl_int_to_float!(I8, F64);
264impl_int_to_float!(I8, Bf16);
265impl_int_to_float!(I8, Bf8);
266impl_int_to_float!(I8, Bf4);
267impl_int_to_float!(I8, F8);
268impl_int_to_float!(I8, F4);
269impl_int_to_float!(I16, F16);
270impl_int_to_float!(I16, F32);
271impl_int_to_float!(I16, F64);
272impl_int_to_float!(I16, Bf16);
273impl_int_to_float!(I16, Bf8);
274impl_int_to_float!(I16, Bf4);
275impl_int_to_float!(I16, F8);
276impl_int_to_float!(I16, F4);
277impl_int_to_float!(I32, F16);
278impl_int_to_float!(I32, F32);
279impl_int_to_float!(I32, F64);
280impl_int_to_float!(I32, Bf16);
281impl_int_to_float!(I32, Bf8);
282impl_int_to_float!(I32, Bf4);
283impl_int_to_float!(I32, F8);
284impl_int_to_float!(I32, F4);