batbox_num/
lib.rs

1//! Numeric types and traits
2#![warn(missing_docs)]
3
4mod float;
5mod real;
6
7pub use float::*;
8pub use real::*;
9
10/// Generic number, possibly unsigned
11pub trait UNum:
12    Sized
13    + Copy
14    + std::fmt::Debug
15    + std::fmt::Display
16    + std::ops::Add<Output = Self>
17    + std::ops::AddAssign
18    + std::ops::Sub<Output = Self>
19    + std::ops::SubAssign
20    + std::ops::Mul<Output = Self>
21    + std::ops::MulAssign
22    + std::ops::Div<Output = Self>
23    + std::ops::DivAssign
24    + PartialEq
25    + PartialOrd
26    + ::rand::distributions::uniform::SampleUniform
27{
28    /// Additive identity
29    const ZERO: Self;
30
31    /// Multiplicative identity
32    const ONE: Self;
33
34    /// Calculate squared value (`self * self`)
35    fn sqr(self) -> Self {
36        self * self
37    }
38}
39
40/// Generic signed number type
41pub trait Num: UNum + std::ops::Neg<Output = Self> {
42    /// Returns a number representing sign of `self`.
43    fn signum(self) -> Self;
44
45    /// Calculate absolute value
46    fn abs(self) -> Self {
47        if self >= Self::ZERO {
48            self
49        } else {
50            -self
51        }
52    }
53}
54
55macro_rules! impl_int {
56    ($($t:ty),*) => {
57        $(
58            impl UNum for $t {
59                const ZERO: Self = 0;
60                const ONE: Self = 1;
61            }
62        )*
63    };
64}
65
66macro_rules! impl_signed_int {
67    ($($t:ty),*) => {
68        $(
69            impl_int!($t);
70
71            impl Num for $t {
72                fn signum(self) -> Self {
73                    match self {
74                        _ if self > 0 => 1,
75                        0 => 0,
76                        _ => -1,
77                    }
78                }
79            }
80        )*
81    }
82}
83
84impl_int! { u8, u16, u32, u64, usize }
85impl_signed_int! { i8, i16, i32, i64, isize }