1#![allow(non_camel_case_types)]
7
8type c32 = num::complex::Complex<f32>;
11type c64 = num::complex::Complex<f64>;
12use duplicate::duplicate_item;
13use num::Complex;
14use num::{One, Zero};
15
16pub trait DTypeIntoFloatAPI {
17 type FloatType;
18 fn into_float(self) -> Self::FloatType;
19}
20
21pub trait DTypeCastAPI<T> {
22 fn into_cast(self) -> T;
23}
24
25pub trait DTypePromoteAPI<T> {
26 type Res;
27 const SAME_TYPE: bool = false;
28 const CAN_CAST_SELF: bool = false;
29 const CAN_CAST_OTHER: bool = false;
30 fn promote_self(self) -> Self::Res;
31 fn promote_other(val: T) -> Self::Res;
32 #[inline]
33 fn promote_pair(self, val: T) -> (Self::Res, Self::Res)
34 where
35 Self: Sized,
36 {
37 (self.promote_self(), Self::promote_other(val))
38 }
39}
40
41impl<T> DTypePromoteAPI<T> for T {
42 type Res = T;
43 const SAME_TYPE: bool = true;
44 const CAN_CAST_SELF: bool = true;
45 const CAN_CAST_OTHER: bool = true;
46 #[inline]
47 fn promote_self(self) -> Self::Res {
48 self
49 }
50 #[inline]
51 fn promote_other(val: T) -> Self::Res {
52 val
53 }
54}
55
56impl<T> DTypeCastAPI<T> for T {
57 #[inline]
58 fn into_cast(self) -> T {
59 self
60 }
61}
62
63#[duplicate_item(T; [u8]; [u16]; [u32]; [u64];)]
68impl DTypeIntoFloatAPI for T {
69 type FloatType = f64;
70 #[inline]
71 fn into_float(self) -> Self::FloatType {
72 self as _
73 }
74}
75
76#[duplicate_item(T; [i8]; [i16]; [i32]; [i64];)]
77impl DTypeIntoFloatAPI for T {
78 type FloatType = f64;
79 #[inline]
80 fn into_float(self) -> Self::FloatType {
81 self as _
82 }
83}
84
85#[duplicate_item(T; [f32]; [f64]; [c32]; [c64];)]
86impl DTypeIntoFloatAPI for T {
87 type FloatType = T;
88 #[inline]
89 fn into_float(self) -> Self::FloatType {
90 self
91 }
92}
93
94#[cfg(feature = "half")]
95#[duplicate_item(T; [half::f16]; [half::bf16];)]
96impl DTypeIntoFloatAPI for T {
97 type FloatType = T;
98 #[inline]
99 fn into_float(self) -> Self::FloatType {
100 self
101 }
102}
103
104impl DTypeIntoFloatAPI for usize {
105 type FloatType = f64;
106 #[inline]
107 fn into_float(self) -> Self::FloatType {
108 self as _
109 }
110}
111
112impl DTypeIntoFloatAPI for isize {
113 type FloatType = f64;
114 #[inline]
115 fn into_float(self) -> Self::FloatType {
116 self as _
117 }
118}
119
120macro_rules! impl_promotion_bool_T {
125 ($T:ty) => {
126 impl DTypePromoteAPI<$T> for bool {
127 type Res = $T;
128 const CAN_CAST_OTHER: bool = true;
129 #[inline]
130 fn promote_self(self) -> Self::Res {
131 if self {
132 <$T>::one()
133 } else {
134 <$T>::zero()
135 }
136 }
137 #[inline]
138 fn promote_other(val: $T) -> Self::Res {
139 val
140 }
141 }
142
143 impl DTypePromoteAPI<bool> for $T {
144 type Res = $T;
145 const CAN_CAST_SELF: bool = true;
146 #[inline]
147 fn promote_self(self) -> Self::Res {
148 self
149 }
150 #[inline]
151 fn promote_other(val: bool) -> Self::Res {
152 if val {
153 <$T>::one()
154 } else {
155 <$T>::zero()
156 }
157 }
158 }
159
160 impl DTypeCastAPI<bool> for $T {
161 #[inline]
162 fn into_cast(self) -> bool {
163 self != <$T>::zero()
164 }
165 }
166
167 impl DTypeCastAPI<$T> for bool {
168 #[inline]
169 fn into_cast(self) -> $T {
170 if self {
171 <$T>::one()
172 } else {
173 <$T>::zero()
174 }
175 }
176 }
177 };
178}
179
180impl_promotion_bool_T!(u8);
182impl_promotion_bool_T!(u16);
183impl_promotion_bool_T!(u32);
184impl_promotion_bool_T!(u64);
185impl_promotion_bool_T!(i8);
186impl_promotion_bool_T!(i16);
187impl_promotion_bool_T!(i32);
188impl_promotion_bool_T!(i64);
189impl_promotion_bool_T!(f32);
190impl_promotion_bool_T!(f64);
191impl_promotion_bool_T!(usize);
193impl_promotion_bool_T!(isize);
194#[cfg(feature = "half")]
195impl_promotion_bool_T!(half::f16);
196#[cfg(feature = "half")]
197impl_promotion_bool_T!(half::bf16);
198impl_promotion_bool_T!(c32);
200impl_promotion_bool_T!(c64);
201
202macro_rules! impl_promotion_asable {
207 ($T1:ty, $T2:ty, $can_cast_self: ident, $can_cast_other: ident, $Res:ty) => {
208 impl DTypePromoteAPI<$T2> for $T1 {
209 type Res = $Res;
210 const CAN_CAST_SELF: bool = $can_cast_self;
211 const CAN_CAST_OTHER: bool = $can_cast_other;
212 #[inline]
213 fn promote_self(self) -> Self::Res {
214 self as $Res
215 }
216 #[inline]
217 fn promote_other(val: $T2) -> Self::Res {
218 val as $Res
219 }
220 }
221
222 impl DTypeCastAPI<$T2> for $T1 {
223 #[inline]
224 fn into_cast(self) -> $T2 {
225 self as $T2
226 }
227 }
228 };
229}
230
231impl_promotion_asable!(i8, i32, false, true, i32);
233impl_promotion_asable!(i8, i64, false, true, i64);
234impl_promotion_asable!(i8, u8, false, false, i16);
235impl_promotion_asable!(i8, u16, false, false, i32);
236impl_promotion_asable!(i8, u32, false, false, i64);
237impl_promotion_asable!(i8, u64, false, false, f64);
238impl_promotion_asable!(i8, f32, false, true, f32);
239impl_promotion_asable!(i8, f64, false, true, f64);
240impl_promotion_asable!(i16, i8, true, false, i16);
241impl_promotion_asable!(i16, i32, false, true, i32);
242impl_promotion_asable!(i16, i64, false, true, i64);
243impl_promotion_asable!(i16, u8, true, false, i16);
244impl_promotion_asable!(i16, u16, false, false, i32);
245impl_promotion_asable!(i16, u32, false, false, i64);
246impl_promotion_asable!(i16, u64, false, false, f64);
247impl_promotion_asable!(i16, f32, false, true, f32);
248impl_promotion_asable!(i16, f64, false, true, f64);
249impl_promotion_asable!(i32, i8, true, false, i32);
250impl_promotion_asable!(i32, i16, true, false, i32);
251impl_promotion_asable!(i32, i64, false, true, i64);
252impl_promotion_asable!(i32, u8, true, false, i32);
253impl_promotion_asable!(i32, u16, true, false, i32);
254impl_promotion_asable!(i32, u32, false, false, i64);
255impl_promotion_asable!(i32, u64, false, false, f64);
256impl_promotion_asable!(i32, f32, false, false, f64);
257impl_promotion_asable!(i32, f64, false, true, f64);
258impl_promotion_asable!(i64, i8, true, false, i64);
259impl_promotion_asable!(i64, i16, true, false, i64);
260impl_promotion_asable!(i64, i32, true, false, i64);
261impl_promotion_asable!(i64, u8, true, false, i64);
262impl_promotion_asable!(i64, u16, true, false, i64);
263impl_promotion_asable!(i64, u32, true, false, i64);
264impl_promotion_asable!(i64, u64, false, false, f64);
265impl_promotion_asable!(i64, f32, false, false, f64);
266impl_promotion_asable!(i64, f64, false, true, f64);
267impl_promotion_asable!(u8, i8, false, false, i16);
268impl_promotion_asable!(u8, i16, false, true, i16);
269impl_promotion_asable!(u8, i32, false, true, i32);
270impl_promotion_asable!(u8, i64, false, true, i64);
271impl_promotion_asable!(u8, u16, false, true, u16);
272impl_promotion_asable!(u8, u32, false, true, u32);
273impl_promotion_asable!(u8, u64, false, true, u64);
274impl_promotion_asable!(u8, f32, false, true, f32);
275impl_promotion_asable!(u8, f64, false, true, f64);
276impl_promotion_asable!(u16, i8, false, false, i32);
277impl_promotion_asable!(u16, i16, false, false, i32);
278impl_promotion_asable!(u16, i32, false, true, i32);
279impl_promotion_asable!(u16, i64, false, true, i64);
280impl_promotion_asable!(u16, u8, true, false, u16);
281impl_promotion_asable!(u16, u32, false, true, u32);
282impl_promotion_asable!(u16, u64, false, true, u64);
283impl_promotion_asable!(u16, f32, false, true, f32);
284impl_promotion_asable!(u16, f64, false, true, f64);
285impl_promotion_asable!(u32, i8, false, false, i64);
286impl_promotion_asable!(u32, i16, false, false, i64);
287impl_promotion_asable!(u32, i32, false, false, i64);
288impl_promotion_asable!(u32, i64, false, true, i64);
289impl_promotion_asable!(u32, u8, true, false, u32);
290impl_promotion_asable!(u32, u16, true, false, u32);
291impl_promotion_asable!(u32, u64, false, true, u64);
292impl_promotion_asable!(u32, f32, false, false, f64);
293impl_promotion_asable!(u32, f64, false, true, f64);
294impl_promotion_asable!(u64, i8, false, false, f64);
295impl_promotion_asable!(u64, i16, false, false, f64);
296impl_promotion_asable!(u64, i32, false, false, f64);
297impl_promotion_asable!(u64, i64, false, false, f64);
298impl_promotion_asable!(u64, u8, true, false, u64);
299impl_promotion_asable!(u64, u16, true, false, u64);
300impl_promotion_asable!(u64, u32, true, false, u64);
301impl_promotion_asable!(u64, f32, false, false, f64);
302impl_promotion_asable!(u64, f64, false, true, f64);
303impl_promotion_asable!(f32, i8, true, false, f32);
304impl_promotion_asable!(f32, i16, true, false, f32);
305impl_promotion_asable!(f32, i32, false, false, f64);
306impl_promotion_asable!(f32, i64, false, false, f64);
307impl_promotion_asable!(f32, u8, true, false, f32);
308impl_promotion_asable!(f32, u16, true, false, f32);
309impl_promotion_asable!(f32, u32, false, false, f64);
310impl_promotion_asable!(f32, u64, false, false, f64);
311impl_promotion_asable!(f32, f64, false, true, f64);
312impl_promotion_asable!(f64, i8, true, false, f64);
313impl_promotion_asable!(f64, i16, true, false, f64);
314impl_promotion_asable!(f64, i32, true, false, f64);
315impl_promotion_asable!(f64, i64, true, false, f64);
316impl_promotion_asable!(f64, u8, true, false, f64);
317impl_promotion_asable!(f64, u16, true, false, f64);
318impl_promotion_asable!(f64, u32, true, false, f64);
319impl_promotion_asable!(f64, u64, true, false, f64);
320impl_promotion_asable!(f64, f32, true, false, f64);
321
322impl_promotion_asable!(isize, i8, true, false, isize);
324impl_promotion_asable!(isize, i16, true, false, isize);
325impl_promotion_asable!(isize, i32, true, false, isize);
326impl_promotion_asable!(isize, i64, true, true, isize);
327impl_promotion_asable!(isize, u8, true, false, isize);
328impl_promotion_asable!(isize, u16, true, false, isize);
329impl_promotion_asable!(isize, u32, true, false, isize);
330impl_promotion_asable!(isize, u64, false, false, f64);
331impl_promotion_asable!(isize, f32, false, false, f64);
332impl_promotion_asable!(isize, f64, false, true, f64);
333impl_promotion_asable!(i8, isize, false, true, isize);
334impl_promotion_asable!(i16, isize, false, true, isize);
335impl_promotion_asable!(i32, isize, false, true, isize);
336impl_promotion_asable!(i64, isize, true, true, isize);
337impl_promotion_asable!(u8, isize, false, true, isize);
338impl_promotion_asable!(u16, isize, false, true, isize);
339impl_promotion_asable!(u32, isize, false, true, isize);
340impl_promotion_asable!(u64, isize, false, false, f64);
341impl_promotion_asable!(f32, isize, false, false, f64);
342impl_promotion_asable!(f64, isize, true, false, f64);
343
344impl_promotion_asable!(usize, i8, false, false, f64);
346impl_promotion_asable!(usize, i16, false, false, f64);
347impl_promotion_asable!(usize, i32, false, false, f64);
348impl_promotion_asable!(usize, i64, false, false, f64);
349impl_promotion_asable!(usize, u8, true, false, usize);
350impl_promotion_asable!(usize, u16, true, false, usize);
351impl_promotion_asable!(usize, u32, true, false, usize);
352impl_promotion_asable!(usize, u64, true, true, usize);
353impl_promotion_asable!(usize, f32, false, false, f64);
354impl_promotion_asable!(usize, f64, false, true, f64);
355impl_promotion_asable!(i8, usize, false, false, f64);
356impl_promotion_asable!(i16, usize, false, false, f64);
357impl_promotion_asable!(i32, usize, false, false, f64);
358impl_promotion_asable!(i64, usize, false, false, f64);
359impl_promotion_asable!(u8, usize, false, true, usize);
360impl_promotion_asable!(u16, usize, false, true, usize);
361impl_promotion_asable!(u32, usize, false, true, usize);
362impl_promotion_asable!(u64, usize, true, true, usize);
363impl_promotion_asable!(f32, usize, false, false, f64);
364impl_promotion_asable!(f64, usize, true, false, f64);
365
366macro_rules! impl_promotion_complex_primitive_cast_self {
371 ($TComp:ty, $TPrim:ty, $can_cast_self:ident, $can_cast_other:ident, $ResComp:ty) => {
372 impl DTypePromoteAPI<$TPrim> for Complex<$TComp> {
373 type Res = Complex<$ResComp>;
374 const CAN_CAST_SELF: bool = $can_cast_self;
375 const CAN_CAST_OTHER: bool = $can_cast_other;
376 #[inline]
377 fn promote_self(self) -> Self::Res {
378 self
379 }
380 #[inline]
381 fn promote_other(val: $TPrim) -> Self::Res {
382 Self::Res::new(val as _, 0 as _)
383 }
384 }
385 };
386}
387
388macro_rules! impl_promotion_complex_primitive_no_cast_self {
389 ($TComp:ty, $TPrim:ty, $can_cast_self:ident, $can_cast_other:ident, $ResComp:ty) => {
390 impl DTypePromoteAPI<$TPrim> for Complex<$TComp> {
391 type Res = Complex<$ResComp>;
392 const CAN_CAST_SELF: bool = $can_cast_self;
393 const CAN_CAST_OTHER: bool = $can_cast_other;
394 #[inline]
395 fn promote_self(self) -> Self::Res {
396 Self::Res::new(self.re as _, self.im as _)
397 }
398 #[inline]
399 fn promote_other(val: $TPrim) -> Self::Res {
400 Self::Res::new(val as _, 0 as _)
401 }
402 }
403 };
404}
405
406impl_promotion_complex_primitive_cast_self!(f32, i8, true, false, f32);
407impl_promotion_complex_primitive_cast_self!(f32, i16, true, false, f32);
408impl_promotion_complex_primitive_cast_self!(f32, u8, true, false, f32);
409impl_promotion_complex_primitive_cast_self!(f32, u16, true, false, f32);
410impl_promotion_complex_primitive_cast_self!(f32, f32, true, false, f32);
411
412impl_promotion_complex_primitive_cast_self!(f64, i8, true, false, f64);
413impl_promotion_complex_primitive_cast_self!(f64, i16, true, false, f64);
414impl_promotion_complex_primitive_cast_self!(f64, i32, true, false, f64);
415impl_promotion_complex_primitive_cast_self!(f64, i64, true, false, f64);
416impl_promotion_complex_primitive_cast_self!(f64, isize, true, false, f64);
417impl_promotion_complex_primitive_cast_self!(f64, u8, true, false, f64);
418impl_promotion_complex_primitive_cast_self!(f64, u16, true, false, f64);
419impl_promotion_complex_primitive_cast_self!(f64, u32, true, false, f64);
420impl_promotion_complex_primitive_cast_self!(f64, u64, true, false, f64);
421impl_promotion_complex_primitive_cast_self!(f64, usize, true, false, f64);
422impl_promotion_complex_primitive_cast_self!(f64, f32, true, false, f64);
423impl_promotion_complex_primitive_cast_self!(f64, f64, true, false, f64);
424
425impl_promotion_complex_primitive_no_cast_self!(f32, i32, false, false, f64);
426impl_promotion_complex_primitive_no_cast_self!(f32, i64, false, false, f64);
427impl_promotion_complex_primitive_no_cast_self!(f32, isize, false, false, f64);
428impl_promotion_complex_primitive_no_cast_self!(f32, u32, false, false, f64);
429impl_promotion_complex_primitive_no_cast_self!(f32, u64, false, false, f64);
430impl_promotion_complex_primitive_no_cast_self!(f32, usize, false, false, f64);
431impl_promotion_complex_primitive_no_cast_self!(f32, f64, false, false, f64);
432
433macro_rules! impl_promotion_primitive_complex_cast_other {
438 ($TComp:ty, $TPrim:ty, $can_cast_self:ident, $can_cast_other:ident, $ResComp:ty) => {
439 impl DTypePromoteAPI<Complex<$TComp>> for $TPrim {
440 type Res = Complex<$ResComp>;
441 const CAN_CAST_SELF: bool = $can_cast_self;
442 const CAN_CAST_OTHER: bool = $can_cast_other;
443 #[inline]
444 fn promote_self(self) -> Self::Res {
445 Self::Res::new(self as _, 0 as _)
446 }
447 #[inline]
448 fn promote_other(val: Complex<$TComp>) -> Self::Res {
449 val
450 }
451 }
452
453 impl DTypeCastAPI<Complex<$TComp>> for $TPrim {
454 #[inline]
455 fn into_cast(self) -> Complex<$TComp> {
456 Complex::<$TComp>::new(self as _, 0 as _)
457 }
458 }
459 };
460}
461
462macro_rules! impl_promotion_primitive_complex_nocast_other {
463 ($TComp:ty, $TPrim:ty, $can_cast_self:ident, $can_cast_other:ident, $ResComp:ty) => {
464 impl DTypePromoteAPI<Complex<$TComp>> for $TPrim {
465 type Res = Complex<$ResComp>;
466 const CAN_CAST_SELF: bool = $can_cast_self;
467 const CAN_CAST_OTHER: bool = $can_cast_other;
468 #[inline]
469 fn promote_self(self) -> Self::Res {
470 Self::Res::new(self as _, 0 as _)
471 }
472 #[inline]
473 fn promote_other(val: Complex<$TComp>) -> Self::Res {
474 Self::Res::new(val.re as _, val.im as _)
475 }
476 }
477
478 impl DTypeCastAPI<Complex<$TComp>> for $TPrim {
479 #[inline]
480 fn into_cast(self) -> Complex<$TComp> {
481 Complex::<$TComp>::new(self as _, 0 as _)
482 }
483 }
484 };
485}
486
487impl_promotion_primitive_complex_cast_other!(f32, i8, false, true, f32);
488impl_promotion_primitive_complex_cast_other!(f32, i16, false, true, f32);
489impl_promotion_primitive_complex_cast_other!(f32, u8, false, true, f32);
490impl_promotion_primitive_complex_cast_other!(f32, u16, false, true, f32);
491impl_promotion_primitive_complex_cast_other!(f32, f32, false, true, f32);
492
493impl_promotion_primitive_complex_nocast_other!(f64, i8, false, true, f64);
494impl_promotion_primitive_complex_nocast_other!(f64, i16, false, true, f64);
495impl_promotion_primitive_complex_nocast_other!(f64, i32, false, true, f64);
496impl_promotion_primitive_complex_nocast_other!(f64, i64, false, true, f64);
497impl_promotion_primitive_complex_nocast_other!(f64, isize, false, true, f64);
498impl_promotion_primitive_complex_nocast_other!(f64, u8, false, true, f64);
499impl_promotion_primitive_complex_nocast_other!(f64, u16, false, true, f64);
500impl_promotion_primitive_complex_nocast_other!(f64, u32, false, true, f64);
501impl_promotion_primitive_complex_nocast_other!(f64, u64, false, true, f64);
502impl_promotion_primitive_complex_nocast_other!(f64, usize, false, true, f64);
503impl_promotion_primitive_complex_nocast_other!(f64, f32, false, true, f64);
504impl_promotion_primitive_complex_nocast_other!(f64, f64, false, true, f64);
505
506impl_promotion_primitive_complex_nocast_other!(f32, i32, false, false, f64);
507impl_promotion_primitive_complex_nocast_other!(f32, i64, false, false, f64);
508impl_promotion_primitive_complex_nocast_other!(f32, isize, false, false, f64);
509impl_promotion_primitive_complex_nocast_other!(f32, u32, false, false, f64);
510impl_promotion_primitive_complex_nocast_other!(f32, u64, false, false, f64);
511impl_promotion_primitive_complex_nocast_other!(f32, usize, false, false, f64);
512impl_promotion_primitive_complex_nocast_other!(f32, f64, false, false, f64);
513
514impl DTypePromoteAPI<c32> for c64 {
519 type Res = c64;
520 const CAN_CAST_SELF: bool = true;
521 const CAN_CAST_OTHER: bool = false;
522 #[inline]
523 fn promote_self(self) -> Self::Res {
524 self
525 }
526 #[inline]
527 fn promote_other(val: c32) -> Self::Res {
528 c64::new(val.re as f64, val.im as f64)
529 }
530}
531
532impl DTypePromoteAPI<c64> for c32 {
533 type Res = c64;
534 const CAN_CAST_SELF: bool = false;
535 const CAN_CAST_OTHER: bool = true;
536 #[inline]
537 fn promote_self(self) -> Self::Res {
538 c64::new(self.re as f64, self.im as f64)
539 }
540 #[inline]
541 fn promote_other(val: c64) -> Self::Res {
542 val
543 }
544}
545
546impl DTypeCastAPI<c32> for c64 {
547 #[inline]
548 fn into_cast(self) -> c32 {
549 c32::new(self.re as f32, self.im as f32)
550 }
551}
552
553impl DTypeCastAPI<c64> for c32 {
554 #[inline]
555 fn into_cast(self) -> c64 {
556 c64::new(self.re as f64, self.im as f64)
557 }
558}
559
560