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
use std::fmt::Debug; use std::ops::*; pub trait Scalar: Copy + Debug + PartialEq + PartialOrd {} impl<S: Copy + Debug + PartialEq + PartialOrd> Scalar for S {} pub trait Number: Scalar + Add<Output=Self> + AddAssign + Sub<Output=Self> + SubAssign + Mul<Output=Self> + MulAssign + Div<Output=Self> + DivAssign { const ZERO: Self; const ONE: Self; const TWO: Self; } macro_rules! impl_number { ($ty: ty, $zero: tt, $one: tt) => { impl Number for $ty { const ZERO: Self = $zero; const ONE: Self = $one; const TWO: Self = $one + $one; } } } impl_number!(i8, 0, 1); impl_number!(u8, 0, 1); impl_number!(i16, 0, 1); impl_number!(u16, 0, 1); impl_number!(i32, 0, 1); impl_number!(u32, 0, 1); impl_number!(i64, 0, 1); impl_number!(u64, 0, 1); impl_number!(i128, 0, 1); impl_number!(u128, 0, 1); impl_number!(isize, 0, 1); impl_number!(usize, 0, 1); impl_number!(f32, 0.0, 1.0); impl_number!(f64, 0.0, 1.0); pub trait Signed: Number + Neg<Output=Self> { fn abs(self) -> Self; } macro_rules! impl_signed { ($ty: ty) => { impl Signed for $ty { #[inline(always)] fn abs(self) -> Self { Self::abs(self) } } }; } impl_signed!(i8); impl_signed!(i32); impl_signed!(i64); impl_signed!(i128); impl_signed!(isize); impl_signed!(f32); impl_signed!(f64); pub trait Float: Signed { fn of(value: f64) -> Self; fn sqrt(self) -> Self; fn sin(self) -> Self; fn cos(self) -> Self; fn tan(self) -> Self; fn powi(self, pow: i32) -> Self; } macro_rules! impl_float { ($ty: ty) => { impl Float for $ty { #[inline(always)] fn of(value: f64) -> Self { value as Self } #[inline(always)] fn sqrt(self) -> Self { Self::sqrt(self) } #[inline(always)] fn sin(self) -> Self { Self::sin(self) } #[inline(always)] fn cos(self) -> Self { Self::cos(self) } #[inline(always)] fn tan(self) -> Self { Self::tan(self) } #[inline(always)] fn powi(self, pow: i32) -> Self { Self::powi(self, pow) } } }; } impl_float!(f32); impl_float!(f64);