1use core::{i128, i16, i32, i64, i8, isize};
2use core::{u128, u16, u32, u64, u8, usize};
3
4macro_rules! overflowing_impl {
5 ($trait_name:ident, $method:ident, $t:ty) => {
6 impl $trait_name<$t> for $t {
7 type Output = $t;
8 #[inline]
9 fn $method(self, v: $t) -> ($t, bool) {
10 <$t>::$method(self, v)
11 }
12 }
13
14 impl $trait_name<&$t> for $t {
15 type Output = $t;
16 #[inline]
17 fn $method(self, v: &$t) -> ($t, bool) {
18 <$t>::$method(self, *v)
19 }
20 }
21
22 impl $trait_name<$t> for &$t {
23 type Output = $t;
24 #[inline]
25 fn $method(self, v: $t) -> ($t, bool) {
26 <$t>::$method(*self, v)
27 }
28 }
29
30 impl $trait_name<&$t> for &$t {
31 type Output = $t;
32 #[inline]
33 fn $method(self, v: &$t) -> ($t, bool) {
34 <$t>::$method(*self, *v)
35 }
36 }
37 };
38}
39
40pub trait OverflowingAdd<Rhs = Self>: Sized {
42 type Output;
43 fn overflowing_add(self, v: Rhs) -> (Self::Output, bool);
46}
47
48overflowing_impl!(OverflowingAdd, overflowing_add, u8);
49overflowing_impl!(OverflowingAdd, overflowing_add, u16);
50overflowing_impl!(OverflowingAdd, overflowing_add, u32);
51overflowing_impl!(OverflowingAdd, overflowing_add, u64);
52overflowing_impl!(OverflowingAdd, overflowing_add, usize);
53overflowing_impl!(OverflowingAdd, overflowing_add, u128);
54
55overflowing_impl!(OverflowingAdd, overflowing_add, i8);
56overflowing_impl!(OverflowingAdd, overflowing_add, i16);
57overflowing_impl!(OverflowingAdd, overflowing_add, i32);
58overflowing_impl!(OverflowingAdd, overflowing_add, i64);
59overflowing_impl!(OverflowingAdd, overflowing_add, isize);
60overflowing_impl!(OverflowingAdd, overflowing_add, i128);
61
62pub trait OverflowingSub<Rhs = Self>: Sized {
64 type Output;
65 fn overflowing_sub(self, v: Rhs) -> (Self::Output, bool);
68}
69
70overflowing_impl!(OverflowingSub, overflowing_sub, u8);
71overflowing_impl!(OverflowingSub, overflowing_sub, u16);
72overflowing_impl!(OverflowingSub, overflowing_sub, u32);
73overflowing_impl!(OverflowingSub, overflowing_sub, u64);
74overflowing_impl!(OverflowingSub, overflowing_sub, usize);
75overflowing_impl!(OverflowingSub, overflowing_sub, u128);
76
77overflowing_impl!(OverflowingSub, overflowing_sub, i8);
78overflowing_impl!(OverflowingSub, overflowing_sub, i16);
79overflowing_impl!(OverflowingSub, overflowing_sub, i32);
80overflowing_impl!(OverflowingSub, overflowing_sub, i64);
81overflowing_impl!(OverflowingSub, overflowing_sub, isize);
82overflowing_impl!(OverflowingSub, overflowing_sub, i128);
83
84pub trait OverflowingMul<Rhs = Self>: Sized {
86 type Output;
87 fn overflowing_mul(self, v: Rhs) -> (Self::Output, bool);
90}
91
92overflowing_impl!(OverflowingMul, overflowing_mul, u8);
93overflowing_impl!(OverflowingMul, overflowing_mul, u16);
94overflowing_impl!(OverflowingMul, overflowing_mul, u32);
95overflowing_impl!(OverflowingMul, overflowing_mul, u64);
96overflowing_impl!(OverflowingMul, overflowing_mul, usize);
97overflowing_impl!(OverflowingMul, overflowing_mul, u128);
98
99overflowing_impl!(OverflowingMul, overflowing_mul, i8);
100overflowing_impl!(OverflowingMul, overflowing_mul, i16);
101overflowing_impl!(OverflowingMul, overflowing_mul, i32);
102overflowing_impl!(OverflowingMul, overflowing_mul, i64);
103overflowing_impl!(OverflowingMul, overflowing_mul, isize);
104overflowing_impl!(OverflowingMul, overflowing_mul, i128);
105
106#[test]
107fn test_overflowing_traits() {
108 fn overflowing_add<T: OverflowingAdd>(a: T, b: T) -> (T, bool) {
109 a.overflowing_add(&b)
110 }
111 fn overflowing_sub<T: OverflowingSub>(a: T, b: T) -> (T, bool) {
112 a.overflowing_sub(&b)
113 }
114 fn overflowing_mul<T: OverflowingMul>(a: T, b: T) -> (T, bool) {
115 a.overflowing_mul(&b)
116 }
117 assert_eq!(overflowing_add(5i16, 2), (7, false));
118 assert_eq!(overflowing_add(i16::MAX, 1), (i16::MIN, true));
119 assert_eq!(overflowing_sub(5i16, 2), (3, false));
120 assert_eq!(overflowing_sub(i16::MIN, 1), (i16::MAX, true));
121 assert_eq!(overflowing_mul(5i16, 2), (10, false));
122 assert_eq!(overflowing_mul(1_000_000_000i32, 10), (1410065408, true));
123}