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