diff --git a/src/internal_type_traits.rs b/src/internal_type_traits.rs index 8b13789..b4f060f 100644 --- a/src/internal_type_traits.rs +++ b/src/internal_type_traits.rs @@ -1 +1,90 @@ +use std::{ + fmt, + iter::{Product, Sum}, + ops::{ + Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, + DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, + SubAssign, + }, +}; +// Skipped: +// +// - `is_signed_int_t` (probably won't be used directly in `modint.rs`) +// - `is_unsigned_int_t` (probably won't be used directly in `modint.rs`) +// - `to_unsigned_t` (not used in `fenwicktree.rs`) + +/// Corresponds to `std::is_integral` in C++. +// We will remove unnecessary bounds later. +// +// Maybe we should rename this to `PrimitiveInteger` or something, as it probably won't be used in the +// same way as the original ACL. +pub(crate) trait Integral: + 'static + + Send + + Sync + + Copy + + Ord + + Not + + Add + + Sub + + Mul + + Div + + Rem + + AddAssign + + SubAssign + + MulAssign + + DivAssign + + RemAssign + + Sum + + Product + + BitOr + + BitAnd + + BitXor + + BitOrAssign + + BitAndAssign + + BitXorAssign + + Shl + + Shr + + ShlAssign + + ShrAssign + + fmt::Display + + fmt::Debug + + fmt::Binary + + fmt::Octal +{ + fn zero() -> Self; + fn one() -> Self; + fn min_value() -> Self; + fn max_value() -> Self; +} + +macro_rules! impl_integral { + ($($ty:ty),*) => { + $( + impl Integral for $ty { + #[inline] + fn zero() -> Self { + 0 + } + + #[inline] + fn one() -> Self { + 1 + } + + #[inline] + fn min_value() -> Self { + Self::min_value() + } + + #[inline] + fn max_value() -> Self { + Self::max_value() + } + } + )* + }; +} + +impl_integral!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize);