Coverage Report

Created: 2025-08-28 06:06

/rust/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.15/src/ops/wrapping.rs
Line
Count
Source (jump to first uncovered line)
1
use core::num::Wrapping;
2
use core::ops::{Add, Mul, Neg, Shl, Shr, Sub};
3
4
macro_rules! wrapping_impl {
5
    ($trait_name:ident, $method:ident, $t:ty) => {
6
        impl $trait_name for $t {
7
            #[inline]
8
0
            fn $method(&self, v: &Self) -> Self {
9
0
                <$t>::$method(*self, *v)
10
0
            }
Unexecuted instantiation: <u8 as num_traits::ops::wrapping::WrappingAdd>::wrapping_add
Unexecuted instantiation: <u16 as num_traits::ops::wrapping::WrappingAdd>::wrapping_add
Unexecuted instantiation: <u32 as num_traits::ops::wrapping::WrappingAdd>::wrapping_add
Unexecuted instantiation: <u64 as num_traits::ops::wrapping::WrappingAdd>::wrapping_add
Unexecuted instantiation: <usize as num_traits::ops::wrapping::WrappingAdd>::wrapping_add
Unexecuted instantiation: <u128 as num_traits::ops::wrapping::WrappingAdd>::wrapping_add
Unexecuted instantiation: <i8 as num_traits::ops::wrapping::WrappingAdd>::wrapping_add
Unexecuted instantiation: <i16 as num_traits::ops::wrapping::WrappingAdd>::wrapping_add
Unexecuted instantiation: <i32 as num_traits::ops::wrapping::WrappingAdd>::wrapping_add
Unexecuted instantiation: <i64 as num_traits::ops::wrapping::WrappingAdd>::wrapping_add
Unexecuted instantiation: <isize as num_traits::ops::wrapping::WrappingAdd>::wrapping_add
Unexecuted instantiation: <i128 as num_traits::ops::wrapping::WrappingAdd>::wrapping_add
Unexecuted instantiation: <u8 as num_traits::ops::wrapping::WrappingSub>::wrapping_sub
Unexecuted instantiation: <u16 as num_traits::ops::wrapping::WrappingSub>::wrapping_sub
Unexecuted instantiation: <u32 as num_traits::ops::wrapping::WrappingSub>::wrapping_sub
Unexecuted instantiation: <u64 as num_traits::ops::wrapping::WrappingSub>::wrapping_sub
Unexecuted instantiation: <usize as num_traits::ops::wrapping::WrappingSub>::wrapping_sub
Unexecuted instantiation: <u128 as num_traits::ops::wrapping::WrappingSub>::wrapping_sub
Unexecuted instantiation: <i8 as num_traits::ops::wrapping::WrappingSub>::wrapping_sub
Unexecuted instantiation: <i16 as num_traits::ops::wrapping::WrappingSub>::wrapping_sub
Unexecuted instantiation: <i32 as num_traits::ops::wrapping::WrappingSub>::wrapping_sub
Unexecuted instantiation: <i64 as num_traits::ops::wrapping::WrappingSub>::wrapping_sub
Unexecuted instantiation: <isize as num_traits::ops::wrapping::WrappingSub>::wrapping_sub
Unexecuted instantiation: <i128 as num_traits::ops::wrapping::WrappingSub>::wrapping_sub
Unexecuted instantiation: <u8 as num_traits::ops::wrapping::WrappingMul>::wrapping_mul
Unexecuted instantiation: <u16 as num_traits::ops::wrapping::WrappingMul>::wrapping_mul
Unexecuted instantiation: <u32 as num_traits::ops::wrapping::WrappingMul>::wrapping_mul
Unexecuted instantiation: <u64 as num_traits::ops::wrapping::WrappingMul>::wrapping_mul
Unexecuted instantiation: <usize as num_traits::ops::wrapping::WrappingMul>::wrapping_mul
Unexecuted instantiation: <u128 as num_traits::ops::wrapping::WrappingMul>::wrapping_mul
Unexecuted instantiation: <i8 as num_traits::ops::wrapping::WrappingMul>::wrapping_mul
Unexecuted instantiation: <i16 as num_traits::ops::wrapping::WrappingMul>::wrapping_mul
Unexecuted instantiation: <i32 as num_traits::ops::wrapping::WrappingMul>::wrapping_mul
Unexecuted instantiation: <i64 as num_traits::ops::wrapping::WrappingMul>::wrapping_mul
Unexecuted instantiation: <isize as num_traits::ops::wrapping::WrappingMul>::wrapping_mul
Unexecuted instantiation: <i128 as num_traits::ops::wrapping::WrappingMul>::wrapping_mul
11
        }
12
    };
13
    ($trait_name:ident, $method:ident, $t:ty, $rhs:ty) => {
14
        impl $trait_name<$rhs> for $t {
15
            #[inline]
16
            fn $method(&self, v: &$rhs) -> Self {
17
                <$t>::$method(*self, *v)
18
            }
19
        }
20
    };
21
}
22
23
/// Performs addition that wraps around on overflow.
24
pub trait WrappingAdd: Sized + Add<Self, Output = Self> {
25
    /// Wrapping (modular) addition. Computes `self + other`, wrapping around at the boundary of
26
    /// the type.
27
    fn wrapping_add(&self, v: &Self) -> Self;
28
}
29
30
wrapping_impl!(WrappingAdd, wrapping_add, u8);
31
wrapping_impl!(WrappingAdd, wrapping_add, u16);
32
wrapping_impl!(WrappingAdd, wrapping_add, u32);
33
wrapping_impl!(WrappingAdd, wrapping_add, u64);
34
wrapping_impl!(WrappingAdd, wrapping_add, usize);
35
#[cfg(has_i128)]
36
wrapping_impl!(WrappingAdd, wrapping_add, u128);
37
38
wrapping_impl!(WrappingAdd, wrapping_add, i8);
39
wrapping_impl!(WrappingAdd, wrapping_add, i16);
40
wrapping_impl!(WrappingAdd, wrapping_add, i32);
41
wrapping_impl!(WrappingAdd, wrapping_add, i64);
42
wrapping_impl!(WrappingAdd, wrapping_add, isize);
43
#[cfg(has_i128)]
44
wrapping_impl!(WrappingAdd, wrapping_add, i128);
45
46
/// Performs subtraction that wraps around on overflow.
47
pub trait WrappingSub: Sized + Sub<Self, Output = Self> {
48
    /// Wrapping (modular) subtraction. Computes `self - other`, wrapping around at the boundary
49
    /// of the type.
50
    fn wrapping_sub(&self, v: &Self) -> Self;
51
}
52
53
wrapping_impl!(WrappingSub, wrapping_sub, u8);
54
wrapping_impl!(WrappingSub, wrapping_sub, u16);
55
wrapping_impl!(WrappingSub, wrapping_sub, u32);
56
wrapping_impl!(WrappingSub, wrapping_sub, u64);
57
wrapping_impl!(WrappingSub, wrapping_sub, usize);
58
#[cfg(has_i128)]
59
wrapping_impl!(WrappingSub, wrapping_sub, u128);
60
61
wrapping_impl!(WrappingSub, wrapping_sub, i8);
62
wrapping_impl!(WrappingSub, wrapping_sub, i16);
63
wrapping_impl!(WrappingSub, wrapping_sub, i32);
64
wrapping_impl!(WrappingSub, wrapping_sub, i64);
65
wrapping_impl!(WrappingSub, wrapping_sub, isize);
66
#[cfg(has_i128)]
67
wrapping_impl!(WrappingSub, wrapping_sub, i128);
68
69
/// Performs multiplication that wraps around on overflow.
70
pub trait WrappingMul: Sized + Mul<Self, Output = Self> {
71
    /// Wrapping (modular) multiplication. Computes `self * other`, wrapping around at the boundary
72
    /// of the type.
73
    fn wrapping_mul(&self, v: &Self) -> Self;
74
}
75
76
wrapping_impl!(WrappingMul, wrapping_mul, u8);
77
wrapping_impl!(WrappingMul, wrapping_mul, u16);
78
wrapping_impl!(WrappingMul, wrapping_mul, u32);
79
wrapping_impl!(WrappingMul, wrapping_mul, u64);
80
wrapping_impl!(WrappingMul, wrapping_mul, usize);
81
#[cfg(has_i128)]
82
wrapping_impl!(WrappingMul, wrapping_mul, u128);
83
84
wrapping_impl!(WrappingMul, wrapping_mul, i8);
85
wrapping_impl!(WrappingMul, wrapping_mul, i16);
86
wrapping_impl!(WrappingMul, wrapping_mul, i32);
87
wrapping_impl!(WrappingMul, wrapping_mul, i64);
88
wrapping_impl!(WrappingMul, wrapping_mul, isize);
89
#[cfg(has_i128)]
90
wrapping_impl!(WrappingMul, wrapping_mul, i128);
91
92
macro_rules! wrapping_unary_impl {
93
    ($trait_name:ident, $method:ident, $t:ty) => {
94
        impl $trait_name for $t {
95
            #[inline]
96
0
            fn $method(&self) -> $t {
97
0
                <$t>::$method(*self)
98
0
            }
Unexecuted instantiation: <u8 as num_traits::ops::wrapping::WrappingNeg>::wrapping_neg
Unexecuted instantiation: <u16 as num_traits::ops::wrapping::WrappingNeg>::wrapping_neg
Unexecuted instantiation: <u32 as num_traits::ops::wrapping::WrappingNeg>::wrapping_neg
Unexecuted instantiation: <u64 as num_traits::ops::wrapping::WrappingNeg>::wrapping_neg
Unexecuted instantiation: <usize as num_traits::ops::wrapping::WrappingNeg>::wrapping_neg
Unexecuted instantiation: <u128 as num_traits::ops::wrapping::WrappingNeg>::wrapping_neg
Unexecuted instantiation: <i8 as num_traits::ops::wrapping::WrappingNeg>::wrapping_neg
Unexecuted instantiation: <i16 as num_traits::ops::wrapping::WrappingNeg>::wrapping_neg
Unexecuted instantiation: <i32 as num_traits::ops::wrapping::WrappingNeg>::wrapping_neg
Unexecuted instantiation: <i64 as num_traits::ops::wrapping::WrappingNeg>::wrapping_neg
Unexecuted instantiation: <isize as num_traits::ops::wrapping::WrappingNeg>::wrapping_neg
Unexecuted instantiation: <i128 as num_traits::ops::wrapping::WrappingNeg>::wrapping_neg
99
        }
100
    };
101
}
102
103
/// Performs a negation that does not panic.
104
pub trait WrappingNeg: Sized {
105
    /// Wrapping (modular) negation. Computes `-self`,
106
    /// wrapping around at the boundary of the type.
107
    ///
108
    /// Since unsigned types do not have negative equivalents
109
    /// all applications of this function will wrap (except for `-0`).
110
    /// For values smaller than the corresponding signed type's maximum
111
    /// the result is the same as casting the corresponding signed value.
112
    /// Any larger values are equivalent to `MAX + 1 - (val - MAX - 1)` where
113
    /// `MAX` is the corresponding signed type's maximum.
114
    ///
115
    /// ```
116
    /// use num_traits::WrappingNeg;
117
    ///
118
    /// assert_eq!(100i8.wrapping_neg(), -100);
119
    /// assert_eq!((-100i8).wrapping_neg(), 100);
120
    /// assert_eq!((-128i8).wrapping_neg(), -128); // wrapped!
121
    /// ```
122
    fn wrapping_neg(&self) -> Self;
123
}
124
125
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u8);
126
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u16);
127
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u32);
128
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u64);
129
wrapping_unary_impl!(WrappingNeg, wrapping_neg, usize);
130
#[cfg(has_i128)]
131
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u128);
132
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i8);
133
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i16);
134
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i32);
135
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i64);
136
wrapping_unary_impl!(WrappingNeg, wrapping_neg, isize);
137
#[cfg(has_i128)]
138
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i128);
139
140
macro_rules! wrapping_shift_impl {
141
    ($trait_name:ident, $method:ident, $t:ty) => {
142
        impl $trait_name for $t {
143
            #[inline]
144
0
            fn $method(&self, rhs: u32) -> $t {
145
0
                <$t>::$method(*self, rhs)
146
0
            }
Unexecuted instantiation: <u8 as num_traits::ops::wrapping::WrappingShl>::wrapping_shl
Unexecuted instantiation: <u16 as num_traits::ops::wrapping::WrappingShl>::wrapping_shl
Unexecuted instantiation: <u32 as num_traits::ops::wrapping::WrappingShl>::wrapping_shl
Unexecuted instantiation: <u64 as num_traits::ops::wrapping::WrappingShl>::wrapping_shl
Unexecuted instantiation: <usize as num_traits::ops::wrapping::WrappingShl>::wrapping_shl
Unexecuted instantiation: <u128 as num_traits::ops::wrapping::WrappingShl>::wrapping_shl
Unexecuted instantiation: <i8 as num_traits::ops::wrapping::WrappingShl>::wrapping_shl
Unexecuted instantiation: <i16 as num_traits::ops::wrapping::WrappingShl>::wrapping_shl
Unexecuted instantiation: <i32 as num_traits::ops::wrapping::WrappingShl>::wrapping_shl
Unexecuted instantiation: <i64 as num_traits::ops::wrapping::WrappingShl>::wrapping_shl
Unexecuted instantiation: <isize as num_traits::ops::wrapping::WrappingShl>::wrapping_shl
Unexecuted instantiation: <i128 as num_traits::ops::wrapping::WrappingShl>::wrapping_shl
Unexecuted instantiation: <u8 as num_traits::ops::wrapping::WrappingShr>::wrapping_shr
Unexecuted instantiation: <u16 as num_traits::ops::wrapping::WrappingShr>::wrapping_shr
Unexecuted instantiation: <u32 as num_traits::ops::wrapping::WrappingShr>::wrapping_shr
Unexecuted instantiation: <u64 as num_traits::ops::wrapping::WrappingShr>::wrapping_shr
Unexecuted instantiation: <usize as num_traits::ops::wrapping::WrappingShr>::wrapping_shr
Unexecuted instantiation: <u128 as num_traits::ops::wrapping::WrappingShr>::wrapping_shr
Unexecuted instantiation: <i8 as num_traits::ops::wrapping::WrappingShr>::wrapping_shr
Unexecuted instantiation: <i16 as num_traits::ops::wrapping::WrappingShr>::wrapping_shr
Unexecuted instantiation: <i32 as num_traits::ops::wrapping::WrappingShr>::wrapping_shr
Unexecuted instantiation: <i64 as num_traits::ops::wrapping::WrappingShr>::wrapping_shr
Unexecuted instantiation: <isize as num_traits::ops::wrapping::WrappingShr>::wrapping_shr
Unexecuted instantiation: <i128 as num_traits::ops::wrapping::WrappingShr>::wrapping_shr
147
        }
148
    };
149
}
150
151
/// Performs a left shift that does not panic.
152
pub trait WrappingShl: Sized + Shl<usize, Output = Self> {
153
    /// Panic-free bitwise shift-left; yields `self << mask(rhs)`,
154
    /// where `mask` removes any high order bits of `rhs` that would
155
    /// cause the shift to exceed the bitwidth of the type.
156
    ///
157
    /// ```
158
    /// use num_traits::WrappingShl;
159
    ///
160
    /// let x: u16 = 0x0001;
161
    ///
162
    /// assert_eq!(WrappingShl::wrapping_shl(&x, 0),  0x0001);
163
    /// assert_eq!(WrappingShl::wrapping_shl(&x, 1),  0x0002);
164
    /// assert_eq!(WrappingShl::wrapping_shl(&x, 15), 0x8000);
165
    /// assert_eq!(WrappingShl::wrapping_shl(&x, 16), 0x0001);
166
    /// ```
167
    fn wrapping_shl(&self, rhs: u32) -> Self;
168
}
169
170
wrapping_shift_impl!(WrappingShl, wrapping_shl, u8);
171
wrapping_shift_impl!(WrappingShl, wrapping_shl, u16);
172
wrapping_shift_impl!(WrappingShl, wrapping_shl, u32);
173
wrapping_shift_impl!(WrappingShl, wrapping_shl, u64);
174
wrapping_shift_impl!(WrappingShl, wrapping_shl, usize);
175
#[cfg(has_i128)]
176
wrapping_shift_impl!(WrappingShl, wrapping_shl, u128);
177
178
wrapping_shift_impl!(WrappingShl, wrapping_shl, i8);
179
wrapping_shift_impl!(WrappingShl, wrapping_shl, i16);
180
wrapping_shift_impl!(WrappingShl, wrapping_shl, i32);
181
wrapping_shift_impl!(WrappingShl, wrapping_shl, i64);
182
wrapping_shift_impl!(WrappingShl, wrapping_shl, isize);
183
#[cfg(has_i128)]
184
wrapping_shift_impl!(WrappingShl, wrapping_shl, i128);
185
186
/// Performs a right shift that does not panic.
187
pub trait WrappingShr: Sized + Shr<usize, Output = Self> {
188
    /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`,
189
    /// where `mask` removes any high order bits of `rhs` that would
190
    /// cause the shift to exceed the bitwidth of the type.
191
    ///
192
    /// ```
193
    /// use num_traits::WrappingShr;
194
    ///
195
    /// let x: u16 = 0x8000;
196
    ///
197
    /// assert_eq!(WrappingShr::wrapping_shr(&x, 0),  0x8000);
198
    /// assert_eq!(WrappingShr::wrapping_shr(&x, 1),  0x4000);
199
    /// assert_eq!(WrappingShr::wrapping_shr(&x, 15), 0x0001);
200
    /// assert_eq!(WrappingShr::wrapping_shr(&x, 16), 0x8000);
201
    /// ```
202
    fn wrapping_shr(&self, rhs: u32) -> Self;
203
}
204
205
wrapping_shift_impl!(WrappingShr, wrapping_shr, u8);
206
wrapping_shift_impl!(WrappingShr, wrapping_shr, u16);
207
wrapping_shift_impl!(WrappingShr, wrapping_shr, u32);
208
wrapping_shift_impl!(WrappingShr, wrapping_shr, u64);
209
wrapping_shift_impl!(WrappingShr, wrapping_shr, usize);
210
#[cfg(has_i128)]
211
wrapping_shift_impl!(WrappingShr, wrapping_shr, u128);
212
213
wrapping_shift_impl!(WrappingShr, wrapping_shr, i8);
214
wrapping_shift_impl!(WrappingShr, wrapping_shr, i16);
215
wrapping_shift_impl!(WrappingShr, wrapping_shr, i32);
216
wrapping_shift_impl!(WrappingShr, wrapping_shr, i64);
217
wrapping_shift_impl!(WrappingShr, wrapping_shr, isize);
218
#[cfg(has_i128)]
219
wrapping_shift_impl!(WrappingShr, wrapping_shr, i128);
220
221
// Well this is a bit funny, but all the more appropriate.
222
impl<T: WrappingAdd> WrappingAdd for Wrapping<T>
223
where
224
    Wrapping<T>: Add<Output = Wrapping<T>>,
