1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
use core::hash::Hash; use core::ops::{ Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign, Rem, RemAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Shl, ShlAssign, Shr, ShrAssign, Neg, Not, }; pub trait Float : Copy + Default + Sized + Add + AddAssign + Div + DivAssign + Mul + MulAssign + Rem + RemAssign + Sub + SubAssign { const WIDTH: usize; } pub trait Integer : Copy + Default + Eq + Hash + Ord + Sized + Not<Output=Self> + Add<Self, Output=Self> + AddAssign<Self> + Div<Self, Output=Self> + DivAssign<Self> + Mul<Self, Output=Self> + MulAssign<Self> + Sub<Self, Output=Self> + SubAssign<Self> + Rem<Self, Output=Self> + RemAssign<Self> + BitAnd<Self, Output=Self> + BitAndAssign<Self> + BitOr<Self, Output=Self> + BitOrAssign<Self> + BitXor<Self, Output=Self> + BitXorAssign<Self> + Shl<Self, Output=Self> + ShlAssign<Self> + Shr<Self, Output=Self> + ShrAssign<Self> { const MIN: Self; const MAX: Self; const ZERO: Self; const ONE: Self; const WIDTH: usize; } pub trait Signed : Neg {} pub trait Unsigned {} pub trait AddSign : Integer + Unsigned { type Signed : DropSign<Unsigned=Self>; fn add_sign(self) -> <Self as AddSign>::Signed; } pub trait DropSign : Integer + Signed { type Unsigned : AddSign<Signed=Self>; fn drop_sign(self) -> <Self as DropSign>::Unsigned; } pub trait ArithmeticShr : Integer + Signed {} pub trait LogicalShr : Integer + Unsigned {} impl<T: Integer + Signed> ArithmeticShr for T {} impl<T: Integer + Unsigned> LogicalShr for T {} impl Signed for f32 {} impl Signed for f64 {} impl Signed for i8 {} impl Signed for i16 {} impl Signed for i32 {} impl Signed for i64 {} impl Signed for i128 {} impl Signed for isize {} impl Unsigned for u8 {} impl Unsigned for u16 {} impl Unsigned for u32 {} impl Unsigned for u64 {} impl Unsigned for u128 {} impl Unsigned for usize {} macro_rules! impl_float { ($type:ty = $size:expr) => { impl Float for $type { const WIDTH: usize = $size; } } } macro_rules! impl_integer { ($type:ty = $size:expr) => { impl Integer for $type { const MAX: $type = <$type>::MAX; const MIN: $type = <$type>::MIN; const ZERO: $type = 0; const ONE: $type = 1; const WIDTH: usize = $size; } } } macro_rules! impl_add_sign { ($type:ty = $signed:ty) => { impl AddSign for $type { type Signed = $signed; fn add_sign(self) -> $signed { self as $signed } } } } macro_rules! impl_drop_sign { ($type:ty = $unsigned:ty) => { impl DropSign for $type { type Unsigned = $unsigned; fn drop_sign(self) -> $unsigned { self as $unsigned } } } } impl_float!(f32 = 32); impl_float!(f64 = 64); impl_integer!(i8 = 8); impl_integer!(i16 = 16); impl_integer!(i32 = 32); impl_integer!(i64 = 64); impl_integer!(i128 = 128); #[cfg(target_pointer_width="32")] impl_integer!(isize = 32); #[cfg(target_pointer_width="64")] impl_integer!(isize = 64); impl_integer!(u8 = 8); impl_integer!(u16 = 16); impl_integer!(u32 = 32); impl_integer!(u64 = 32); impl_integer!(u128 = 128); #[cfg(target_pointer_width="32")] impl_integer!(usize = 32); #[cfg(target_pointer_width="64")] impl_integer!(usize = 64); impl_add_sign!(u8 = i8); impl_add_sign!(u16 = i16); impl_add_sign!(u32 = i32); impl_add_sign!(u64 = i64); impl_add_sign!(u128 = i128); impl_add_sign!(usize = isize); impl_drop_sign!(i8 = u8); impl_drop_sign!(i16 = u16); impl_drop_sign!(i32 = u32); impl_drop_sign!(i64 = u64); impl_drop_sign!(i128 = u128); impl_drop_sign!(isize = usize);