1use core::num::Wrapping;
9use core::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub};
10
11macro_rules! wrapping_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 {
17 <$t>::$method(self, v)
18 }
19 }
20 }
21 };
22 ($trait_name:ident, $method:ident, $t:ty, $rhs:ty) => {
23 c0nst::c0nst! {
24 c0nst impl $trait_name<$rhs> for $t {
25 #[inline]
26 fn $method(self, v: $rhs) -> Self {
27 <$t>::$method(self, v)
28 }
29 }
30 }
31 };
32}
33
34c0nst::c0nst! {
35pub c0nst trait WrappingAdd: Sized + [c0nst] Add<Self> {
37 fn wrapping_add(self, v: Self) -> <Self as Add<Self>>::Output;
40}
41}
42
43wrapping_impl!(WrappingAdd, wrapping_add, u8);
44wrapping_impl!(WrappingAdd, wrapping_add, u16);
45wrapping_impl!(WrappingAdd, wrapping_add, u32);
46wrapping_impl!(WrappingAdd, wrapping_add, u64);
47wrapping_impl!(WrappingAdd, wrapping_add, usize);
48wrapping_impl!(WrappingAdd, wrapping_add, u128);
49
50wrapping_impl!(WrappingAdd, wrapping_add, i8);
51wrapping_impl!(WrappingAdd, wrapping_add, i16);
52wrapping_impl!(WrappingAdd, wrapping_add, i32);
53wrapping_impl!(WrappingAdd, wrapping_add, i64);
54wrapping_impl!(WrappingAdd, wrapping_add, isize);
55wrapping_impl!(WrappingAdd, wrapping_add, i128);
56
57c0nst::c0nst! {
58pub c0nst trait WrappingSub: Sized + [c0nst] Sub<Self> {
60 fn wrapping_sub(self, v: Self) -> <Self as Sub<Self>>::Output;
63}
64}
65
66wrapping_impl!(WrappingSub, wrapping_sub, u8);
67wrapping_impl!(WrappingSub, wrapping_sub, u16);
68wrapping_impl!(WrappingSub, wrapping_sub, u32);
69wrapping_impl!(WrappingSub, wrapping_sub, u64);
70wrapping_impl!(WrappingSub, wrapping_sub, usize);
71wrapping_impl!(WrappingSub, wrapping_sub, u128);
72
73wrapping_impl!(WrappingSub, wrapping_sub, i8);
74wrapping_impl!(WrappingSub, wrapping_sub, i16);
75wrapping_impl!(WrappingSub, wrapping_sub, i32);
76wrapping_impl!(WrappingSub, wrapping_sub, i64);
77wrapping_impl!(WrappingSub, wrapping_sub, isize);
78wrapping_impl!(WrappingSub, wrapping_sub, i128);
79
80c0nst::c0nst! {
81pub c0nst trait WrappingMul: Sized + [c0nst] Mul<Self> {
83 fn wrapping_mul(self, v: Self) -> <Self as Mul<Self>>::Output;
86}
87}
88
89wrapping_impl!(WrappingMul, wrapping_mul, u8);
90wrapping_impl!(WrappingMul, wrapping_mul, u16);
91wrapping_impl!(WrappingMul, wrapping_mul, u32);
92wrapping_impl!(WrappingMul, wrapping_mul, u64);
93wrapping_impl!(WrappingMul, wrapping_mul, usize);
94wrapping_impl!(WrappingMul, wrapping_mul, u128);
95
96wrapping_impl!(WrappingMul, wrapping_mul, i8);
97wrapping_impl!(WrappingMul, wrapping_mul, i16);
98wrapping_impl!(WrappingMul, wrapping_mul, i32);
99wrapping_impl!(WrappingMul, wrapping_mul, i64);
100wrapping_impl!(WrappingMul, wrapping_mul, isize);
101wrapping_impl!(WrappingMul, wrapping_mul, i128);
102
103macro_rules! wrapping_neg_impl {
104 ($($t:ty)*) => {$(
105 c0nst::c0nst! {
106 c0nst impl WrappingNeg for $t {
107 type Output = $t;
108 #[inline]
109 fn wrapping_neg(self) -> $t {
110 <$t>::wrapping_neg(self)
111 }
112 }
113 }
114 )*};
115}
116
117macro_rules! wrapping_unary_impl {
118 ($trait_name:ident, $method:ident, $t:ty) => {
119 c0nst::c0nst! {
120 c0nst impl $trait_name for $t {
121 #[inline]
122 fn $method(self) -> $t {
123 <$t>::$method(self)
124 }
125 }
126 }
127 };
128}
129
130c0nst::c0nst! {
131pub c0nst trait WrappingNeg: Sized {
133 type Output;
151 fn wrapping_neg(self) -> Self::Output;
152}
153}
154
155wrapping_neg_impl!(u8 u16 u32 u64 usize u128 i8 i16 i32 i64 isize i128);
156
157macro_rules! wrapping_shift_impl {
158 ($trait_name:ident, $method:ident, $t:ty) => {
159 c0nst::c0nst! {
160 c0nst impl $trait_name for $t {
161 #[inline]
162 fn $method(self, rhs: u32) -> $t {
163 <$t>::$method(self, rhs)
164 }
165 }
166 }
167 };
168}
169
170c0nst::c0nst! {
171pub c0nst trait WrappingShl: Sized + [c0nst] Shl<usize> {
173 fn wrapping_shl(self, rhs: u32) -> <Self as Shl<usize>>::Output;
188}
189}
190
191wrapping_shift_impl!(WrappingShl, wrapping_shl, u8);
192wrapping_shift_impl!(WrappingShl, wrapping_shl, u16);
193wrapping_shift_impl!(WrappingShl, wrapping_shl, u32);
194wrapping_shift_impl!(WrappingShl, wrapping_shl, u64);
195wrapping_shift_impl!(WrappingShl, wrapping_shl, usize);
196wrapping_shift_impl!(WrappingShl, wrapping_shl, u128);
197
198wrapping_shift_impl!(WrappingShl, wrapping_shl, i8);
199wrapping_shift_impl!(WrappingShl, wrapping_shl, i16);
200wrapping_shift_impl!(WrappingShl, wrapping_shl, i32);
201wrapping_shift_impl!(WrappingShl, wrapping_shl, i64);
202wrapping_shift_impl!(WrappingShl, wrapping_shl, isize);
203wrapping_shift_impl!(WrappingShl, wrapping_shl, i128);
204
205c0nst::c0nst! {
206pub c0nst trait WrappingShr: Sized + [c0nst] Shr<usize> {
208 fn wrapping_shr(self, rhs: u32) -> <Self as Shr<usize>>::Output;
223}
224}
225
226wrapping_shift_impl!(WrappingShr, wrapping_shr, u8);
227wrapping_shift_impl!(WrappingShr, wrapping_shr, u16);
228wrapping_shift_impl!(WrappingShr, wrapping_shr, u32);
229wrapping_shift_impl!(WrappingShr, wrapping_shr, u64);
230wrapping_shift_impl!(WrappingShr, wrapping_shr, usize);
231wrapping_shift_impl!(WrappingShr, wrapping_shr, u128);
232
233wrapping_shift_impl!(WrappingShr, wrapping_shr, i8);
234wrapping_shift_impl!(WrappingShr, wrapping_shr, i16);
235wrapping_shift_impl!(WrappingShr, wrapping_shr, i32);
236wrapping_shift_impl!(WrappingShr, wrapping_shr, i64);
237wrapping_shift_impl!(WrappingShr, wrapping_shr, isize);
238wrapping_shift_impl!(WrappingShr, wrapping_shr, i128);
239
240c0nst::c0nst! {
241pub c0nst trait WrappingDiv: Sized + [c0nst] Div<Self> {
243 fn wrapping_div(self, v: Self) -> <Self as Div<Self>>::Output;
262}
263}
264
265wrapping_impl!(WrappingDiv, wrapping_div, u8);
266wrapping_impl!(WrappingDiv, wrapping_div, u16);
267wrapping_impl!(WrappingDiv, wrapping_div, u32);
268wrapping_impl!(WrappingDiv, wrapping_div, u64);
269wrapping_impl!(WrappingDiv, wrapping_div, usize);
270wrapping_impl!(WrappingDiv, wrapping_div, u128);
271
272wrapping_impl!(WrappingDiv, wrapping_div, i8);
273wrapping_impl!(WrappingDiv, wrapping_div, i16);
274wrapping_impl!(WrappingDiv, wrapping_div, i32);
275wrapping_impl!(WrappingDiv, wrapping_div, i64);
276wrapping_impl!(WrappingDiv, wrapping_div, isize);
277wrapping_impl!(WrappingDiv, wrapping_div, i128);
278
279c0nst::c0nst! {
280pub c0nst trait WrappingRem: Sized + [c0nst] Rem<Self> {
282 fn wrapping_rem(self, v: Self) -> <Self as Rem<Self>>::Output;
300}
301}
302
303wrapping_impl!(WrappingRem, wrapping_rem, u8);
304wrapping_impl!(WrappingRem, wrapping_rem, u16);
305wrapping_impl!(WrappingRem, wrapping_rem, u32);
306wrapping_impl!(WrappingRem, wrapping_rem, u64);
307wrapping_impl!(WrappingRem, wrapping_rem, usize);
308wrapping_impl!(WrappingRem, wrapping_rem, u128);
309
310wrapping_impl!(WrappingRem, wrapping_rem, i8);
311wrapping_impl!(WrappingRem, wrapping_rem, i16);
312wrapping_impl!(WrappingRem, wrapping_rem, i32);
313wrapping_impl!(WrappingRem, wrapping_rem, i64);
314wrapping_impl!(WrappingRem, wrapping_rem, isize);
315wrapping_impl!(WrappingRem, wrapping_rem, i128);
316
317c0nst::c0nst! {
318pub c0nst trait WrappingAbs: Sized + [c0nst] Neg {
320 fn wrapping_abs(self) -> <Self as Neg>::Output;
331}
332}
333
334wrapping_unary_impl!(WrappingAbs, wrapping_abs, i8);
335wrapping_unary_impl!(WrappingAbs, wrapping_abs, i16);
336wrapping_unary_impl!(WrappingAbs, wrapping_abs, i32);
337wrapping_unary_impl!(WrappingAbs, wrapping_abs, i64);
338wrapping_unary_impl!(WrappingAbs, wrapping_abs, isize);
339wrapping_unary_impl!(WrappingAbs, wrapping_abs, i128);
340
341c0nst::c0nst! {
342pub c0nst trait WrappingPow: Sized + [c0nst] Mul<Self> {
344 fn wrapping_pow(self, exp: u32) -> <Self as Mul<Self>>::Output;
354}
355}
356
357wrapping_shift_impl!(WrappingPow, wrapping_pow, u8);
358wrapping_shift_impl!(WrappingPow, wrapping_pow, u16);
359wrapping_shift_impl!(WrappingPow, wrapping_pow, u32);
360wrapping_shift_impl!(WrappingPow, wrapping_pow, u64);
361wrapping_shift_impl!(WrappingPow, wrapping_pow, usize);
362wrapping_shift_impl!(WrappingPow, wrapping_pow, u128);
363
364wrapping_shift_impl!(WrappingPow, wrapping_pow, i8);
365wrapping_shift_impl!(WrappingPow, wrapping_pow, i16);
366wrapping_shift_impl!(WrappingPow, wrapping_pow, i32);
367wrapping_shift_impl!(WrappingPow, wrapping_pow, i64);
368wrapping_shift_impl!(WrappingPow, wrapping_pow, isize);
369wrapping_shift_impl!(WrappingPow, wrapping_pow, i128);
370
371#[test]
372fn test_wrapping_div_rem_abs_pow() {
373 assert_eq!(WrappingDiv::wrapping_div(i8::MIN, -1), i8::MIN);
374 assert_eq!(WrappingDiv::wrapping_div(100u8, 7), 14);
375 assert_eq!(WrappingRem::wrapping_rem(i8::MIN, -1), 0);
376 assert_eq!(WrappingRem::wrapping_rem(100u8, 7), 2);
377 assert_eq!(WrappingAbs::wrapping_abs(i16::MIN), i16::MIN);
378 assert_eq!(WrappingAbs::wrapping_abs(-7i16), 7);
379 assert_eq!(WrappingPow::wrapping_pow(3i8, 5), -13);
380 assert_eq!(WrappingPow::wrapping_pow(2u16, 16), 0);
381}
382
383impl<T: WrappingAdd<Output = T>> WrappingAdd for Wrapping<T>
386where
387 Wrapping<T>: Add<Output = Wrapping<T>>,
388{
389 fn wrapping_add(self, v: Self) -> Self {
390 Wrapping(self.0.wrapping_add(v.0))
391 }
392}
393impl<T: WrappingSub<Output = T>> WrappingSub for Wrapping<T>
394where
395 Wrapping<T>: Sub<Output = Wrapping<T>>,
396{
397 fn wrapping_sub(self, v: Self) -> Self {
398 Wrapping(self.0.wrapping_sub(v.0))
399 }
400}
401impl<T: WrappingMul<Output = T>> WrappingMul for Wrapping<T>
402where
403 Wrapping<T>: Mul<Output = Wrapping<T>>,
404{
405 fn wrapping_mul(self, v: Self) -> Self {
406 Wrapping(self.0.wrapping_mul(v.0))
407 }
408}
409impl<T: WrappingNeg<Output = T>> WrappingNeg for Wrapping<T>
410where
411 Wrapping<T>: Neg<Output = Wrapping<T>>,
412{
413 type Output = Wrapping<T>;
414 fn wrapping_neg(self) -> Self {
415 Wrapping(self.0.wrapping_neg())
416 }
417}
418impl<T: WrappingShl<Output = T>> WrappingShl for Wrapping<T>
419where
420 Wrapping<T>: Shl<usize, Output = Wrapping<T>>,
421{
422 fn wrapping_shl(self, rhs: u32) -> Self {
423 Wrapping(self.0.wrapping_shl(rhs))
424 }
425}
426impl<T: WrappingShr<Output = T>> WrappingShr for Wrapping<T>
427where
428 Wrapping<T>: Shr<usize, Output = Wrapping<T>>,
429{
430 fn wrapping_shr(self, rhs: u32) -> Self {
431 Wrapping(self.0.wrapping_shr(rhs))
432 }
433}
434
435#[test]
436fn test_wrapping_traits() {
437 fn wrapping_add<T: WrappingAdd<Output = T>>(a: T, b: T) -> T {
438 a.wrapping_add(b)
439 }
440 fn wrapping_sub<T: WrappingSub<Output = T>>(a: T, b: T) -> T {
441 a.wrapping_sub(b)
442 }
443 fn wrapping_mul<T: WrappingMul<Output = T>>(a: T, b: T) -> T {
444 a.wrapping_mul(b)
445 }
446 fn wrapping_neg<T: WrappingNeg<Output = T>>(a: T) -> T {
447 a.wrapping_neg()
448 }
449 fn wrapping_shl<T: WrappingShl<Output = T>>(a: T, b: u32) -> T {
450 a.wrapping_shl(b)
451 }
452 fn wrapping_shr<T: WrappingShr<Output = T>>(a: T, b: u32) -> T {
453 a.wrapping_shr(b)
454 }
455 assert_eq!(wrapping_add(255, 1), 0u8);
456 assert_eq!(wrapping_sub(0, 1), 255u8);
457 assert_eq!(wrapping_mul(255, 2), 254u8);
458 assert_eq!(wrapping_neg(255), 1u8);
459 assert_eq!(wrapping_shl(255, 8), 255u8);
460 assert_eq!(wrapping_shr(255, 8), 255u8);
461 assert_eq!(wrapping_add(255, 1), (Wrapping(255u8) + Wrapping(1u8)).0);
462 assert_eq!(wrapping_sub(0, 1), (Wrapping(0u8) - Wrapping(1u8)).0);
463 assert_eq!(wrapping_mul(255, 2), (Wrapping(255u8) * Wrapping(2u8)).0);
464 assert_eq!(wrapping_neg(255), (-Wrapping(255u8)).0);
465 assert_eq!(wrapping_shl(255, 8), (Wrapping(255u8) << 8).0);
466 assert_eq!(wrapping_shr(255, 8), (Wrapping(255u8) >> 8).0);
467}
468
469#[test]
470fn wrapping_is_wrappingadd() {
471 fn require_wrappingadd<T: WrappingAdd<Output = T>>(_: &T) {}
472 require_wrappingadd(&Wrapping(42));
473}
474
475#[test]
476fn wrapping_is_wrappingsub() {
477 fn require_wrappingsub<T: WrappingSub<Output = T>>(_: &T) {}
478 require_wrappingsub(&Wrapping(42));
479}
480
481#[test]
482fn wrapping_is_wrappingmul() {
483 fn require_wrappingmul<T: WrappingMul<Output = T>>(_: &T) {}
484 require_wrappingmul(&Wrapping(42));
485}
486
487#[test]
488fn wrapping_is_wrappingneg() {
489 fn require_wrappingneg<T: WrappingNeg<Output = T>>(_: &T) {}
490 require_wrappingneg(&Wrapping(42));
491}
492
493#[test]
494fn wrapping_is_wrappingshl() {
495 fn require_wrappingshl<T: WrappingShl<Output = T>>(_: &T) {}
496 require_wrappingshl(&Wrapping(42));
497}
498
499#[test]
500fn wrapping_is_wrappingshr() {
501 fn require_wrappingshr<T: WrappingShr<Output = T>>(_: &T) {}
502 require_wrappingshr(&Wrapping(42));
503}