225
{
226
0
    fn wrapping_add(&self, v: &Self) -> Self {
227
0
        Wrapping(self.0.wrapping_add(&v.0))
228
0
    }
229
}
230
impl<T: WrappingSub> WrappingSub for Wrapping<T>
231
where
232
    Wrapping<T>: Sub<Output = Wrapping<T>>,
233
{
234
0
    fn wrapping_sub(&self, v: &Self) -> Self {
235
0
        Wrapping(self.0.wrapping_sub(&v.0))
236
0
    }
237
}
238
impl<T: WrappingMul> WrappingMul for Wrapping<T>
239
where
240
    Wrapping<T>: Mul<Output = Wrapping<T>>,
241
{
242
0
    fn wrapping_mul(&self, v: &Self) -> Self {
243
0
        Wrapping(self.0.wrapping_mul(&v.0))
244
0
    }
245
}
246
impl<T: WrappingNeg> WrappingNeg for Wrapping<T>
247
where
248
    Wrapping<T>: Neg<Output = Wrapping<T>>,
249
{
250
0
    fn wrapping_neg(&self) -> Self {
251
0
        Wrapping(self.0.wrapping_neg())
252
0
    }
253
}
254
impl<T: WrappingShl> WrappingShl for Wrapping<T>
255
where
256
    Wrapping<T>: Shl<usize, Output = Wrapping<T>>,
