1use core::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Rem, Shl, Shr, Sub};
25
26use num_traits::{Float, One, Zero};
27
28use crate::basenum::{ApproxEq, BaseFloat, BaseInt, BaseNum, SignedNum};
29
30pub trait GenNum<E: BaseNum>:
34 Copy
35 + Sized
36 + Clone
37 + One
38 + Zero
39 + Div<Self, Output = Self>
40 + Rem<Self, Output = Self>
41 + Add<E, Output = Self>
42 + Mul<E, Output = Self>
43{
44 fn from_s(x: E) -> Self;
46
47 fn map<F>(self, f: F) -> Self
48 where
49 F: Fn(E) -> E;
50
51 fn zip<F>(self, y: Self, f: F) -> Self
52 where
53 F: Fn(E, E) -> E;
54
55 fn split<F>(self, f: F) -> (Self, Self)
56 where
57 F: Fn(E) -> (E, E);
58
59 fn map2<F>(self, y: Self, f: F) -> (Self, Self)
60 where
61 F: Fn(E, E) -> (E, E);
62}
63
64macro_rules! impl_GenNum_for_scalar(
65 ($t: ty) => {
66 impl GenNum<$t> for $t {
67 #[inline(always)]
68 fn from_s(x: $t) -> Self {
69 x
70 }
71 #[inline(always)]
72 fn map<F: Fn($t) -> $t>(self, f: F) -> $t {
73 f(self)
74 }
75 #[inline(always)]
76 fn zip<F: Fn($t, $t) -> $t>(self, y: $t, f: F) -> $t {
77 f(self, y)
78 }
79 #[inline(always)]
80 fn split<F: Fn($t) -> ($t, $t)>(self, f: F) -> ($t, $t) {
81 f(self)
82 }
83 #[inline(always)]
84 fn map2<F: Fn($t, $t) -> ($t, $t)>(self, y: $t, f: F) -> ($t, $t) {
85 f(self, y)
86 }
87 }
88 }
89);
90
91pub trait GenInt<I: BaseInt>:
93 GenNum<I>
94 + Eq
95 + Not<Output = Self>
96 + BitAnd<Output = Self>
97 + BitOr<Output = Self>
98 + BitXor<Output = Self>
99 + Shl<usize, Output = Self>
100 + Shr<usize, Output = Self>
101{
102}
103
104pub trait GenIType: GenInt<i32> + SignedNum + Sub<i32, Output = Self> {}
110
111impl_GenNum_for_scalar! { i32 }
112impl GenInt<i32> for i32 {}
113impl GenIType for i32 {}
114
115pub trait GenUType: GenInt<u32> {}
121
122impl_GenNum_for_scalar! { u32 }
123impl GenInt<u32> for u32 {}
124impl GenUType for u32 {}
125
126pub trait GenFloat<F: BaseFloat>:
128 GenNum<F> + ApproxEq<BaseType = F> + SignedNum + Sub<F, Output = Self>
129{
130 fn fma(&self, b: &Self, c: &Self) -> Self;
132}
133
134pub trait GenType: GenFloat<f32> {}
135pub trait GenDType: GenFloat<f64> {}
136
137macro_rules! impl_GenFloat_for_scalar(
138 ($t: ty, $gt: path) => {
139 impl_GenNum_for_scalar! { $t }
140 impl GenFloat<$t> for $t {
141 fn fma(&self, b: &$t, c: &$t) -> $t {
142 Float::mul_add(*self, *b, *c)
143 }
144 }
145 impl $gt for $t {}
146 }
147);
148
149impl_GenFloat_for_scalar! { f32, GenType }
150impl_GenFloat_for_scalar! { f64, GenDType }
151
152pub trait GenBType: Eq {}
154
155impl GenBType for bool {}