1use core::ops::{Add, Div, Mul, Neg, Sub};
2use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
3
4pub trait Operations<Rhs = Self, Output = Self>:
5 Add<Rhs, Output = Output>
6 + Sub<Rhs, Output = Output>
7 + Mul<Rhs, Output = Output>
8 + Div<Rhs, Output = Output>
9{
10}
11
12impl<T, Rhs, Output> Operations<Rhs, Output> for T where
13 T: Add<Rhs, Output = Output>
14 + Sub<Rhs, Output = Output>
15 + Mul<Rhs, Output = Output>
16 + Div<Rhs, Output = Output>
17{
18}
19
20pub trait AssignOperations<Rhs = Self>:
21 AddAssign<Rhs>
22 + SubAssign<Rhs>
23 + MulAssign<Rhs>
24 + DivAssign<Rhs>
25{
26}
27
28impl<T, Rhs> AssignOperations<Rhs> for T where
29 T: AddAssign<Rhs>
30 + SubAssign<Rhs>
31 + MulAssign<Rhs>
32 + DivAssign<Rhs>
33{
34}
35
36pub trait Zero: Sized + Add<Self, Output = Self> {
37 fn zero() -> Self;
39}
40
41pub trait One: Sized + Mul<Self, Output = Self> {
42 fn one() -> Self;
44}
45
46
47pub trait Number: PartialEq + Sized + Operations + AssignOperations + Zero + One
48{
49
50}
51
52pub trait Signed: Number + Neg<Output = Self> {
53 fn abs(&self) -> Self;
54}
55
56macro_rules! impl_identity {
57 ($name: ident for $($t: ty)*, $method: ident, $v: expr) => ($(
58 impl $name for $t {
59 #[inline]
60 fn $method() -> $t {
61 $v
62 }
63 }
64 )*)
65}
66
67impl_identity!( Zero for f32 f64, zero, 0.0 );
68impl_identity!( One for f32 f64, one, 1.0 );
69impl_identity!( Zero for usize u8 u16 u32 u64 isize i8 i16 i32 i64, zero, 0 );
70impl_identity!( One for usize u8 u16 u32 u64 isize i8 i16 i32 i64, one, 1 );
71
72macro_rules! impl_signed {
73 ($($t:ty)*, $v: expr) => ($(
74 impl Signed for $t {
75 #[inline]
76 fn abs(&self) -> $t {
77 if *self < $v { -*self } else { *self }
78 }
79 }
80 )*)
81}
82
83impl_signed!( isize i8 i16 i32 i64, 0 );
84impl_signed!( f32 f64, 0.0 );
85
86macro_rules! impl_trait {
87 ($name: ident for $($t: ty)*) => ($(
88 impl $name for $t {
89
90 }
91 )*)
92}
93
94impl_trait!( Number for usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64);