1pub trait WrappingAdd<Rhs = Self> {
11 type Output;
12 fn wrapping_add(self, rhs: Rhs) -> Self::Output;
13}
14
15pub trait WrappingMul<Rhs = Self> {
18 type Output;
19 fn wrapping_mul(self, rhs: Rhs) -> Self::Output;
20}
21
22pub trait WrappingNeg {
24 type Output;
25 fn wrapping_neg(self) -> Self::Output;
26}
27
28pub trait WrappingSub<Rhs = Self> {
30 type Output;
31 fn wrapping_sub(self, rhs: Rhs) -> Self::Output;
32}
33
34macro_rules! impl_unary_ops {
38 { $(impl $trait:ident::$fn:ident for $ty:ident;)* } => { $(
39 impl $trait for $ty {
40 type Output = $ty;
41
42 fn $fn(self) -> $ty {
43 self.$fn()
44 }
45 }
46
47 impl<'a> $trait for &'a $ty {
48 type Output = $ty;
49
50 fn $fn(self) -> $ty {
51 $trait::$fn(*self)
52 }
53 }
54 )* };
55}
56
57macro_rules! impl_binary_ops {
59 { $(impl $trait:ident::$fn:ident for $ty:ident;)* } => { $(
60 impl $trait for $ty {
61 type Output = $ty;
62
63 fn $fn(self, rhs: $ty) -> $ty {
64 self.$fn(rhs)
65 }
66 }
67
68 impl<'a> $trait<$ty> for &'a $ty {
69 type Output = $ty;
70
71 fn $fn(self, rhs: $ty) -> $ty {
72 $trait::$fn(*self, rhs)
73 }
74 }
75
76 impl<'r> $trait<&'r $ty> for $ty {
77 type Output = $ty;
78
79 fn $fn(self, rhs: &'r $ty) -> $ty {
80 $trait::$fn(self, *rhs)
81 }
82 }
83
84 impl<'a, 'r> $trait<&'r $ty> for &'a $ty {
85 type Output = $ty;
86
87 fn $fn(self, rhs: &'r $ty) -> $ty {
88 $trait::$fn(*self, *rhs)
89 }
90 }
91 )* };
92}
93
94macro_rules! impl_int_ops {
96 ($($ty:ident),*) => { $(
97 impl_unary_ops! {
98 impl WrappingNeg::wrapping_neg for $ty;
99 }
100
101 impl_binary_ops! {
102 impl WrappingAdd::wrapping_add for $ty;
103 impl WrappingMul::wrapping_mul for $ty;
104 impl WrappingSub::wrapping_sub for $ty;
105 }
106 )* };
107}
108
109impl_int_ops!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize);
110
111#[test]
114fn test_wrapping_add() {
115 assert_eq!(WrappingAdd::wrapping_add(100i8, 27), 127);
116 assert_eq!(WrappingAdd::wrapping_add(100i8, 28), -128);
117 assert_eq!(WrappingAdd::wrapping_add(-100i8, -28), -128);
118 assert_eq!(WrappingAdd::wrapping_add(-100i8, -29), 127);
119 assert_eq!(WrappingAdd::wrapping_add(200u8, 55), 255);
120 assert_eq!(WrappingAdd::wrapping_add(200u8, 56), 0);
121}
122
123#[test]
124fn test_wrapping_mul() {
125 assert_eq!(WrappingMul::wrapping_mul(8i8, 15), 120);
126 assert_eq!(WrappingMul::wrapping_mul(8i8, 16), -128);
127 assert_eq!(WrappingMul::wrapping_mul(8i8, -16), -128);
128 assert_eq!(WrappingMul::wrapping_mul(3i8, -43), 127);
129 assert_eq!(WrappingMul::wrapping_mul(-1i8, -127), 127);
130 assert_eq!(WrappingMul::wrapping_mul(-1i8, -128), -128);
131 assert_eq!(WrappingMul::wrapping_mul(85u8, 3), 255);
132 assert_eq!(WrappingMul::wrapping_mul(16u8, 16), 0);
133}
134
135#[test]
136fn test_wrapping_neg() {
137 assert_eq!(WrappingNeg::wrapping_neg(127i8), -127);
138 assert_eq!(WrappingNeg::wrapping_neg(-127i8), 127);
139 assert_eq!(WrappingNeg::wrapping_neg(-128i8), -128);
140 assert_eq!(WrappingNeg::wrapping_neg(0u8), 0);
141 assert_eq!(WrappingNeg::wrapping_neg(1u8), 255);
142 assert_eq!(WrappingNeg::wrapping_neg(255u8), 1);
143}
144
145#[test]
146fn test_wrapping_sub() {
147 assert_eq!(WrappingSub::wrapping_sub(100i8, -27), 127);
148 assert_eq!(WrappingSub::wrapping_sub(100i8, -28), -128);
149 assert_eq!(WrappingSub::wrapping_sub(-100i8, 28), -128);
150 assert_eq!(WrappingSub::wrapping_sub(-100i8, 29), 127);
151 assert_eq!(WrappingSub::wrapping_sub(100u8, 100), 0);
152 assert_eq!(WrappingSub::wrapping_sub(100u8, 101), 255);
153}