irox_types/
num.rs

1// SPDX-License-Identifier: MIT
2// Copyright 2024 IROX Contributors
3//
4
5//!
6//! Number Traits
7
8/// A number, signed or unsigned, floating point or integer, any size.
9pub trait Number:
10    core::marker::Sized
11    + core::marker::Copy
12    + core::marker::Send
13    + core::clone::Clone
14    + core::default::Default
15    + core::fmt::Display
16    + core::fmt::Debug
17    + core::fmt::LowerExp
18    + core::fmt::UpperExp
19    + core::ops::Add
20    + core::ops::Sub
21    + core::ops::Mul
22    + core::ops::Div
23    + core::ops::Rem
24    + core::str::FromStr
25    + core::cmp::PartialEq
26    + core::cmp::PartialOrd
27{
28}
29/// A mutable number
30pub trait NumberMut:
31    Number
32    + core::ops::AddAssign
33    + core::ops::SubAssign
34    + core::ops::MulAssign
35    + core::ops::DivAssign
36    + core::ops::RemAssign
37{
38}
39
40/// A number that can have bitwise-operations performed on it (IE, not floating point)
41pub trait NumberBits:
42    Number
43    + core::fmt::Binary
44    + core::fmt::LowerHex
45    + core::fmt::UpperHex
46    + core::fmt::Octal
47    + core::ops::BitAnd
48    + core::ops::BitOr
49    + core::ops::BitXor
50    + core::ops::Not
51    + core::ops::Shl
52    + core::ops::Shr
53    + core::hash::Hash
54{
55}
56// A mutable bitwise-number (not floating point)
57pub trait NumberBitsMut:
58    NumberMut
59    + NumberBits
60    + core::fmt::Binary
61    + core::fmt::LowerHex
62    + core::fmt::UpperHex
63    + core::fmt::Octal
64    + core::ops::BitAndAssign
65    + core::ops::BitOrAssign
66    + core::ops::BitXorAssign
67    + core::ops::ShlAssign
68    + core::ops::ShrAssign
69{
70}
71/// An exact number (not floating point)
72pub trait NumberExact: Number + core::cmp::Eq + core::cmp::Ord + core::hash::Hash {}
73/// A floating point number
74pub trait NumberFloating: Number + core::fmt::LowerExp + core::fmt::UpperExp {}
75
76/// A signed number
77pub trait NumberSigned: Number + core::ops::Neg {}
78/// Any unsigned integer
79pub trait AnyUnsignedInteger:
80    Number + NumberMut + NumberBits + NumberBitsMut + NumberExact
81{
82    fn as_u8(&self) -> u8;
83    fn as_u16(&self) -> u16;
84    fn as_u32(&self) -> u32;
85    fn as_u64(&self) -> u64;
86    fn as_u128(&self) -> u128;
87}
88pub trait AnySignedInteger: AnyUnsignedInteger + NumberSigned {}
89pub trait AnyFloat:
90    Number + NumberMut + NumberFloating + NumberSigned + irox_tools::f64::FloatExt
91{
92}
93macro_rules! impl_exact {
94    ($($typ:ty) *) => {
95        $(
96            impl<'a> Number for $typ {}
97            impl<'a> NumberMut for $typ {}
98            impl<'a> NumberBits for $typ {}
99            impl<'a> NumberBitsMut for $typ {}
100            impl<'a> NumberExact for $typ {}
101            impl<'a> AnyUnsignedInteger for $typ {
102                fn as_u8(&self) -> u8 {
103                    *self as u8
104                }
105                fn as_u16(&self) -> u16 {
106                    *self as u16
107                }
108                fn as_u32(&self) -> u32 {
109                    *self as u32
110                }
111                fn as_u64(&self) -> u64 {
112                    *self as u64
113                }
114                fn as_u128(&self) -> u128 {
115                    *self as u128
116                }
117            }
118        )*
119    };
120}
121macro_rules! impl_float {
122    ($($typ:ty) *) => {
123        $(
124            impl<'a> Number for $typ {}
125            impl<'a> NumberMut for $typ {}
126            impl<'a> NumberSigned for $typ {}
127            impl<'a> NumberFloating for $typ {}
128            impl<'a> AnyFloat for $typ {}
129        )*
130    };
131}
132macro_rules! impl_signed {
133    ($($typ:ty) *) => {
134        $(
135            impl<'a> NumberSigned for $typ {}
136            impl<'a> AnySignedInteger for $typ {}
137        )*
138    };
139}
140
141impl_float!(f64 f32);
142impl_exact!(u128 u64 u32 u16 u8 usize isize i8 i16 i32 i64 i128);
143impl_signed!(i8 i16 i32 i64 i128 isize);