1use crate::traits::{CastFrom, FloatElement, NumericElement};
2use crate::types::{Bf16, Bf4, Bf8, F16, F32, F4, F64, F8, I16, I32, I8};
3
4macro_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
125macro_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
214macro_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
250macro_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);