1use core::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub};
10
11macro_rules! overflowing_impl {
12 ($trait_name:ident, $method:ident, $t:ty) => {
13 c0nst::c0nst! {
14 c0nst impl $trait_name for $t {
15 #[inline]
16 fn $method(self, v: Self) -> (Self, bool) {
17 <$t>::$method(self, v)
18 }
19 }
20 }
21 };
22}
23
24c0nst::c0nst! {
25pub c0nst trait OverflowingAdd: Sized + [c0nst] Add<Self> {
27 fn overflowing_add(self, v: Self) -> (<Self as Add<Self>>::Output, bool);
30}
31}
32
33overflowing_impl!(OverflowingAdd, overflowing_add, u8);
34overflowing_impl!(OverflowingAdd, overflowing_add, u16);
35overflowing_impl!(OverflowingAdd, overflowing_add, u32);
36overflowing_impl!(OverflowingAdd, overflowing_add, u64);
37overflowing_impl!(OverflowingAdd, overflowing_add, usize);
38overflowing_impl!(OverflowingAdd, overflowing_add, u128);
39
40overflowing_impl!(OverflowingAdd, overflowing_add, i8);
41overflowing_impl!(OverflowingAdd, overflowing_add, i16);
42overflowing_impl!(OverflowingAdd, overflowing_add, i32);
43overflowing_impl!(OverflowingAdd, overflowing_add, i64);
44overflowing_impl!(OverflowingAdd, overflowing_add, isize);
45overflowing_impl!(OverflowingAdd, overflowing_add, i128);
46
47c0nst::c0nst! {
48pub c0nst trait OverflowingSub: Sized + [c0nst] Sub<Self> {
50 fn overflowing_sub(self, v: Self) -> (<Self as Sub<Self>>::Output, bool);
53}
54}
55
56overflowing_impl!(OverflowingSub, overflowing_sub, u8);
57overflowing_impl!(OverflowingSub, overflowing_sub, u16);
58overflowing_impl!(OverflowingSub, overflowing_sub, u32);
59overflowing_impl!(OverflowingSub, overflowing_sub, u64);
60overflowing_impl!(OverflowingSub, overflowing_sub, usize);
61overflowing_impl!(OverflowingSub, overflowing_sub, u128);
62
63overflowing_impl!(OverflowingSub, overflowing_sub, i8);
64overflowing_impl!(OverflowingSub, overflowing_sub, i16);
65overflowing_impl!(OverflowingSub, overflowing_sub, i32);
66overflowing_impl!(OverflowingSub, overflowing_sub, i64);
67overflowing_impl!(OverflowingSub, overflowing_sub, isize);
68overflowing_impl!(OverflowingSub, overflowing_sub, i128);
69
70c0nst::c0nst! {
71pub c0nst trait OverflowingMul: Sized + [c0nst] Mul<Self> {
73 fn overflowing_mul(self, v: Self) -> (<Self as Mul<Self>>::Output, bool);
76}
77}
78
79overflowing_impl!(OverflowingMul, overflowing_mul, u8);
80overflowing_impl!(OverflowingMul, overflowing_mul, u16);
81overflowing_impl!(OverflowingMul, overflowing_mul, u32);
82overflowing_impl!(OverflowingMul, overflowing_mul, u64);
83overflowing_impl!(OverflowingMul, overflowing_mul, usize);
84overflowing_impl!(OverflowingMul, overflowing_mul, u128);
85
86overflowing_impl!(OverflowingMul, overflowing_mul, i8);
87overflowing_impl!(OverflowingMul, overflowing_mul, i16);
88overflowing_impl!(OverflowingMul, overflowing_mul, i32);
89overflowing_impl!(OverflowingMul, overflowing_mul, i64);
90overflowing_impl!(OverflowingMul, overflowing_mul, isize);
91overflowing_impl!(OverflowingMul, overflowing_mul, i128);
92
93c0nst::c0nst! {
94pub c0nst trait OverflowingDiv: Sized + [c0nst] Div<Self> {
96 fn overflowing_div(self, v: Self) -> (<Self as Div<Self>>::Output, bool);
104}
105}
106
107overflowing_impl!(OverflowingDiv, overflowing_div, u8);
108overflowing_impl!(OverflowingDiv, overflowing_div, u16);
109overflowing_impl!(OverflowingDiv, overflowing_div, u32);
110overflowing_impl!(OverflowingDiv, overflowing_div, u64);
111overflowing_impl!(OverflowingDiv, overflowing_div, usize);
112overflowing_impl!(OverflowingDiv, overflowing_div, u128);
113
114overflowing_impl!(OverflowingDiv, overflowing_div, i8);
115overflowing_impl!(OverflowingDiv, overflowing_div, i16);
116overflowing_impl!(OverflowingDiv, overflowing_div, i32);
117overflowing_impl!(OverflowingDiv, overflowing_div, i64);
118overflowing_impl!(OverflowingDiv, overflowing_div, isize);
119overflowing_impl!(OverflowingDiv, overflowing_div, i128);
120
121c0nst::c0nst! {
122pub c0nst trait OverflowingRem: Sized + [c0nst] Rem<Self> {
124 fn overflowing_rem(self, v: Self) -> (<Self as Rem<Self>>::Output, bool);
132}
133}
134
135overflowing_impl!(OverflowingRem, overflowing_rem, u8);
136overflowing_impl!(OverflowingRem, overflowing_rem, u16);
137overflowing_impl!(OverflowingRem, overflowing_rem, u32);
138overflowing_impl!(OverflowingRem, overflowing_rem, u64);
139overflowing_impl!(OverflowingRem, overflowing_rem, usize);
140overflowing_impl!(OverflowingRem, overflowing_rem, u128);
141
142overflowing_impl!(OverflowingRem, overflowing_rem, i8);
143overflowing_impl!(OverflowingRem, overflowing_rem, i16);
144overflowing_impl!(OverflowingRem, overflowing_rem, i32);
145overflowing_impl!(OverflowingRem, overflowing_rem, i64);
146overflowing_impl!(OverflowingRem, overflowing_rem, isize);
147overflowing_impl!(OverflowingRem, overflowing_rem, i128);
148
149macro_rules! overflowing_neg_impl {
150 ($($t:ty)*) => {$(
151 c0nst::c0nst! {
152 c0nst impl OverflowingNeg for $t {
153 type Output = $t;
154 #[inline]
155 fn overflowing_neg(self) -> ($t, bool) { <$t>::overflowing_neg(self) }
156 }
157 }
158 )*};
159}
160
161macro_rules! overflowing_unary_impl {
162 ($trait_name:ident, $method:ident, $t:ty) => {
163 c0nst::c0nst! {
164 c0nst impl $trait_name for $t {
165 #[inline]
166 fn $method(self) -> ($t, bool) {
167 <$t>::$method(self)
168 }
169 }
170 }
171 };
172}
173
174c0nst::c0nst! {
175pub c0nst trait OverflowingNeg: Sized {
177 type Output;
181 fn overflowing_neg(self) -> (Self::Output, bool);
182}
183}
184
185overflowing_neg_impl!(u8 u16 u32 u64 usize u128 i8 i16 i32 i64 isize i128);
186
187c0nst::c0nst! {
188pub c0nst trait OverflowingAbs: Sized + [c0nst] Neg {
190 fn overflowing_abs(self) -> (<Self as Neg>::Output, bool);
194}
195}
196
197overflowing_unary_impl!(OverflowingAbs, overflowing_abs, i8);
198overflowing_unary_impl!(OverflowingAbs, overflowing_abs, i16);
199overflowing_unary_impl!(OverflowingAbs, overflowing_abs, i32);
200overflowing_unary_impl!(OverflowingAbs, overflowing_abs, i64);
201overflowing_unary_impl!(OverflowingAbs, overflowing_abs, isize);
202overflowing_unary_impl!(OverflowingAbs, overflowing_abs, i128);
203
204macro_rules! overflowing_u32_rhs_impl {
205 ($trait_name:ident, $method:ident, $t:ty) => {
206 c0nst::c0nst! {
207 c0nst impl $trait_name for $t {
208 #[inline]
209 fn $method(self, rhs: u32) -> ($t, bool) {
210 <$t>::$method(self, rhs)
211 }
212 }
213 }
214 };
215}
216
217c0nst::c0nst! {
218pub c0nst trait OverflowingShl: Sized + [c0nst] Shl<u32> {
220 fn overflowing_shl(self, rhs: u32) -> (<Self as Shl<u32>>::Output, bool);
231}
232}
233
234overflowing_u32_rhs_impl!(OverflowingShl, overflowing_shl, u8);
235overflowing_u32_rhs_impl!(OverflowingShl, overflowing_shl, u16);
236overflowing_u32_rhs_impl!(OverflowingShl, overflowing_shl, u32);
237overflowing_u32_rhs_impl!(OverflowingShl, overflowing_shl, u64);
238overflowing_u32_rhs_impl!(OverflowingShl, overflowing_shl, usize);
239overflowing_u32_rhs_impl!(OverflowingShl, overflowing_shl, u128);
240
241overflowing_u32_rhs_impl!(OverflowingShl, overflowing_shl, i8);
242overflowing_u32_rhs_impl!(OverflowingShl, overflowing_shl, i16);
243overflowing_u32_rhs_impl!(OverflowingShl, overflowing_shl, i32);
244overflowing_u32_rhs_impl!(OverflowingShl, overflowing_shl, i64);
245overflowing_u32_rhs_impl!(OverflowingShl, overflowing_shl, isize);
246overflowing_u32_rhs_impl!(OverflowingShl, overflowing_shl, i128);
247
248c0nst::c0nst! {
249pub c0nst trait OverflowingShr: Sized + [c0nst] Shr<u32> {
251 fn overflowing_shr(self, rhs: u32) -> (<Self as Shr<u32>>::Output, bool);
262}
263}
264
265overflowing_u32_rhs_impl!(OverflowingShr, overflowing_shr, u8);
266overflowing_u32_rhs_impl!(OverflowingShr, overflowing_shr, u16);
267overflowing_u32_rhs_impl!(OverflowingShr, overflowing_shr, u32);
268overflowing_u32_rhs_impl!(OverflowingShr, overflowing_shr, u64);
269overflowing_u32_rhs_impl!(OverflowingShr, overflowing_shr, usize);
270overflowing_u32_rhs_impl!(OverflowingShr, overflowing_shr, u128);
271
272overflowing_u32_rhs_impl!(OverflowingShr, overflowing_shr, i8);
273overflowing_u32_rhs_impl!(OverflowingShr, overflowing_shr, i16);
274overflowing_u32_rhs_impl!(OverflowingShr, overflowing_shr, i32);
275overflowing_u32_rhs_impl!(OverflowingShr, overflowing_shr, i64);
276overflowing_u32_rhs_impl!(OverflowingShr, overflowing_shr, isize);
277overflowing_u32_rhs_impl!(OverflowingShr, overflowing_shr, i128);
278
279c0nst::c0nst! {
280pub c0nst trait OverflowingPow: Sized + [c0nst] Mul<Self> {
282 fn overflowing_pow(self, exp: u32) -> (<Self as Mul<Self>>::Output, bool);
286}
287}
288
289overflowing_u32_rhs_impl!(OverflowingPow, overflowing_pow, u8);
290overflowing_u32_rhs_impl!(OverflowingPow, overflowing_pow, u16);
291overflowing_u32_rhs_impl!(OverflowingPow, overflowing_pow, u32);
292overflowing_u32_rhs_impl!(OverflowingPow, overflowing_pow, u64);
293overflowing_u32_rhs_impl!(OverflowingPow, overflowing_pow, usize);
294overflowing_u32_rhs_impl!(OverflowingPow, overflowing_pow, u128);
295
296overflowing_u32_rhs_impl!(OverflowingPow, overflowing_pow, i8);
297overflowing_u32_rhs_impl!(OverflowingPow, overflowing_pow, i16);
298overflowing_u32_rhs_impl!(OverflowingPow, overflowing_pow, i32);
299overflowing_u32_rhs_impl!(OverflowingPow, overflowing_pow, i64);
300overflowing_u32_rhs_impl!(OverflowingPow, overflowing_pow, isize);
301overflowing_u32_rhs_impl!(OverflowingPow, overflowing_pow, i128);
302
303#[test]
304fn test_overflowing_extended_traits() {
305 assert_eq!(
306 OverflowingDiv::overflowing_div(i8::MIN, -1),
307 (i8::MIN, true)
308 );
309 assert_eq!(OverflowingDiv::overflowing_div(100u8, 7), (14, false));
310 assert_eq!(OverflowingRem::overflowing_rem(i8::MIN, -1), (0, true));
311 assert_eq!(OverflowingNeg::overflowing_neg(1u8), (255, true));
312 assert_eq!(OverflowingNeg::overflowing_neg(0u8), (0, false));
313 assert_eq!(OverflowingNeg::overflowing_neg(i8::MIN), (i8::MIN, true));
314 assert_eq!(OverflowingAbs::overflowing_abs(i8::MIN), (i8::MIN, true));
315 assert_eq!(OverflowingAbs::overflowing_abs(-7i8), (7, false));
316 assert_eq!(OverflowingShl::overflowing_shl(1u8, 8), (1, true));
317 assert_eq!(OverflowingShr::overflowing_shr(0x80u8, 9), (0x40, true));
318 assert_eq!(OverflowingPow::overflowing_pow(3u8, 6), (217, true));
319 assert_eq!(OverflowingPow::overflowing_pow(3i32, 4), (81, false));
320}
321
322#[test]
323fn test_overflowing_traits() {
324 fn overflowing_add<T: OverflowingAdd<Output = T>>(a: T, b: T) -> (T, bool) {
325 a.overflowing_add(b)
326 }
327 fn overflowing_sub<T: OverflowingSub<Output = T>>(a: T, b: T) -> (T, bool) {
328 a.overflowing_sub(b)
329 }
330 fn overflowing_mul<T: OverflowingMul<Output = T>>(a: T, b: T) -> (T, bool) {
331 a.overflowing_mul(b)
332 }
333 assert_eq!(overflowing_add(5i16, 2), (7, false));
334 assert_eq!(overflowing_add(i16::MAX, 1), (i16::MIN, true));
335 assert_eq!(overflowing_sub(5i16, 2), (3, false));
336 assert_eq!(overflowing_sub(i16::MIN, 1), (i16::MAX, true));
337 assert_eq!(overflowing_mul(5i16, 2), (10, false));
338 assert_eq!(overflowing_mul(1_000_000_000i32, 10), (1410065408, true));
339}