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<u32, Output = T>
18    + Shr<u32, 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) -> u32;
26    fn minmax(self, other: T) -> (T, T);
27}
28
29pub trait Unsigned<T>: Integer<T> {}
30
31pub trait Signed<T>: Integer<T> + Neg<Output = T> {}
32
33macro_rules! integer {
34    ($($t:ty)*) => ($(
35        impl Integer<$t> for $t {
36            const ZERO: $t = 0;
37            const ONE: $t = 1;
38            const TEN: $t = 10;
39
40            #[inline]
41            fn trailing_zeros(self) -> u32 {
42                <$t>::trailing_zeros(self)
43            }
44
45            #[inline]
46            fn minmax(self, other: $t) -> ($t, $t) {
47                if self < other { (self, other) } else { (other, self) }
48            }
49        }
50    )*)
51}
52
53macro_rules! empty_trait {
54    ($name:ident for $($t:ty)*) => ($(
55        impl $name<$t> for $t {}
56    )*)
57}
58
59integer!(u8 u16 u32 u64 u128 usize i16 i32 i64 i128);
60empty_trait!(Unsigned for u8 u16 u32 u64 u128 usize);
61empty_trait!(Signed for i16 i32 i64 i128);