1use core::num::Wrapping;
9
10macro_rules! wrapping_impl {
11 ($trait_name:ident, $method:ident, $t:ty) => {
12 c0nst::c0nst! {
13 c0nst impl $trait_name for $t {
14 type Output = $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 type Output = $t;
26 #[inline]
27 fn $method(self, v: $rhs) -> Self {
28 <$t>::$method(self, v)
29 }
30 }
31 }
32 };
33}
34
35c0nst::c0nst! {
36pub c0nst trait WrappingAdd: Sized {
38 type Output;
40 fn wrapping_add(self, v: Self) -> Self::Output;
43}
44}
45
46wrapping_impl!(WrappingAdd, wrapping_add, u8);
47wrapping_impl!(WrappingAdd, wrapping_add, u16);
48wrapping_impl!(WrappingAdd, wrapping_add, u32);
49wrapping_impl!(WrappingAdd, wrapping_add, u64);
50wrapping_impl!(WrappingAdd, wrapping_add, usize);
51wrapping_impl!(WrappingAdd, wrapping_add, u128);
52
53wrapping_impl!(WrappingAdd, wrapping_add, i8);
54wrapping_impl!(WrappingAdd, wrapping_add, i16);
55wrapping_impl!(WrappingAdd, wrapping_add, i32);
56wrapping_impl!(WrappingAdd, wrapping_add, i64);
57wrapping_impl!(WrappingAdd, wrapping_add, isize);
58wrapping_impl!(WrappingAdd, wrapping_add, i128);
59
60c0nst::c0nst! {
61pub c0nst trait WrappingSub: Sized {
63 type Output;
65 fn wrapping_sub(self, v: Self) -> Self::Output;
68}
69}
70
71wrapping_impl!(WrappingSub, wrapping_sub, u8);
72wrapping_impl!(WrappingSub, wrapping_sub, u16);
73wrapping_impl!(WrappingSub, wrapping_sub, u32);
74wrapping_impl!(WrappingSub, wrapping_sub, u64);
75wrapping_impl!(WrappingSub, wrapping_sub, usize);
76wrapping_impl!(WrappingSub, wrapping_sub, u128);
77
78wrapping_impl!(WrappingSub, wrapping_sub, i8);
79wrapping_impl!(WrappingSub, wrapping_sub, i16);
80wrapping_impl!(WrappingSub, wrapping_sub, i32);
81wrapping_impl!(WrappingSub, wrapping_sub, i64);
82wrapping_impl!(WrappingSub, wrapping_sub, isize);
83wrapping_impl!(WrappingSub, wrapping_sub, i128);
84
85c0nst::c0nst! {
86pub c0nst trait WrappingMul: Sized {
88 type Output;
90 fn wrapping_mul(self, v: Self) -> Self::Output;
93}
94}
95
96wrapping_impl!(WrappingMul, wrapping_mul, u8);
97wrapping_impl!(WrappingMul, wrapping_mul, u16);
98wrapping_impl!(WrappingMul, wrapping_mul, u32);
99wrapping_impl!(WrappingMul, wrapping_mul, u64);
100wrapping_impl!(WrappingMul, wrapping_mul, usize);
101wrapping_impl!(WrappingMul, wrapping_mul, u128);
102
103wrapping_impl!(WrappingMul, wrapping_mul, i8);
104wrapping_impl!(WrappingMul, wrapping_mul, i16);
105wrapping_impl!(WrappingMul, wrapping_mul, i32);
106wrapping_impl!(WrappingMul, wrapping_mul, i64);
107wrapping_impl!(WrappingMul, wrapping_mul, isize);
108wrapping_impl!(WrappingMul, wrapping_mul, i128);
109
110macro_rules! wrapping_neg_impl {
111 ($($t:ty)*) => {$(
112 c0nst::c0nst! {
113 c0nst impl WrappingNeg for $t {
114 type Output = $t;
115 #[inline]
116 fn wrapping_neg(self) -> $t {
117 <$t>::wrapping_neg(self)
118 }
119 }
120 }
121 )*};
122}
123
124macro_rules! wrapping_unary_impl {
125 ($trait_name:ident, $method:ident, $t:ty) => {
126 c0nst::c0nst! {
127 c0nst impl $trait_name for $t {
128 type Output = $t;
129 #[inline]
130 fn $method(self) -> $t {
131 <$t>::$method(self)
132 }
133 }
134 }
135 };
136}
137
138c0nst::c0nst! {
139pub c0nst trait WrappingNeg: Sized {
141 type Output;
159 fn wrapping_neg(self) -> Self::Output;
160}
161}
162
163wrapping_neg_impl!(u8 u16 u32 u64 usize u128 i8 i16 i32 i64 isize i128);
164
165macro_rules! wrapping_shift_impl {
166 ($trait_name:ident, $method:ident, $t:ty) => {
167 c0nst::c0nst! {
168 c0nst impl $trait_name for $t {
169 type Output = $t;
170 #[inline]
171 fn $method(self, rhs: u32) -> $t {
172 <$t>::$method(self, rhs)
173 }
174 }
175 }
176 };
177}
178
179c0nst::c0nst! {
180pub c0nst trait WrappingShl: Sized {
182 type Output;
184 fn wrapping_shl(self, rhs: u32) -> Self::Output;
199}
200}
201
202wrapping_shift_impl!(WrappingShl, wrapping_shl, u8);
203wrapping_shift_impl!(WrappingShl, wrapping_shl, u16);
204wrapping_shift_impl!(WrappingShl, wrapping_shl, u32);
205wrapping_shift_impl!(WrappingShl, wrapping_shl, u64);
206wrapping_shift_impl!(WrappingShl, wrapping_shl, usize);
207wrapping_shift_impl!(WrappingShl, wrapping_shl, u128);
208
209wrapping_shift_impl!(WrappingShl, wrapping_shl, i8);
210wrapping_shift_impl!(WrappingShl, wrapping_shl, i16);
211wrapping_shift_impl!(WrappingShl, wrapping_shl, i32);
212wrapping_shift_impl!(WrappingShl, wrapping_shl, i64);
213wrapping_shift_impl!(WrappingShl, wrapping_shl, isize);
214wrapping_shift_impl!(WrappingShl, wrapping_shl, i128);
215
216c0nst::c0nst! {
217pub c0nst trait WrappingShr: Sized {
219 type Output;
221 fn wrapping_shr(self, rhs: u32) -> Self::Output;
236}
237}
238
239wrapping_shift_impl!(WrappingShr, wrapping_shr, u8);
240wrapping_shift_impl!(WrappingShr, wrapping_shr, u16);
241wrapping_shift_impl!(WrappingShr, wrapping_shr, u32);
242wrapping_shift_impl!(WrappingShr, wrapping_shr, u64);
243wrapping_shift_impl!(WrappingShr, wrapping_shr, usize);
244wrapping_shift_impl!(WrappingShr, wrapping_shr, u128);
245
246wrapping_shift_impl!(WrappingShr, wrapping_shr, i8);
247wrapping_shift_impl!(WrappingShr, wrapping_shr, i16);
248wrapping_shift_impl!(WrappingShr, wrapping_shr, i32);
249wrapping_shift_impl!(WrappingShr, wrapping_shr, i64);
250wrapping_shift_impl!(WrappingShr, wrapping_shr, isize);
251wrapping_shift_impl!(WrappingShr, wrapping_shr, i128);
252
253c0nst::c0nst! {
254pub c0nst trait WrappingDiv: Sized {
256 type Output;
258 fn wrapping_div(self, v: Self) -> Self::Output;
277}
278}
279
280wrapping_impl!(WrappingDiv, wrapping_div, u8);
281wrapping_impl!(WrappingDiv, wrapping_div, u16);
282wrapping_impl!(WrappingDiv, wrapping_div, u32);
283wrapping_impl!(WrappingDiv, wrapping_div, u64);
284wrapping_impl!(WrappingDiv, wrapping_div, usize);
285wrapping_impl!(WrappingDiv, wrapping_div, u128);
286
287wrapping_impl!(WrappingDiv, wrapping_div, i8);
288wrapping_impl!(WrappingDiv, wrapping_div, i16);
289wrapping_impl!(WrappingDiv, wrapping_div, i32);
290wrapping_impl!(WrappingDiv, wrapping_div, i64);
291wrapping_impl!(WrappingDiv, wrapping_div, isize);
292wrapping_impl!(WrappingDiv, wrapping_div, i128);
293
294c0nst::c0nst! {
295pub c0nst trait WrappingRem: Sized {
297 type Output;
299 fn wrapping_rem(self, v: Self) -> Self::Output;
317}
318}
319
320wrapping_impl!(WrappingRem, wrapping_rem, u8);
321wrapping_impl!(WrappingRem, wrapping_rem, u16);
322wrapping_impl!(WrappingRem, wrapping_rem, u32);
323wrapping_impl!(WrappingRem, wrapping_rem, u64);
324wrapping_impl!(WrappingRem, wrapping_rem, usize);
325wrapping_impl!(WrappingRem, wrapping_rem, u128);
326
327wrapping_impl!(WrappingRem, wrapping_rem, i8);
328wrapping_impl!(WrappingRem, wrapping_rem, i16);
329wrapping_impl!(WrappingRem, wrapping_rem, i32);
330wrapping_impl!(WrappingRem, wrapping_rem, i64);
331wrapping_impl!(WrappingRem, wrapping_rem, isize);
332wrapping_impl!(WrappingRem, wrapping_rem, i128);
333
334c0nst::c0nst! {
335pub c0nst trait WrappingAbs: Sized {
337 type Output;
339 fn wrapping_abs(self) -> Self::Output;
350}
351}
352
353wrapping_unary_impl!(WrappingAbs, wrapping_abs, i8);
354wrapping_unary_impl!(WrappingAbs, wrapping_abs, i16);
355wrapping_unary_impl!(WrappingAbs, wrapping_abs, i32);
356wrapping_unary_impl!(WrappingAbs, wrapping_abs, i64);
357wrapping_unary_impl!(WrappingAbs, wrapping_abs, isize);
358wrapping_unary_impl!(WrappingAbs, wrapping_abs, i128);
359
360c0nst::c0nst! {
361pub c0nst trait WrappingPow: Sized {
363 type Output;
365 fn wrapping_pow(self, exp: u32) -> Self::Output;
375}
376}
377
378wrapping_shift_impl!(WrappingPow, wrapping_pow, u8);
379wrapping_shift_impl!(WrappingPow, wrapping_pow, u16);
380wrapping_shift_impl!(WrappingPow, wrapping_pow, u32);
381wrapping_shift_impl!(WrappingPow, wrapping_pow, u64);
382wrapping_shift_impl!(WrappingPow, wrapping_pow, usize);
383wrapping_shift_impl!(WrappingPow, wrapping_pow, u128);
384
385wrapping_shift_impl!(WrappingPow, wrapping_pow, i8);
386wrapping_shift_impl!(WrappingPow, wrapping_pow, i16);
387wrapping_shift_impl!(WrappingPow, wrapping_pow, i32);
388wrapping_shift_impl!(WrappingPow, wrapping_pow, i64);
389wrapping_shift_impl!(WrappingPow, wrapping_pow, isize);
390wrapping_shift_impl!(WrappingPow, wrapping_pow, i128);
391
392#[test]
393fn test_wrapping_div_rem_abs_pow() {
394 assert_eq!(WrappingDiv::wrapping_div(i8::MIN, -1), i8::MIN);
395 assert_eq!(WrappingDiv::wrapping_div(100u8, 7), 14);
396 assert_eq!(WrappingRem::wrapping_rem(i8::MIN, -1), 0);
397 assert_eq!(WrappingRem::wrapping_rem(100u8, 7), 2);
398 assert_eq!(WrappingAbs::wrapping_abs(i16::MIN), i16::MIN);
399 assert_eq!(WrappingAbs::wrapping_abs(-7i16), 7);
400 assert_eq!(WrappingPow::wrapping_pow(3i8, 5), -13);
401 assert_eq!(WrappingPow::wrapping_pow(2u16, 16), 0);
402}
403
404impl<T: WrappingAdd<Output = T>> WrappingAdd for Wrapping<T> {
407 type Output = Wrapping<T>;
408 fn wrapping_add(self, v: Self) -> Self {
409 Wrapping(self.0.wrapping_add(v.0))
410 }
411}
412impl<T: WrappingSub<Output = T>> WrappingSub for Wrapping<T> {
413 type Output = Wrapping<T>;
414 fn wrapping_sub(self, v: Self) -> Self {
415 Wrapping(self.0.wrapping_sub(v.0))
416 }
417}
418impl<T: WrappingMul<Output = T>> WrappingMul for Wrapping<T> {
419 type Output = Wrapping<T>;
420 fn wrapping_mul(self, v: Self) -> Self {
421 Wrapping(self.0.wrapping_mul(v.0))
422 }
423}
424impl<T: WrappingNeg<Output = T>> WrappingNeg for Wrapping<T> {
425 type Output = Wrapping<T>;
426 fn wrapping_neg(self) -> Self {
427 Wrapping(self.0.wrapping_neg())
428 }
429}
430impl<T: WrappingShl<Output = T>> WrappingShl for Wrapping<T> {
431 type Output = Wrapping<T>;
432 fn wrapping_shl(self, rhs: u32) -> Self {
433 Wrapping(self.0.wrapping_shl(rhs))
434 }
435}
436impl<T: WrappingShr<Output = T>> WrappingShr for Wrapping<T> {
437 type Output = Wrapping<T>;
438 fn wrapping_shr(self, rhs: u32) -> Self {
439 Wrapping(self.0.wrapping_shr(rhs))
440 }
441}
442
443#[test]
444fn test_wrapping_traits() {
445 fn wrapping_add<T: WrappingAdd<Output = T>>(a: T, b: T) -> T {
446 a.wrapping_add(b)
447 }
448 fn wrapping_sub<T: WrappingSub<Output = T>>(a: T, b: T) -> T {
449 a.wrapping_sub(b)
450 }
451 fn wrapping_mul<T: WrappingMul<Output = T>>(a: T, b: T) -> T {
452 a.wrapping_mul(b)
453 }
454 fn wrapping_neg<T: WrappingNeg<Output = T>>(a: T) -> T {
455 a.wrapping_neg()
456 }
457 fn wrapping_shl<T: WrappingShl<Output = T>>(a: T, b: u32) -> T {
458 a.wrapping_shl(b)
459 }
460 fn wrapping_shr<T: WrappingShr<Output = T>>(a: T, b: u32) -> T {
461 a.wrapping_shr(b)
462 }
463 assert_eq!(wrapping_add(255, 1), 0u8);
464 assert_eq!(wrapping_sub(0, 1), 255u8);
465 assert_eq!(wrapping_mul(255, 2), 254u8);
466 assert_eq!(wrapping_neg(255), 1u8);
467 assert_eq!(wrapping_shl(255, 8), 255u8);
468 assert_eq!(wrapping_shr(255, 8), 255u8);
469 assert_eq!(wrapping_add(255, 1), (Wrapping(255u8) + Wrapping(1u8)).0);
470 assert_eq!(wrapping_sub(0, 1), (Wrapping(0u8) - Wrapping(1u8)).0);
471 assert_eq!(wrapping_mul(255, 2), (Wrapping(255u8) * Wrapping(2u8)).0);
472 assert_eq!(wrapping_neg(255), (-Wrapping(255u8)).0);
473 assert_eq!(wrapping_shl(255, 8), (Wrapping(255u8) << 8).0);
474 assert_eq!(wrapping_shr(255, 8), (Wrapping(255u8) >> 8).0);
475}
476
477#[test]
478fn wrapping_is_wrappingadd() {
479 fn require_wrappingadd<T: WrappingAdd<Output = T>>(_: &T) {}
480 require_wrappingadd(&Wrapping(42));
481}
482
483#[test]
484fn wrapping_is_wrappingsub() {
485 fn require_wrappingsub<T: WrappingSub<Output = T>>(_: &T) {}
486 require_wrappingsub(&Wrapping(42));
487}
488
489#[test]
490fn wrapping_is_wrappingmul() {
491 fn require_wrappingmul<T: WrappingMul<Output = T>>(_: &T) {}
492 require_wrappingmul(&Wrapping(42));
493}
494
495#[test]
496fn wrapping_is_wrappingneg() {
497 fn require_wrappingneg<T: WrappingNeg<Output = T>>(_: &T) {}
498 require_wrappingneg(&Wrapping(42));
499}
500
501#[test]
502fn wrapping_is_wrappingshl() {
503 fn require_wrappingshl<T: WrappingShl<Output = T>>(_: &T) {}
504 require_wrappingshl(&Wrapping(42));
505}
506
507#[test]
508fn wrapping_is_wrappingshr() {
509 fn require_wrappingshr<T: WrappingShr<Output = T>>(_: &T) {}
510 require_wrappingshr(&Wrapping(42));
511}