257
{
258
0
    fn wrapping_shl(&self, rhs: u32) -> Self {
259
0
        Wrapping(self.0.wrapping_shl(rhs))
260
0
    }
261
}
262
impl<T: WrappingShr> WrappingShr for Wrapping<T>
263
where
264
    Wrapping<T>: Shr<usize, Output = Wrapping<T>>,
265
{
266
0
    fn wrapping_shr(&self, rhs: u32) -> Self {
267
0
        Wrapping(self.0.wrapping_shr(rhs))
268
0
    }
269
}
270
271
#[test]
272
fn test_wrapping_traits() {
273
    fn wrapping_add<T: WrappingAdd>(a: T, b: T) -> T {
274
        a.wrapping_add(&b)
275
    }
276
    fn wrapping_sub<T: WrappingSub>(a: T, b: T) -> T {
277
        a.wrapping_sub(&b)
278
    }
279
    fn wrapping_mul<T: WrappingMul>(a: T, b: T) -> T {
280
        a.wrapping_mul(&b)
281
    }
282
    fn wrapping_neg<T: WrappingNeg>(a: T) -> T {
283
        a.wrapping_neg()
284
    }
285
    fn wrapping_shl<T: WrappingShl>(a: T, b: u32) -> T {
286
        a.wrapping_shl(b)
287
    }
288
    fn wrapping_shr<T: WrappingShr>(a: T, b: u32) -> T {
289
        a.wrapping_shr(b)
290
    }
291
    assert_eq!(wrapping_add(255, 1), 0u8);
292
    assert_eq!(wrapping_sub(0, 1), 255u8);
293
    assert_eq!(wrapping_mul(255, 2), 254u8);
294
    assert_eq!(wrapping_neg(255), 1u8);
295
    assert_eq!(wrapping_shl(255, 8), 255u8);
296
    assert_eq!(wrapping_shr(255, 8), 255u8);
297
    assert_eq!(wrapping_add(255, 1), (Wrapping(255u8) + Wrapping(1u8)).0);
298
    assert_eq!(wrapping_sub(0, 1), (Wrapping(0u8) - Wrapping(1u8)).0);
299
    assert_eq!(wrapping_mul(255, 2), (Wrapping(255u8) * Wrapping(2u8)).0);
300
    // TODO: Test for Wrapping::Neg. Not possible yet since core::ops::Neg was
301
    // only added to core::num::Wrapping<_> in Rust 1.10.
302
    assert_eq!(wrapping_shl(255, 8), (Wrapping(255u8) << 8).0);
303
    assert_eq!(wrapping_shr(255, 8), (Wrapping(255u8) >> 8).0);
304
}
305
306
#[test]
307
fn wrapping_is_wrappingadd() {
308
    fn require_wrappingadd<T: WrappingAdd>(_: &T) {}
309
    require_wrappingadd(&Wrapping(42));
310
}
311
312
#[test]
313
fn wrapping_is_wrappingsub() {
314
    fn require_wrappingsub<T: WrappingSub>(_: &T) {}
315
    require_wrappingsub(&Wrapping(42));
316
}
317
318
#[test]
319
fn wrapping_is_wrappingmul() {
320
    fn require_wrappingmul<T: WrappingMul>(_: &T) {}
321
    require_wrappingmul(&Wrapping(42));
322
}
323
324
// TODO: Test for Wrapping::Neg. Not possible yet since core::ops::Neg was
325
// only added to core::num::Wrapping<_> in Rust 1.10.
326
327
#[test]
328
fn wrapping_is_wrappingshl() {
329
    fn require_wrappingshl<T: WrappingShl>(_: &T) {}
330
    require_wrappingshl(&Wrapping(42));
331
}
332
333
#[test]
334
fn wrapping_is_wrappingshr() {
335
    fn require_wrappingshr<T: WrappingShr>(_: &T) {}
336
    require_wrappingshr(&Wrapping(42));
337
}