use_arithmetic/
wrapping.rs1#![allow(clippy::module_name_repetitions)]
2
3mod sealed {
4 pub trait Sealed {}
5
6 macro_rules! impl_sealed {
7 ($($ty:ty),* $(,)?) => {
8 $(impl Sealed for $ty {})*
9 };
10 }
11
12 impl_sealed!(
13 u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
14 );
15}
16
17pub trait WrappingArithmetic: sealed::Sealed + Sized {
19 #[must_use]
21 fn wrapping_add(self, rhs: Self) -> Self;
22
23 #[must_use]
25 fn wrapping_sub(self, rhs: Self) -> Self;
26
27 #[must_use]
29 fn wrapping_mul(self, rhs: Self) -> Self;
30}
31
32macro_rules! impl_wrapping_arithmetic {
33 ($($ty:ty),* $(,)?) => {
34 $(impl WrappingArithmetic for $ty {
35 fn wrapping_add(self, rhs: Self) -> Self {
36 <$ty>::wrapping_add(self, rhs)
37 }
38
39 fn wrapping_sub(self, rhs: Self) -> Self {
40 <$ty>::wrapping_sub(self, rhs)
41 }
42
43 fn wrapping_mul(self, rhs: Self) -> Self {
44 <$ty>::wrapping_mul(self, rhs)
45 }
46 })*
47 };
48}
49
50impl_wrapping_arithmetic!(
51 u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
52);
53
54#[must_use]
56pub fn wrapping_add<T: WrappingArithmetic>(left: T, right: T) -> T {
57 <T as WrappingArithmetic>::wrapping_add(left, right)
58}
59
60#[must_use]
62pub fn wrapping_sub<T: WrappingArithmetic>(left: T, right: T) -> T {
63 <T as WrappingArithmetic>::wrapping_sub(left, right)
64}
65
66#[must_use]
68pub fn wrapping_mul<T: WrappingArithmetic>(left: T, right: T) -> T {
69 <T as WrappingArithmetic>::wrapping_mul(left, right)
70}
71
72#[cfg(test)]
73mod tests {
74 use super::{wrapping_add, wrapping_mul, wrapping_sub};
75
76 #[test]
77 fn wraps_unsigned_values() {
78 assert_eq!(wrapping_add(u8::MAX, 1), 0);
79 assert_eq!(wrapping_sub(0_u8, 1), u8::MAX);
80 assert_eq!(wrapping_mul(200_u8, 2), 144);
81 }
82
83 #[test]
84 fn wraps_signed_values() {
85 assert_eq!(wrapping_add(i8::MAX, 1), i8::MIN);
86 assert_eq!(wrapping_sub(i8::MIN, 1), i8::MAX);
87 assert_eq!(wrapping_mul(100_i8, 2), -56);
88 }
89}