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