diff --git a/src/internal_type_traits.rs b/src/internal_type_traits.rs index 88a52a9..4405c9b 100644 --- a/src/internal_type_traits.rs +++ b/src/internal_type_traits.rs @@ -1,6 +1,6 @@ use std::{ fmt, - iter::{Product, Sum}, + iter::{self, Product, Sum}, ops::{ Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, @@ -52,25 +52,33 @@ pub trait Integral: + fmt::Debug + fmt::Binary + fmt::Octal - + Zero - + One + BoundedBelow + BoundedAbove { } /// Class that has additive identity element -pub trait Zero { +pub(super) trait SumExt: Sum { /// The additive identity element - fn zero() -> Self; + #[inline] + fn zero() -> Self { + iter::empty().sum() + } } +impl SumExt for T {} + /// Class that has multiplicative identity element -pub trait One { +pub(super) trait ProductExt: Product { /// The multiplicative identity element - fn one() -> Self; + #[inline] + fn one() -> Self { + iter::empty().product() + } } +impl ProductExt for T {} + pub trait BoundedBelow { fn min_value() -> Self; } @@ -82,20 +90,6 @@ pub trait BoundedAbove { macro_rules! impl_integral { ($($ty:ty),*) => { $( - impl Zero for $ty { - #[inline] - fn zero() -> Self { - 0 - } - } - - impl One for $ty { - #[inline] - fn one() -> Self { - 1 - } - } - impl BoundedBelow for $ty { #[inline] fn min_value() -> Self { @@ -116,3 +110,40 @@ macro_rules! impl_integral { } impl_integral!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize); + +#[cfg(test)] +mod tests { + use super::{ProductExt as _, SumExt as _}; + + #[test] + fn zero() { + assert_eq!(0, i8::zero()); + assert_eq!(0, i16::zero()); + assert_eq!(0, i32::zero()); + assert_eq!(0, i64::zero()); + assert_eq!(0, i128::zero()); + assert_eq!(0, isize::zero()); + assert_eq!(0, u8::zero()); + assert_eq!(0, u16::zero()); + assert_eq!(0, u32::zero()); + assert_eq!(0, u64::zero()); + assert_eq!(0, u128::zero()); + assert_eq!(0, usize::zero()); + } + + #[test] + fn one() { + assert_eq!(1, i8::one()); + assert_eq!(1, i16::one()); + assert_eq!(1, i32::one()); + assert_eq!(1, i64::one()); + assert_eq!(1, i128::one()); + assert_eq!(1, isize::one()); + assert_eq!(1, u8::one()); + assert_eq!(1, u16::one()); + assert_eq!(1, u32::one()); + assert_eq!(1, u64::one()); + assert_eq!(1, u128::one()); + assert_eq!(1, usize::one()); + } +} diff --git a/src/maxflow.rs b/src/maxflow.rs index 6e6e157..4459171 100644 --- a/src/maxflow.rs +++ b/src/maxflow.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] use crate::internal_queue::SimpleQueue; -use crate::internal_type_traits::Integral; +use crate::internal_type_traits::{Integral, SumExt as _}; use std::cmp::min; use std::iter; diff --git a/src/mincostflow.rs b/src/mincostflow.rs index 7d708e4..5eb6bf9 100644 --- a/src/mincostflow.rs +++ b/src/mincostflow.rs @@ -1,4 +1,4 @@ -use crate::internal_type_traits::Integral; +use crate::internal_type_traits::{Integral, SumExt as _}; pub struct MinCostFlowEdge { pub from: usize, diff --git a/src/segtree.rs b/src/segtree.rs index b543aa3..9f9dbab 100644 --- a/src/segtree.rs +++ b/src/segtree.rs @@ -1,7 +1,8 @@ use crate::internal_bit::ceil_pow2; -use crate::internal_type_traits::{BoundedAbove, BoundedBelow, One, Zero}; +use crate::internal_type_traits::{BoundedAbove, BoundedBelow, ProductExt as _, SumExt as _}; use std::cmp::{max, min}; use std::convert::Infallible; +use std::iter::{Product, Sum}; use std::marker::PhantomData; use std::ops::{Add, Mul}; @@ -43,7 +44,7 @@ where pub struct Additive(Infallible, PhantomData S>); impl Monoid for Additive where - S: Copy + Add + Zero, + S: Copy + Add + Sum, { type S = S; fn identity() -> Self::S { @@ -57,7 +58,7 @@ where pub struct Multiplicative(Infallible, PhantomData S>); impl Monoid for Multiplicative where - S: Copy + Mul + One, + S: Copy + Mul + Product, { type S = S; fn identity() -> Self::S {