1use core::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub};
10
11c0nst::c0nst! {
12pub c0nst trait CheckedAdd: Sized + [c0nst] Add<Self> {
14 fn checked_add(self, v: Self) -> Option<<Self as Add<Self>>::Output>;
17}
18}
19
20macro_rules! checked_impl {
21 ($trait_name:ident, $method:ident, $t:ty) => {
22 c0nst::c0nst! {
23 c0nst impl $trait_name for $t {
24 #[inline]
25 fn $method(self, v: $t) -> Option<$t> {
26 <$t>::$method(self, v)
27 }
28 }
29 }
30 };
31}
32
33checked_impl!(CheckedAdd, checked_add, u8);
34checked_impl!(CheckedAdd, checked_add, u16);
35checked_impl!(CheckedAdd, checked_add, u32);
36checked_impl!(CheckedAdd, checked_add, u64);
37checked_impl!(CheckedAdd, checked_add, usize);
38checked_impl!(CheckedAdd, checked_add, u128);
39
40checked_impl!(CheckedAdd, checked_add, i8);
41checked_impl!(CheckedAdd, checked_add, i16);
42checked_impl!(CheckedAdd, checked_add, i32);
43checked_impl!(CheckedAdd, checked_add, i64);
44checked_impl!(CheckedAdd, checked_add, isize);
45checked_impl!(CheckedAdd, checked_add, i128);
46
47c0nst::c0nst! {
48pub c0nst trait CheckedSub: Sized + [c0nst] Sub<Self> {
50 fn checked_sub(self, v: Self) -> Option<<Self as Sub<Self>>::Output>;
53}
54}
55
56checked_impl!(CheckedSub, checked_sub, u8);
57checked_impl!(CheckedSub, checked_sub, u16);
58checked_impl!(CheckedSub, checked_sub, u32);
59checked_impl!(CheckedSub, checked_sub, u64);
60checked_impl!(CheckedSub, checked_sub, usize);
61checked_impl!(CheckedSub, checked_sub, u128);
62
63checked_impl!(CheckedSub, checked_sub, i8);
64checked_impl!(CheckedSub, checked_sub, i16);
65checked_impl!(CheckedSub, checked_sub, i32);
66checked_impl!(CheckedSub, checked_sub, i64);
67checked_impl!(CheckedSub, checked_sub, isize);
68checked_impl!(CheckedSub, checked_sub, i128);
69
70c0nst::c0nst! {
71pub c0nst trait CheckedMul: Sized + [c0nst] Mul<Self> {
73 fn checked_mul(self, v: Self) -> Option<<Self as Mul<Self>>::Output>;
76}
77}
78
79checked_impl!(CheckedMul, checked_mul, u8);
80checked_impl!(CheckedMul, checked_mul, u16);
81checked_impl!(CheckedMul, checked_mul, u32);
82checked_impl!(CheckedMul, checked_mul, u64);
83checked_impl!(CheckedMul, checked_mul, usize);
84checked_impl!(CheckedMul, checked_mul, u128);
85
86checked_impl!(CheckedMul, checked_mul, i8);
87checked_impl!(CheckedMul, checked_mul, i16);
88checked_impl!(CheckedMul, checked_mul, i32);
89checked_impl!(CheckedMul, checked_mul, i64);
90checked_impl!(CheckedMul, checked_mul, isize);
91checked_impl!(CheckedMul, checked_mul, i128);
92
93c0nst::c0nst! {
94pub c0nst trait CheckedDiv: Sized + [c0nst] Div<Self> {
97 fn checked_div(self, v: Self) -> Option<<Self as Div<Self>>::Output>;
100}
101}
102
103checked_impl!(CheckedDiv, checked_div, u8);
104checked_impl!(CheckedDiv, checked_div, u16);
105checked_impl!(CheckedDiv, checked_div, u32);
106checked_impl!(CheckedDiv, checked_div, u64);
107checked_impl!(CheckedDiv, checked_div, usize);
108checked_impl!(CheckedDiv, checked_div, u128);
109
110checked_impl!(CheckedDiv, checked_div, i8);
111checked_impl!(CheckedDiv, checked_div, i16);
112checked_impl!(CheckedDiv, checked_div, i32);
113checked_impl!(CheckedDiv, checked_div, i64);
114checked_impl!(CheckedDiv, checked_div, isize);
115checked_impl!(CheckedDiv, checked_div, i128);
116
117c0nst::c0nst! {
118pub c0nst trait CheckedRem: Sized + [c0nst] Rem<Self> {
121 fn checked_rem(self, v: Self) -> Option<<Self as Rem<Self>>::Output>;
141}
142}
143
144checked_impl!(CheckedRem, checked_rem, u8);
145checked_impl!(CheckedRem, checked_rem, u16);
146checked_impl!(CheckedRem, checked_rem, u32);
147checked_impl!(CheckedRem, checked_rem, u64);
148checked_impl!(CheckedRem, checked_rem, usize);
149checked_impl!(CheckedRem, checked_rem, u128);
150
151checked_impl!(CheckedRem, checked_rem, i8);
152checked_impl!(CheckedRem, checked_rem, i16);
153checked_impl!(CheckedRem, checked_rem, i32);
154checked_impl!(CheckedRem, checked_rem, i64);
155checked_impl!(CheckedRem, checked_rem, isize);
156checked_impl!(CheckedRem, checked_rem, i128);
157
158macro_rules! checked_impl_unary {
159 ($trait_name:ident, $method:ident, $t:ty) => {
160 c0nst::c0nst! {
161 c0nst impl $trait_name for $t {
162 #[inline]
163 fn $method(self) -> Option<$t> {
164 <$t>::$method(self)
165 }
166 }
167 }
168 };
169}
170
171c0nst::c0nst! {
172pub c0nst trait CheckedNeg: Sized {
174 type Output;
177
178 fn checked_neg(self) -> Option<Self::Output>;
195}
196}
197
198macro_rules! checked_neg_impl {
199 ($($t:ty)*) => {$(
200 c0nst::c0nst! {
201 c0nst impl CheckedNeg for $t {
202 type Output = $t;
203 #[inline]
204 fn checked_neg(self) -> Option<$t> {
205 <$t>::checked_neg(self)
206 }
207 }
208 }
209 )*};
210}
211
212checked_neg_impl!(u8 u16 u32 u64 usize u128 i8 i16 i32 i64 isize i128);
213
214c0nst::c0nst! {
215pub c0nst trait CheckedShl: Sized + [c0nst] Shl<u32> {
218 fn checked_shl(self, rhs: u32) -> Option<<Self as Shl<u32>>::Output>;
232}
233}
234
235macro_rules! checked_shift_impl {
236 ($trait_name:ident, $method:ident, $t:ty) => {
237 c0nst::c0nst! {
238 c0nst impl $trait_name for $t {
239 #[inline]
240 fn $method(self, rhs: u32) -> Option<$t> {
241 <$t>::$method(self, rhs)
242 }
243 }
244 }
245 };
246}
247
248checked_shift_impl!(CheckedShl, checked_shl, u8);
249checked_shift_impl!(CheckedShl, checked_shl, u16);
250checked_shift_impl!(CheckedShl, checked_shl, u32);
251checked_shift_impl!(CheckedShl, checked_shl, u64);
252checked_shift_impl!(CheckedShl, checked_shl, usize);
253checked_shift_impl!(CheckedShl, checked_shl, u128);
254
255checked_shift_impl!(CheckedShl, checked_shl, i8);
256checked_shift_impl!(CheckedShl, checked_shl, i16);
257checked_shift_impl!(CheckedShl, checked_shl, i32);
258checked_shift_impl!(CheckedShl, checked_shl, i64);
259checked_shift_impl!(CheckedShl, checked_shl, isize);
260checked_shift_impl!(CheckedShl, checked_shl, i128);
261
262c0nst::c0nst! {
263pub c0nst trait CheckedShr: Sized + [c0nst] Shr<u32> {
266 fn checked_shr(self, rhs: u32) -> Option<<Self as Shr<u32>>::Output>;
280}
281}
282
283checked_shift_impl!(CheckedShr, checked_shr, u8);
284checked_shift_impl!(CheckedShr, checked_shr, u16);
285checked_shift_impl!(CheckedShr, checked_shr, u32);
286checked_shift_impl!(CheckedShr, checked_shr, u64);
287checked_shift_impl!(CheckedShr, checked_shr, usize);
288checked_shift_impl!(CheckedShr, checked_shr, u128);
289
290checked_shift_impl!(CheckedShr, checked_shr, i8);
291checked_shift_impl!(CheckedShr, checked_shr, i16);
292checked_shift_impl!(CheckedShr, checked_shr, i32);
293checked_shift_impl!(CheckedShr, checked_shr, i64);
294checked_shift_impl!(CheckedShr, checked_shr, isize);
295checked_shift_impl!(CheckedShr, checked_shr, i128);
296
297c0nst::c0nst! {
298pub c0nst trait CheckedAbs: Sized + [c0nst] Neg {
300 fn checked_abs(self) -> Option<<Self as Neg>::Output>;
312}
313}
314
315checked_impl_unary!(CheckedAbs, checked_abs, i8);
316checked_impl_unary!(CheckedAbs, checked_abs, i16);
317checked_impl_unary!(CheckedAbs, checked_abs, i32);
318checked_impl_unary!(CheckedAbs, checked_abs, i64);
319checked_impl_unary!(CheckedAbs, checked_abs, isize);
320checked_impl_unary!(CheckedAbs, checked_abs, i128);
321
322c0nst::c0nst! {
323pub c0nst trait CheckedPow: Sized + [c0nst] Mul<Self> {
325 fn checked_pow(self, exp: u32) -> Option<<Self as Mul<Self>>::Output>;
341}
342}
343
344checked_shift_impl!(CheckedPow, checked_pow, u8);
345checked_shift_impl!(CheckedPow, checked_pow, u16);
346checked_shift_impl!(CheckedPow, checked_pow, u32);
347checked_shift_impl!(CheckedPow, checked_pow, u64);
348checked_shift_impl!(CheckedPow, checked_pow, usize);
349checked_shift_impl!(CheckedPow, checked_pow, u128);
350
351checked_shift_impl!(CheckedPow, checked_pow, i8);
352checked_shift_impl!(CheckedPow, checked_pow, i16);
353checked_shift_impl!(CheckedPow, checked_pow, i32);
354checked_shift_impl!(CheckedPow, checked_pow, i64);
355checked_shift_impl!(CheckedPow, checked_pow, isize);
356checked_shift_impl!(CheckedPow, checked_pow, i128);
357
358#[test]
359fn test_checked_abs_pow() {
360 fn checked_abs<T: CheckedAbs + core::ops::Neg<Output = T>>(a: T) -> Option<T> {
361 a.checked_abs()
362 }
363 fn checked_pow<T: CheckedPow + core::ops::Mul<Output = T>>(a: T, exp: u32) -> Option<T> {
364 a.checked_pow(exp)
365 }
366 assert_eq!(checked_abs(-5i16), Some(5));
367 assert_eq!(checked_abs(i16::MIN), None);
368 assert_eq!(checked_pow(3u8, 5), Some(243));
369 assert_eq!(checked_pow(2u8, 8), None);
370 assert_eq!(checked_pow(-3i32, 3), Some(-27));
371}