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