1use super::prelude::*;
9
10macro_rules! wrapping_specs {
11 ([$(($uN: ty, $iN: ty, $modname_u:ident, $modname_i:ident, $range:expr),)*]) => {
12 $(
13 verus! {
14
15 pub mod $modname_u {
16 use super::*;
17
18 pub open spec fn wrapping_add(x: $uN, y: $uN) -> $uN {
19 if x + y > <$uN>::MAX {
20 (x + y - $range) as $uN
21 } else {
22 (x + y) as $uN
23 }
24 }
25
26 pub open spec fn wrapping_add_signed(x: $uN, y: $iN) -> $uN {
27 if x + y > <$uN>::MAX {
28 (x + y - $range) as $uN
29 } else if x + y < 0 {
30 (x + y + $range) as $uN
31 } else {
32 (x + y) as $uN
33 }
34 }
35
36 pub open spec fn wrapping_sub(x: $uN, y: $uN) -> $uN {
37 if x - y < 0 {
38 (x - y + $range) as $uN
39 } else {
40 (x - y) as $uN
41 }
42 }
43
44 pub open spec fn wrapping_mul(x: $uN, y: $uN) -> $uN {
45 ((x as nat * y as nat) % $range as nat) as $uN
46 }
47 }
48
49 pub mod $modname_i {
50 use super::*;
51
52 pub open spec fn wrapping_add(x: $iN, y: $iN) -> $iN {
53 if x + y > <$iN>::MAX {
54 (x + y - $range) as $iN
55 } else if x + y < <$iN>::MIN {
56 (x + y + $range) as $iN
57 } else {
58 (x + y) as $iN
59 }
60 }
61
62 pub open spec fn wrapping_add_unsigned(x: $iN, y: $uN) -> $iN {
63 if x + y > <$iN>::MAX {
64 (x + y - $range) as $iN
65 } else {
66 (x + y) as $iN
67 }
68 }
69
70 pub open spec fn wrapping_sub(x: $iN, y: $iN) -> $iN {
71 if x - y > <$iN>::MAX {
72 (x - y - $range) as $iN
73 } else if x - y < <$iN>::MIN {
74 (x - y + $range) as $iN
75 } else {
76 (x - y) as $iN
77 }
78 }
79
80 pub open spec fn signed_crop(x: int) -> $iN {
81 if (x % ($range as int)) > (<$iN>::MAX as int) {
82 ((x % ($range as int)) - $range) as $iN
83 } else {
84 (x % ($range as int)) as $iN
85 }
86 }
87
88 pub open spec fn wrapping_mul(x: $iN, y: $iN) -> $iN {
89 signed_crop(x * y)
90 }
91 }
92
93 }
94 )*
95
96 }
97}
98
99wrapping_specs!([
100 (u8, i8, u8_specs, i8_specs, 0x100),
101 (u16, i16, u16_specs, i16_specs, 0x1_0000),
102 (u32, i32, u32_specs, i32_specs, 0x1_0000_0000),
103 (u64, i64, u64_specs, i64_specs, 0x1_0000_0000_0000_0000),
104 (u128, i128, u128_specs, i128_specs, 0x1_0000_0000_0000_0000_0000_0000_0000_0000),
105 (usize, isize, usize_specs, isize_specs, (usize::MAX - usize::MIN + 1)),
106]);