1 | //! Definitions of `Wrapping<T>`. |
2 | |
3 | use crate::fmt; |
4 | use crate::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign}; |
5 | use crate::ops::{BitXor, BitXorAssign, Div, DivAssign}; |
6 | use crate::ops::{Mul, MulAssign, Neg, Not, Rem, RemAssign}; |
7 | use crate::ops::{Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign}; |
8 | |
9 | /// Provides intentionally-wrapped arithmetic on `T`. |
10 | /// |
11 | /// Operations like `+` on `u32` values are intended to never overflow, |
12 | /// and in some debug configurations overflow is detected and results |
13 | /// in a panic. While most arithmetic falls into this category, some |
14 | /// code explicitly expects and relies upon modular arithmetic (e.g., |
15 | /// hashing). |
16 | /// |
17 | /// Wrapping arithmetic can be achieved either through methods like |
18 | /// `wrapping_add`, or through the `Wrapping<T>` type, which says that |
19 | /// all standard arithmetic operations on the underlying value are |
20 | /// intended to have wrapping semantics. |
21 | /// |
22 | /// The underlying value can be retrieved through the `.0` index of the |
23 | /// `Wrapping` tuple. |
24 | /// |
25 | /// # Examples |
26 | /// |
27 | /// ``` |
28 | /// use std::num::Wrapping; |
29 | /// |
30 | /// let zero = Wrapping(0u32); |
31 | /// let one = Wrapping(1u32); |
32 | /// |
33 | /// assert_eq!(u32::MAX, (zero - one).0); |
34 | /// ``` |
35 | /// |
36 | /// # Layout |
37 | /// |
38 | /// `Wrapping<T>` is guaranteed to have the same layout and ABI as `T`. |
39 | #[stable (feature = "rust1" , since = "1.0.0" )] |
40 | #[derive (PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)] |
41 | #[repr (transparent)] |
42 | #[rustc_diagnostic_item = "Wrapping" ] |
43 | pub struct Wrapping<T>(#[stable (feature = "rust1" , since = "1.0.0" )] pub T); |
44 | |
45 | #[stable (feature = "rust1" , since = "1.0.0" )] |
46 | impl<T: fmt::Debug> fmt::Debug for Wrapping<T> { |
47 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
48 | self.0.fmt(f) |
49 | } |
50 | } |
51 | |
52 | #[stable (feature = "wrapping_display" , since = "1.10.0" )] |
53 | impl<T: fmt::Display> fmt::Display for Wrapping<T> { |
54 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
55 | self.0.fmt(f) |
56 | } |
57 | } |
58 | |
59 | #[stable (feature = "wrapping_fmt" , since = "1.11.0" )] |
60 | impl<T: fmt::Binary> fmt::Binary for Wrapping<T> { |
61 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
62 | self.0.fmt(f) |
63 | } |
64 | } |
65 | |
66 | #[stable (feature = "wrapping_fmt" , since = "1.11.0" )] |
67 | impl<T: fmt::Octal> fmt::Octal for Wrapping<T> { |
68 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
69 | self.0.fmt(f) |
70 | } |
71 | } |
72 | |
73 | #[stable (feature = "wrapping_fmt" , since = "1.11.0" )] |
74 | impl<T: fmt::LowerHex> fmt::LowerHex for Wrapping<T> { |
75 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
76 | self.0.fmt(f) |
77 | } |
78 | } |
79 | |
80 | #[stable (feature = "wrapping_fmt" , since = "1.11.0" )] |
81 | impl<T: fmt::UpperHex> fmt::UpperHex for Wrapping<T> { |
82 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
83 | self.0.fmt(f) |
84 | } |
85 | } |
86 | |
87 | #[allow (unused_macros)] |
88 | macro_rules! sh_impl_signed { |
89 | ($t:ident, $f:ident) => { |
90 | #[stable(feature = "rust1" , since = "1.0.0" )] |
91 | impl Shl<$f> for Wrapping<$t> { |
92 | type Output = Wrapping<$t>; |
93 | |
94 | #[inline] |
95 | fn shl(self, other: $f) -> Wrapping<$t> { |
96 | if other < 0 { |
97 | Wrapping(self.0.wrapping_shr((-other & self::shift_max::$t as $f) as u32)) |
98 | } else { |
99 | Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) |
100 | } |
101 | } |
102 | } |
103 | forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, |
104 | #[stable(feature = "wrapping_ref_ops" , since = "1.39.0" )] } |
105 | |
106 | #[stable(feature = "op_assign_traits" , since = "1.8.0" )] |
107 | impl ShlAssign<$f> for Wrapping<$t> { |
108 | #[inline] |
109 | fn shl_assign(&mut self, other: $f) { |
110 | *self = *self << other; |
111 | } |
112 | } |
113 | forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f } |
114 | |
115 | #[stable(feature = "rust1" , since = "1.0.0" )] |
116 | impl Shr<$f> for Wrapping<$t> { |
117 | type Output = Wrapping<$t>; |
118 | |
119 | #[inline] |
120 | fn shr(self, other: $f) -> Wrapping<$t> { |
121 | if other < 0 { |
122 | Wrapping(self.0.wrapping_shl((-other & self::shift_max::$t as $f) as u32)) |
123 | } else { |
124 | Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) |
125 | } |
126 | } |
127 | } |
128 | forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, |
129 | #[stable(feature = "wrapping_ref_ops" , since = "1.39.0" )] } |
130 | |
131 | #[stable(feature = "op_assign_traits" , since = "1.8.0" )] |
132 | impl ShrAssign<$f> for Wrapping<$t> { |
133 | #[inline] |
134 | fn shr_assign(&mut self, other: $f) { |
135 | *self = *self >> other; |
136 | } |
137 | } |
138 | forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } |
139 | }; |
140 | } |
141 | |
142 | macro_rules! sh_impl_unsigned { |
143 | ($t:ident, $f:ident) => { |
144 | #[stable(feature = "rust1" , since = "1.0.0" )] |
145 | impl Shl<$f> for Wrapping<$t> { |
146 | type Output = Wrapping<$t>; |
147 | |
148 | #[inline] |
149 | fn shl(self, other: $f) -> Wrapping<$t> { |
150 | Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) |
151 | } |
152 | } |
153 | forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, |
154 | #[stable(feature = "wrapping_ref_ops" , since = "1.39.0" )] } |
155 | |
156 | #[stable(feature = "op_assign_traits" , since = "1.8.0" )] |
157 | impl ShlAssign<$f> for Wrapping<$t> { |
158 | #[inline] |
159 | fn shl_assign(&mut self, other: $f) { |
160 | *self = *self << other; |
161 | } |
162 | } |
163 | forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f } |
164 | |
165 | #[stable(feature = "rust1" , since = "1.0.0" )] |
166 | impl Shr<$f> for Wrapping<$t> { |
167 | type Output = Wrapping<$t>; |
168 | |
169 | #[inline] |
170 | fn shr(self, other: $f) -> Wrapping<$t> { |
171 | Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) |
172 | } |
173 | } |
174 | forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, |
175 | #[stable(feature = "wrapping_ref_ops" , since = "1.39.0" )] } |
176 | |
177 | #[stable(feature = "op_assign_traits" , since = "1.8.0" )] |
178 | impl ShrAssign<$f> for Wrapping<$t> { |
179 | #[inline] |
180 | fn shr_assign(&mut self, other: $f) { |
181 | *self = *self >> other; |
182 | } |
183 | } |
184 | forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } |
185 | }; |
186 | } |
187 | |
188 | // FIXME (#23545): uncomment the remaining impls |
189 | macro_rules! sh_impl_all { |
190 | ($($t:ident)*) => ($( |
191 | //sh_impl_unsigned! { $t, u8 } |
192 | //sh_impl_unsigned! { $t, u16 } |
193 | //sh_impl_unsigned! { $t, u32 } |
194 | //sh_impl_unsigned! { $t, u64 } |
195 | //sh_impl_unsigned! { $t, u128 } |
196 | sh_impl_unsigned! { $t, usize } |
197 | |
198 | //sh_impl_signed! { $t, i8 } |
199 | //sh_impl_signed! { $t, i16 } |
200 | //sh_impl_signed! { $t, i32 } |
201 | //sh_impl_signed! { $t, i64 } |
202 | //sh_impl_signed! { $t, i128 } |
203 | //sh_impl_signed! { $t, isize } |
204 | )*) |
205 | } |
206 | |
207 | sh_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } |
208 | |
209 | // FIXME(30524): impl Op<T> for Wrapping<T>, impl OpAssign<T> for Wrapping<T> |
210 | macro_rules! wrapping_impl { |
211 | ($($t:ty)*) => ($( |
212 | #[stable(feature = "rust1" , since = "1.0.0" )] |
213 | impl Add for Wrapping<$t> { |
214 | type Output = Wrapping<$t>; |
215 | |
216 | #[inline] |
217 | fn add(self, other: Wrapping<$t>) -> Wrapping<$t> { |
218 | Wrapping(self.0.wrapping_add(other.0)) |
219 | } |
220 | } |
221 | forward_ref_binop! { impl Add, add for Wrapping<$t>, Wrapping<$t>, |
222 | #[stable(feature = "wrapping_ref" , since = "1.14.0" )] } |
223 | |
224 | #[stable(feature = "op_assign_traits" , since = "1.8.0" )] |
225 | impl AddAssign for Wrapping<$t> { |
226 | #[inline] |
227 | fn add_assign(&mut self, other: Wrapping<$t>) { |
228 | *self = *self + other; |
229 | } |
230 | } |
231 | forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } |
232 | |
233 | #[stable(feature = "wrapping_int_assign_impl" , since = "1.60.0" )] |
234 | impl AddAssign<$t> for Wrapping<$t> { |
235 | #[inline] |
236 | fn add_assign(&mut self, other: $t) { |
237 | *self = *self + Wrapping(other); |
238 | } |
239 | } |
240 | forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, $t } |
241 | |
242 | #[stable(feature = "rust1" , since = "1.0.0" )] |
243 | impl Sub for Wrapping<$t> { |
244 | type Output = Wrapping<$t>; |
245 | |
246 | #[inline] |
247 | fn sub(self, other: Wrapping<$t>) -> Wrapping<$t> { |
248 | Wrapping(self.0.wrapping_sub(other.0)) |
249 | } |
250 | } |
251 | forward_ref_binop! { impl Sub, sub for Wrapping<$t>, Wrapping<$t>, |
252 | #[stable(feature = "wrapping_ref" , since = "1.14.0" )] } |
253 | |
254 | #[stable(feature = "op_assign_traits" , since = "1.8.0" )] |
255 | impl SubAssign for Wrapping<$t> { |
256 | #[inline] |
257 | fn sub_assign(&mut self, other: Wrapping<$t>) { |
258 | *self = *self - other; |
259 | } |
260 | } |
261 | forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } |
262 | |
263 | #[stable(feature = "wrapping_int_assign_impl" , since = "1.60.0" )] |
264 | impl SubAssign<$t> for Wrapping<$t> { |
265 | #[inline] |
266 | fn sub_assign(&mut self, other: $t) { |
267 | *self = *self - Wrapping(other); |
268 | } |
269 | } |
270 | forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, $t } |
271 | |
272 | #[stable(feature = "rust1" , since = "1.0.0" )] |
273 | impl Mul for Wrapping<$t> { |
274 | type Output = Wrapping<$t>; |
275 | |
276 | #[inline] |
277 | fn mul(self, other: Wrapping<$t>) -> Wrapping<$t> { |
278 | Wrapping(self.0.wrapping_mul(other.0)) |
279 | } |
280 | } |
281 | forward_ref_binop! { impl Mul, mul for Wrapping<$t>, Wrapping<$t>, |
282 | #[stable(feature = "wrapping_ref" , since = "1.14.0" )] } |
283 | |
284 | #[stable(feature = "op_assign_traits" , since = "1.8.0" )] |
285 | impl MulAssign for Wrapping<$t> { |
286 | #[inline] |
287 | fn mul_assign(&mut self, other: Wrapping<$t>) { |
288 | *self = *self * other; |
289 | } |
290 | } |
291 | forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } |
292 | |
293 | #[stable(feature = "wrapping_int_assign_impl" , since = "1.60.0" )] |
294 | impl MulAssign<$t> for Wrapping<$t> { |
295 | #[inline] |
296 | fn mul_assign(&mut self, other: $t) { |
297 | *self = *self * Wrapping(other); |
298 | } |
299 | } |
300 | forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, $t } |
301 | |
302 | #[stable(feature = "wrapping_div" , since = "1.3.0" )] |
303 | impl Div for Wrapping<$t> { |
304 | type Output = Wrapping<$t>; |
305 | |
306 | #[inline] |
307 | fn div(self, other: Wrapping<$t>) -> Wrapping<$t> { |
308 | Wrapping(self.0.wrapping_div(other.0)) |
309 | } |
310 | } |
311 | forward_ref_binop! { impl Div, div for Wrapping<$t>, Wrapping<$t>, |
312 | #[stable(feature = "wrapping_ref" , since = "1.14.0" )] } |
313 | |
314 | #[stable(feature = "op_assign_traits" , since = "1.8.0" )] |
315 | impl DivAssign for Wrapping<$t> { |
316 | #[inline] |
317 | fn div_assign(&mut self, other: Wrapping<$t>) { |
318 | *self = *self / other; |
319 | } |
320 | } |
321 | forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } |
322 | |
323 | #[stable(feature = "wrapping_int_assign_impl" , since = "1.60.0" )] |
324 | impl DivAssign<$t> for Wrapping<$t> { |
325 | #[inline] |
326 | fn div_assign(&mut self, other: $t) { |
327 | *self = *self / Wrapping(other); |
328 | } |
329 | } |
330 | forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, $t } |
331 | |
332 | #[stable(feature = "wrapping_impls" , since = "1.7.0" )] |
333 | impl Rem for Wrapping<$t> { |
334 | type Output = Wrapping<$t>; |
335 | |
336 | #[inline] |
337 | fn rem(self, other: Wrapping<$t>) -> Wrapping<$t> { |
338 | Wrapping(self.0.wrapping_rem(other.0)) |
339 | } |
340 | } |
341 | forward_ref_binop! { impl Rem, rem for Wrapping<$t>, Wrapping<$t>, |
342 | #[stable(feature = "wrapping_ref" , since = "1.14.0" )] } |
343 | |
344 | #[stable(feature = "op_assign_traits" , since = "1.8.0" )] |
345 | impl RemAssign for Wrapping<$t> { |
346 | #[inline] |
347 | fn rem_assign(&mut self, other: Wrapping<$t>) { |
348 | *self = *self % other; |
349 | } |
350 | } |
351 | forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } |
352 | |
353 | #[stable(feature = "wrapping_int_assign_impl" , since = "1.60.0" )] |
354 | impl RemAssign<$t> for Wrapping<$t> { |
355 | #[inline] |
356 | fn rem_assign(&mut self, other: $t) { |
357 | *self = *self % Wrapping(other); |
358 | } |
359 | } |
360 | forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, $t } |
361 | |
362 | #[stable(feature = "rust1" , since = "1.0.0" )] |
363 | impl Not for Wrapping<$t> { |
364 | type Output = Wrapping<$t>; |
365 | |
366 | #[inline] |
367 | fn not(self) -> Wrapping<$t> { |
368 | Wrapping(!self.0) |
369 | } |
370 | } |
371 | forward_ref_unop! { impl Not, not for Wrapping<$t>, |
372 | #[stable(feature = "wrapping_ref" , since = "1.14.0" )] } |
373 | |
374 | #[stable(feature = "rust1" , since = "1.0.0" )] |
375 | impl BitXor for Wrapping<$t> { |
376 | type Output = Wrapping<$t>; |
377 | |
378 | #[inline] |
379 | fn bitxor(self, other: Wrapping<$t>) -> Wrapping<$t> { |
380 | Wrapping(self.0 ^ other.0) |
381 | } |
382 | } |
383 | forward_ref_binop! { impl BitXor, bitxor for Wrapping<$t>, Wrapping<$t>, |
384 | #[stable(feature = "wrapping_ref" , since = "1.14.0" )] } |
385 | |
386 | #[stable(feature = "op_assign_traits" , since = "1.8.0" )] |
387 | impl BitXorAssign for Wrapping<$t> { |
388 | #[inline] |
389 | fn bitxor_assign(&mut self, other: Wrapping<$t>) { |
390 | *self = *self ^ other; |
391 | } |
392 | } |
393 | forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } |
394 | |
395 | #[stable(feature = "wrapping_int_assign_impl" , since = "1.60.0" )] |
396 | impl BitXorAssign<$t> for Wrapping<$t> { |
397 | #[inline] |
398 | fn bitxor_assign(&mut self, other: $t) { |
399 | *self = *self ^ Wrapping(other); |
400 | } |
401 | } |
402 | forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, $t } |
403 | |
404 | #[stable(feature = "rust1" , since = "1.0.0" )] |
405 | impl BitOr for Wrapping<$t> { |
406 | type Output = Wrapping<$t>; |
407 | |
408 | #[inline] |
409 | fn bitor(self, other: Wrapping<$t>) -> Wrapping<$t> { |
410 | Wrapping(self.0 | other.0) |
411 | } |
412 | } |
413 | forward_ref_binop! { impl BitOr, bitor for Wrapping<$t>, Wrapping<$t>, |
414 | #[stable(feature = "wrapping_ref" , since = "1.14.0" )] } |
415 | |
416 | #[stable(feature = "op_assign_traits" , since = "1.8.0" )] |
417 | impl BitOrAssign for Wrapping<$t> { |
418 | #[inline] |
419 | fn bitor_assign(&mut self, other: Wrapping<$t>) { |
420 | *self = *self | other; |
421 | } |
422 | } |
423 | forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } |
424 | |
425 | #[stable(feature = "wrapping_int_assign_impl" , since = "1.60.0" )] |
426 | impl BitOrAssign<$t> for Wrapping<$t> { |
427 | #[inline] |
428 | fn bitor_assign(&mut self, other: $t) { |
429 | *self = *self | Wrapping(other); |
430 | } |
431 | } |
432 | forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, $t } |
433 | |
434 | #[stable(feature = "rust1" , since = "1.0.0" )] |
435 | impl BitAnd for Wrapping<$t> { |
436 | type Output = Wrapping<$t>; |
437 | |
438 | #[inline] |
439 | fn bitand(self, other: Wrapping<$t>) -> Wrapping<$t> { |
440 | Wrapping(self.0 & other.0) |
441 | } |
442 | } |
443 | forward_ref_binop! { impl BitAnd, bitand for Wrapping<$t>, Wrapping<$t>, |
444 | #[stable(feature = "wrapping_ref" , since = "1.14.0" )] } |
445 | |
446 | #[stable(feature = "op_assign_traits" , since = "1.8.0" )] |
447 | impl BitAndAssign for Wrapping<$t> { |
448 | #[inline] |
449 | fn bitand_assign(&mut self, other: Wrapping<$t>) { |
450 | *self = *self & other; |
451 | } |
452 | } |
453 | forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } |
454 | |
455 | #[stable(feature = "wrapping_int_assign_impl" , since = "1.60.0" )] |
456 | impl BitAndAssign<$t> for Wrapping<$t> { |
457 | #[inline] |
458 | fn bitand_assign(&mut self, other: $t) { |
459 | *self = *self & Wrapping(other); |
460 | } |
461 | } |
462 | forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, $t } |
463 | |
464 | #[stable(feature = "wrapping_neg" , since = "1.10.0" )] |
465 | impl Neg for Wrapping<$t> { |
466 | type Output = Self; |
467 | #[inline] |
468 | fn neg(self) -> Self { |
469 | Wrapping(0) - self |
470 | } |
471 | } |
472 | forward_ref_unop! { impl Neg, neg for Wrapping<$t>, |
473 | #[stable(feature = "wrapping_ref" , since = "1.14.0" )] } |
474 | |
475 | )*) |
476 | } |
477 | |
478 | wrapping_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } |
479 | |
480 | macro_rules! wrapping_int_impl { |
481 | ($($t:ty)*) => ($( |
482 | impl Wrapping<$t> { |
483 | /// Returns the smallest value that can be represented by this integer type. |
484 | /// |
485 | /// # Examples |
486 | /// |
487 | /// Basic usage: |
488 | /// |
489 | /// ``` |
490 | /// #![feature(wrapping_int_impl)] |
491 | /// use std::num::Wrapping; |
492 | /// |
493 | #[doc = concat!("assert_eq!(<Wrapping<" , stringify!($t), ">>::MIN, Wrapping(" , stringify!($t), "::MIN));" )] |
494 | /// ``` |
495 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
496 | pub const MIN: Self = Self(<$t>::MIN); |
497 | |
498 | /// Returns the largest value that can be represented by this integer type. |
499 | /// |
500 | /// # Examples |
501 | /// |
502 | /// Basic usage: |
503 | /// |
504 | /// ``` |
505 | /// #![feature(wrapping_int_impl)] |
506 | /// use std::num::Wrapping; |
507 | /// |
508 | #[doc = concat!("assert_eq!(<Wrapping<" , stringify!($t), ">>::MAX, Wrapping(" , stringify!($t), "::MAX));" )] |
509 | /// ``` |
510 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
511 | pub const MAX: Self = Self(<$t>::MAX); |
512 | |
513 | /// Returns the size of this integer type in bits. |
514 | /// |
515 | /// # Examples |
516 | /// |
517 | /// Basic usage: |
518 | /// |
519 | /// ``` |
520 | /// #![feature(wrapping_int_impl)] |
521 | /// use std::num::Wrapping; |
522 | /// |
523 | #[doc = concat!("assert_eq!(<Wrapping<" , stringify!($t), ">>::BITS, " , stringify!($t), "::BITS);" )] |
524 | /// ``` |
525 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
526 | pub const BITS: u32 = <$t>::BITS; |
527 | |
528 | /// Returns the number of ones in the binary representation of `self`. |
529 | /// |
530 | /// # Examples |
531 | /// |
532 | /// Basic usage: |
533 | /// |
534 | /// ``` |
535 | /// #![feature(wrapping_int_impl)] |
536 | /// use std::num::Wrapping; |
537 | /// |
538 | #[doc = concat!("let n = Wrapping(0b01001100" , stringify!($t), ");" )] |
539 | /// |
540 | /// assert_eq!(n.count_ones(), 3); |
541 | /// ``` |
542 | #[inline] |
543 | #[doc(alias = "popcount" )] |
544 | #[doc(alias = "popcnt" )] |
545 | #[must_use = "this returns the result of the operation, \ |
546 | without modifying the original" ] |
547 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
548 | pub const fn count_ones(self) -> u32 { |
549 | self.0.count_ones() |
550 | } |
551 | |
552 | /// Returns the number of zeros in the binary representation of `self`. |
553 | /// |
554 | /// # Examples |
555 | /// |
556 | /// Basic usage: |
557 | /// |
558 | /// ``` |
559 | /// #![feature(wrapping_int_impl)] |
560 | /// use std::num::Wrapping; |
561 | /// |
562 | #[doc = concat!("assert_eq!(Wrapping(!0" , stringify!($t), ").count_zeros(), 0);" )] |
563 | /// ``` |
564 | #[inline] |
565 | #[must_use = "this returns the result of the operation, \ |
566 | without modifying the original" ] |
567 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
568 | pub const fn count_zeros(self) -> u32 { |
569 | self.0.count_zeros() |
570 | } |
571 | |
572 | /// Returns the number of trailing zeros in the binary representation of `self`. |
573 | /// |
574 | /// # Examples |
575 | /// |
576 | /// Basic usage: |
577 | /// |
578 | /// ``` |
579 | /// #![feature(wrapping_int_impl)] |
580 | /// use std::num::Wrapping; |
581 | /// |
582 | #[doc = concat!("let n = Wrapping(0b0101000" , stringify!($t), ");" )] |
583 | /// |
584 | /// assert_eq!(n.trailing_zeros(), 3); |
585 | /// ``` |
586 | #[inline] |
587 | #[must_use = "this returns the result of the operation, \ |
588 | without modifying the original" ] |
589 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
590 | pub const fn trailing_zeros(self) -> u32 { |
591 | self.0.trailing_zeros() |
592 | } |
593 | |
594 | /// Shifts the bits to the left by a specified amount, `n`, |
595 | /// wrapping the truncated bits to the end of the resulting |
596 | /// integer. |
597 | /// |
598 | /// Please note this isn't the same operation as the `<<` shifting |
599 | /// operator! |
600 | /// |
601 | /// # Examples |
602 | /// |
603 | /// Basic usage: |
604 | /// |
605 | /// ``` |
606 | /// #![feature(wrapping_int_impl)] |
607 | /// use std::num::Wrapping; |
608 | /// |
609 | /// let n: Wrapping<i64> = Wrapping(0x0123456789ABCDEF); |
610 | /// let m: Wrapping<i64> = Wrapping(-0x76543210FEDCBA99); |
611 | /// |
612 | /// assert_eq!(n.rotate_left(32), m); |
613 | /// ``` |
614 | #[inline] |
615 | #[must_use = "this returns the result of the operation, \ |
616 | without modifying the original" ] |
617 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
618 | pub const fn rotate_left(self, n: u32) -> Self { |
619 | Wrapping(self.0.rotate_left(n)) |
620 | } |
621 | |
622 | /// Shifts the bits to the right by a specified amount, `n`, |
623 | /// wrapping the truncated bits to the beginning of the resulting |
624 | /// integer. |
625 | /// |
626 | /// Please note this isn't the same operation as the `>>` shifting |
627 | /// operator! |
628 | /// |
629 | /// # Examples |
630 | /// |
631 | /// Basic usage: |
632 | /// |
633 | /// ``` |
634 | /// #![feature(wrapping_int_impl)] |
635 | /// use std::num::Wrapping; |
636 | /// |
637 | /// let n: Wrapping<i64> = Wrapping(0x0123456789ABCDEF); |
638 | /// let m: Wrapping<i64> = Wrapping(-0xFEDCBA987654322); |
639 | /// |
640 | /// assert_eq!(n.rotate_right(4), m); |
641 | /// ``` |
642 | #[inline] |
643 | #[must_use = "this returns the result of the operation, \ |
644 | without modifying the original" ] |
645 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
646 | pub const fn rotate_right(self, n: u32) -> Self { |
647 | Wrapping(self.0.rotate_right(n)) |
648 | } |
649 | |
650 | /// Reverses the byte order of the integer. |
651 | /// |
652 | /// # Examples |
653 | /// |
654 | /// Basic usage: |
655 | /// |
656 | /// ``` |
657 | /// #![feature(wrapping_int_impl)] |
658 | /// use std::num::Wrapping; |
659 | /// |
660 | /// let n: Wrapping<i16> = Wrapping(0b0000000_01010101); |
661 | /// assert_eq!(n, Wrapping(85)); |
662 | /// |
663 | /// let m = n.swap_bytes(); |
664 | /// |
665 | /// assert_eq!(m, Wrapping(0b01010101_00000000)); |
666 | /// assert_eq!(m, Wrapping(21760)); |
667 | /// ``` |
668 | #[inline] |
669 | #[must_use = "this returns the result of the operation, \ |
670 | without modifying the original" ] |
671 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
672 | pub const fn swap_bytes(self) -> Self { |
673 | Wrapping(self.0.swap_bytes()) |
674 | } |
675 | |
676 | /// Reverses the bit pattern of the integer. |
677 | /// |
678 | /// # Examples |
679 | /// |
680 | /// Please note that this example is shared between integer types. |
681 | /// Which explains why `i16` is used here. |
682 | /// |
683 | /// Basic usage: |
684 | /// |
685 | /// ``` |
686 | /// use std::num::Wrapping; |
687 | /// |
688 | /// let n = Wrapping(0b0000000_01010101i16); |
689 | /// assert_eq!(n, Wrapping(85)); |
690 | /// |
691 | /// let m = n.reverse_bits(); |
692 | /// |
693 | /// assert_eq!(m.0 as u16, 0b10101010_00000000); |
694 | /// assert_eq!(m, Wrapping(-22016)); |
695 | /// ``` |
696 | #[stable(feature = "reverse_bits" , since = "1.37.0" )] |
697 | #[rustc_const_stable(feature = "const_reverse_bits" , since = "1.37.0" )] |
698 | #[must_use = "this returns the result of the operation, \ |
699 | without modifying the original" ] |
700 | #[inline] |
701 | pub const fn reverse_bits(self) -> Self { |
702 | Wrapping(self.0.reverse_bits()) |
703 | } |
704 | |
705 | /// Converts an integer from big endian to the target's endianness. |
706 | /// |
707 | /// On big endian this is a no-op. On little endian the bytes are |
708 | /// swapped. |
709 | /// |
710 | /// # Examples |
711 | /// |
712 | /// Basic usage: |
713 | /// |
714 | /// ``` |
715 | /// #![feature(wrapping_int_impl)] |
716 | /// use std::num::Wrapping; |
717 | /// |
718 | #[doc = concat!("let n = Wrapping(0x1A" , stringify!($t), ");" )] |
719 | /// |
720 | /// if cfg!(target_endian = "big") { |
721 | #[doc = concat!(" assert_eq!(<Wrapping<" , stringify!($t), ">>::from_be(n), n)" )] |
722 | /// } else { |
723 | #[doc = concat!(" assert_eq!(<Wrapping<" , stringify!($t), ">>::from_be(n), n.swap_bytes())" )] |
724 | /// } |
725 | /// ``` |
726 | #[inline] |
727 | #[must_use] |
728 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
729 | pub const fn from_be(x: Self) -> Self { |
730 | Wrapping(<$t>::from_be(x.0)) |
731 | } |
732 | |
733 | /// Converts an integer from little endian to the target's endianness. |
734 | /// |
735 | /// On little endian this is a no-op. On big endian the bytes are |
736 | /// swapped. |
737 | /// |
738 | /// # Examples |
739 | /// |
740 | /// Basic usage: |
741 | /// |
742 | /// ``` |
743 | /// #![feature(wrapping_int_impl)] |
744 | /// use std::num::Wrapping; |
745 | /// |
746 | #[doc = concat!("let n = Wrapping(0x1A" , stringify!($t), ");" )] |
747 | /// |
748 | /// if cfg!(target_endian = "little") { |
749 | #[doc = concat!(" assert_eq!(<Wrapping<" , stringify!($t), ">>::from_le(n), n)" )] |
750 | /// } else { |
751 | #[doc = concat!(" assert_eq!(<Wrapping<" , stringify!($t), ">>::from_le(n), n.swap_bytes())" )] |
752 | /// } |
753 | /// ``` |
754 | #[inline] |
755 | #[must_use] |
756 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
757 | pub const fn from_le(x: Self) -> Self { |
758 | Wrapping(<$t>::from_le(x.0)) |
759 | } |
760 | |
761 | /// Converts `self` to big endian from the target's endianness. |
762 | /// |
763 | /// On big endian this is a no-op. On little endian the bytes are |
764 | /// swapped. |
765 | /// |
766 | /// # Examples |
767 | /// |
768 | /// Basic usage: |
769 | /// |
770 | /// ``` |
771 | /// #![feature(wrapping_int_impl)] |
772 | /// use std::num::Wrapping; |
773 | /// |
774 | #[doc = concat!("let n = Wrapping(0x1A" , stringify!($t), ");" )] |
775 | /// |
776 | /// if cfg!(target_endian = "big") { |
777 | /// assert_eq!(n.to_be(), n) |
778 | /// } else { |
779 | /// assert_eq!(n.to_be(), n.swap_bytes()) |
780 | /// } |
781 | /// ``` |
782 | #[inline] |
783 | #[must_use = "this returns the result of the operation, \ |
784 | without modifying the original" ] |
785 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
786 | pub const fn to_be(self) -> Self { |
787 | Wrapping(self.0.to_be()) |
788 | } |
789 | |
790 | /// Converts `self` to little endian from the target's endianness. |
791 | /// |
792 | /// On little endian this is a no-op. On big endian the bytes are |
793 | /// swapped. |
794 | /// |
795 | /// # Examples |
796 | /// |
797 | /// Basic usage: |
798 | /// |
799 | /// ``` |
800 | /// #![feature(wrapping_int_impl)] |
801 | /// use std::num::Wrapping; |
802 | /// |
803 | #[doc = concat!("let n = Wrapping(0x1A" , stringify!($t), ");" )] |
804 | /// |
805 | /// if cfg!(target_endian = "little") { |
806 | /// assert_eq!(n.to_le(), n) |
807 | /// } else { |
808 | /// assert_eq!(n.to_le(), n.swap_bytes()) |
809 | /// } |
810 | /// ``` |
811 | #[inline] |
812 | #[must_use = "this returns the result of the operation, \ |
813 | without modifying the original" ] |
814 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
815 | pub const fn to_le(self) -> Self { |
816 | Wrapping(self.0.to_le()) |
817 | } |
818 | |
819 | /// Raises self to the power of `exp`, using exponentiation by squaring. |
820 | /// |
821 | /// # Examples |
822 | /// |
823 | /// Basic usage: |
824 | /// |
825 | /// ``` |
826 | /// #![feature(wrapping_int_impl)] |
827 | /// use std::num::Wrapping; |
828 | /// |
829 | #[doc = concat!("assert_eq!(Wrapping(3" , stringify!($t), ").pow(4), Wrapping(81));" )] |
830 | /// ``` |
831 | /// |
832 | /// Results that are too large are wrapped: |
833 | /// |
834 | /// ``` |
835 | /// #![feature(wrapping_int_impl)] |
836 | /// use std::num::Wrapping; |
837 | /// |
838 | /// assert_eq!(Wrapping(3i8).pow(5), Wrapping(-13)); |
839 | /// assert_eq!(Wrapping(3i8).pow(6), Wrapping(-39)); |
840 | /// ``` |
841 | #[inline] |
842 | #[must_use = "this returns the result of the operation, \ |
843 | without modifying the original" ] |
844 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
845 | pub fn pow(self, exp: u32) -> Self { |
846 | Wrapping(self.0.wrapping_pow(exp)) |
847 | } |
848 | } |
849 | )*) |
850 | } |
851 | |
852 | wrapping_int_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } |
853 | |
854 | macro_rules! wrapping_int_impl_signed { |
855 | ($($t:ty)*) => ($( |
856 | impl Wrapping<$t> { |
857 | /// Returns the number of leading zeros in the binary representation of `self`. |
858 | /// |
859 | /// # Examples |
860 | /// |
861 | /// Basic usage: |
862 | /// |
863 | /// ``` |
864 | /// #![feature(wrapping_int_impl)] |
865 | /// use std::num::Wrapping; |
866 | /// |
867 | #[doc = concat!("let n = Wrapping(" , stringify!($t), "::MAX) >> 2;" )] |
868 | /// |
869 | /// assert_eq!(n.leading_zeros(), 3); |
870 | /// ``` |
871 | #[inline] |
872 | #[must_use = "this returns the result of the operation, \ |
873 | without modifying the original" ] |
874 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
875 | pub const fn leading_zeros(self) -> u32 { |
876 | self.0.leading_zeros() |
877 | } |
878 | |
879 | /// Computes the absolute value of `self`, wrapping around at |
880 | /// the boundary of the type. |
881 | /// |
882 | /// The only case where such wrapping can occur is when one takes the absolute value of the negative |
883 | /// minimal value for the type this is a positive value that is too large to represent in the type. In |
884 | /// such a case, this function returns `MIN` itself. |
885 | /// |
886 | /// # Examples |
887 | /// |
888 | /// Basic usage: |
889 | /// |
890 | /// ``` |
891 | /// #![feature(wrapping_int_impl)] |
892 | /// use std::num::Wrapping; |
893 | /// |
894 | #[doc = concat!("assert_eq!(Wrapping(100" , stringify!($t), ").abs(), Wrapping(100));" )] |
895 | #[doc = concat!("assert_eq!(Wrapping(-100" , stringify!($t), ").abs(), Wrapping(100));" )] |
896 | #[doc = concat!("assert_eq!(Wrapping(" , stringify!($t), "::MIN).abs(), Wrapping(" , stringify!($t), "::MIN));" )] |
897 | /// assert_eq!(Wrapping(-128i8).abs().0 as u8, 128u8); |
898 | /// ``` |
899 | #[inline] |
900 | #[must_use = "this returns the result of the operation, \ |
901 | without modifying the original" ] |
902 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
903 | pub fn abs(self) -> Wrapping<$t> { |
904 | Wrapping(self.0.wrapping_abs()) |
905 | } |
906 | |
907 | /// Returns a number representing sign of `self`. |
908 | /// |
909 | /// - `0` if the number is zero |
910 | /// - `1` if the number is positive |
911 | /// - `-1` if the number is negative |
912 | /// |
913 | /// # Examples |
914 | /// |
915 | /// Basic usage: |
916 | /// |
917 | /// ``` |
918 | /// #![feature(wrapping_int_impl)] |
919 | /// use std::num::Wrapping; |
920 | /// |
921 | #[doc = concat!("assert_eq!(Wrapping(10" , stringify!($t), ").signum(), Wrapping(1));" )] |
922 | #[doc = concat!("assert_eq!(Wrapping(0" , stringify!($t), ").signum(), Wrapping(0));" )] |
923 | #[doc = concat!("assert_eq!(Wrapping(-10" , stringify!($t), ").signum(), Wrapping(-1));" )] |
924 | /// ``` |
925 | #[inline] |
926 | #[must_use = "this returns the result of the operation, \ |
927 | without modifying the original" ] |
928 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
929 | pub fn signum(self) -> Wrapping<$t> { |
930 | Wrapping(self.0.signum()) |
931 | } |
932 | |
933 | /// Returns `true` if `self` is positive and `false` if the number is zero or |
934 | /// negative. |
935 | /// |
936 | /// # Examples |
937 | /// |
938 | /// Basic usage: |
939 | /// |
940 | /// ``` |
941 | /// #![feature(wrapping_int_impl)] |
942 | /// use std::num::Wrapping; |
943 | /// |
944 | #[doc = concat!("assert!(Wrapping(10" , stringify!($t), ").is_positive());" )] |
945 | #[doc = concat!("assert!(!Wrapping(-10" , stringify!($t), ").is_positive());" )] |
946 | /// ``` |
947 | #[must_use] |
948 | #[inline] |
949 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
950 | pub const fn is_positive(self) -> bool { |
951 | self.0.is_positive() |
952 | } |
953 | |
954 | /// Returns `true` if `self` is negative and `false` if the number is zero or |
955 | /// positive. |
956 | /// |
957 | /// # Examples |
958 | /// |
959 | /// Basic usage: |
960 | /// |
961 | /// ``` |
962 | /// #![feature(wrapping_int_impl)] |
963 | /// use std::num::Wrapping; |
964 | /// |
965 | #[doc = concat!("assert!(Wrapping(-10" , stringify!($t), ").is_negative());" )] |
966 | #[doc = concat!("assert!(!Wrapping(10" , stringify!($t), ").is_negative());" )] |
967 | /// ``` |
968 | #[must_use] |
969 | #[inline] |
970 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
971 | pub const fn is_negative(self) -> bool { |
972 | self.0.is_negative() |
973 | } |
974 | } |
975 | )*) |
976 | } |
977 | |
978 | wrapping_int_impl_signed! { isize i8 i16 i32 i64 i128 } |
979 | |
980 | macro_rules! wrapping_int_impl_unsigned { |
981 | ($($t:ty)*) => ($( |
982 | impl Wrapping<$t> { |
983 | /// Returns the number of leading zeros in the binary representation of `self`. |
984 | /// |
985 | /// # Examples |
986 | /// |
987 | /// Basic usage: |
988 | /// |
989 | /// ``` |
990 | /// #![feature(wrapping_int_impl)] |
991 | /// use std::num::Wrapping; |
992 | /// |
993 | #[doc = concat!("let n = Wrapping(" , stringify!($t), "::MAX) >> 2;" )] |
994 | /// |
995 | /// assert_eq!(n.leading_zeros(), 2); |
996 | /// ``` |
997 | #[inline] |
998 | #[must_use = "this returns the result of the operation, \ |
999 | without modifying the original" ] |
1000 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
1001 | pub const fn leading_zeros(self) -> u32 { |
1002 | self.0.leading_zeros() |
1003 | } |
1004 | |
1005 | /// Returns `true` if and only if `self == 2^k` for some `k`. |
1006 | /// |
1007 | /// # Examples |
1008 | /// |
1009 | /// Basic usage: |
1010 | /// |
1011 | /// ``` |
1012 | /// #![feature(wrapping_int_impl)] |
1013 | /// use std::num::Wrapping; |
1014 | /// |
1015 | #[doc = concat!("assert!(Wrapping(16" , stringify!($t), ").is_power_of_two());" )] |
1016 | #[doc = concat!("assert!(!Wrapping(10" , stringify!($t), ").is_power_of_two());" )] |
1017 | /// ``` |
1018 | #[must_use] |
1019 | #[inline] |
1020 | #[unstable(feature = "wrapping_int_impl" , issue = "32463" )] |
1021 | pub fn is_power_of_two(self) -> bool { |
1022 | self.0.is_power_of_two() |
1023 | } |
1024 | |
1025 | /// Returns the smallest power of two greater than or equal to `self`. |
1026 | /// |
1027 | /// When return value overflows (i.e., `self > (1 << (N-1))` for type |
1028 | /// `uN`), overflows to `2^N = 0`. |
1029 | /// |
1030 | /// # Examples |
1031 | /// |
1032 | /// Basic usage: |
1033 | /// |
1034 | /// ``` |
1035 | /// #![feature(wrapping_next_power_of_two)] |
1036 | /// use std::num::Wrapping; |
1037 | /// |
1038 | #[doc = concat!("assert_eq!(Wrapping(2" , stringify!($t), ").next_power_of_two(), Wrapping(2));" )] |
1039 | #[doc = concat!("assert_eq!(Wrapping(3" , stringify!($t), ").next_power_of_two(), Wrapping(4));" )] |
1040 | #[doc = concat!("assert_eq!(Wrapping(200_u8).next_power_of_two(), Wrapping(0));" )] |
1041 | /// ``` |
1042 | #[inline] |
1043 | #[must_use = "this returns the result of the operation, \ |
1044 | without modifying the original" ] |
1045 | #[unstable(feature = "wrapping_next_power_of_two" , issue = "32463" , |
1046 | reason = "needs decision on wrapping behaviour" )] |
1047 | pub fn next_power_of_two(self) -> Self { |
1048 | Wrapping(self.0.wrapping_next_power_of_two()) |
1049 | } |
1050 | } |
1051 | )*) |
1052 | } |
1053 | |
1054 | wrapping_int_impl_unsigned! { usize u8 u16 u32 u64 u128 } |
1055 | |
1056 | mod shift_max { |
1057 | #![allow (non_upper_case_globals)] |
1058 | |
1059 | #[cfg (target_pointer_width = "16" )] |
1060 | mod platform { |
1061 | pub const usize: u32 = super::u16; |
1062 | pub const isize: u32 = super::i16; |
1063 | } |
1064 | |
1065 | #[cfg (target_pointer_width = "32" )] |
1066 | mod platform { |
1067 | pub const usize: u32 = super::u32; |
1068 | pub const isize: u32 = super::i32; |
1069 | } |
1070 | |
1071 | #[cfg (target_pointer_width = "64" )] |
1072 | mod platform { |
1073 | pub const usize: u32 = super::u64; |
1074 | pub const isize: u32 = super::i64; |
1075 | } |
1076 | |
1077 | pub const i8: u32 = (1 << 3) - 1; |
1078 | pub const i16: u32 = (1 << 4) - 1; |
1079 | pub const i32: u32 = (1 << 5) - 1; |
1080 | pub const i64: u32 = (1 << 6) - 1; |
1081 | pub const i128: u32 = (1 << 7) - 1; |
1082 | pub use self::platform::isize; |
1083 | |
1084 | pub const u8: u32 = i8; |
1085 | pub const u16: u32 = i16; |
1086 | pub const u32: u32 = i32; |
1087 | pub const u64: u32 = i64; |
1088 | pub const u128: u32 = i128; |
1089 | pub use self::platform::usize; |
1090 | } |
1091 | |