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