aoc/util/
integer.rs

1//! Combines common [operators](https://doc.rust-lang.org/book/appendix-02-operators.html)
2//! and constants `0`, `1` and `10` to enable generic methods on integer types.
3use std::ops::*;
4
5pub trait Integer<T>:
6    Copy
7    + From<u8>
8    + PartialEq
9    + PartialOrd
10    + Add<Output = T>
11    + BitAnd<Output = T>
12    + BitOr<Output = T>
13    + BitXor<Output = T>
14    + Div<Output = T>
15    + Mul<Output = T>
16    + Rem<Output = T>
17    + Shl<Output = T>
18    + Shr<Output = T>
19    + Sub<Output = T>
20{
21    const ZERO: T;
22    const ONE: T;
23    const TEN: T;
24
25    fn trailing_zeros(self) -> T;
26}
27
28pub trait Unsigned<T>: Integer<T> {}
29
30pub trait Signed<T>: Integer<T> + Neg<Output = T> {}
31
32macro_rules! integer {
33    ($($t:ty)*) => ($(
34        impl Integer<$t> for $t {
35            const ZERO: $t = 0;
36            const ONE: $t = 1;
37            const TEN: $t = 10;
38
39            #[inline]
40            #[allow(trivial_numeric_casts)]
41            fn trailing_zeros(self) -> $t {
42                <$t>::trailing_zeros(self) as $t
43            }
44        }
45    )*)
46}
47
48macro_rules! empty_trait {
49    ($name:ident for $($t:ty)*) => ($(
50        impl $name<$t> for $t {}
51    )*)
52}
53
54integer!(u8 u16 u32 u64 u128 usize i16 i32 i64 i128);
55empty_trait!(Unsigned for u8 u16 u32 u64 u128 usize);
56empty_trait!(Signed for i16 i32 i64 i128);