]> git.proxmox.com Git - rustc.git/blame - library/core/src/num/wrapping.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / library / core / src / num / wrapping.rs
CommitLineData
1b1a35ee 1//! Definitions of `Wrapping<T>`.
c34b1796 2
1b1a35ee
XL
3use crate::fmt;
4use crate::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign};
5use crate::ops::{BitXor, BitXorAssign, Div, DivAssign};
6use crate::ops::{Mul, MulAssign, Neg, Not, Rem, RemAssign};
7use 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)]
38pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
39
40#[stable(feature = "rust1", since = "1.0.0")]
41impl<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")]
48impl<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")]
55impl<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")]
62impl<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")]
69impl<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")]
76impl<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}
c34b1796 81
7cac9316 82#[allow(unused_macros)]
9cc50fc6 83macro_rules! sh_impl_signed {
60c5eb7d 84 ($t:ident, $f:ident) => {
c34b1796
AL
85 #[stable(feature = "rust1", since = "1.0.0")]
86 impl Shl<$f> for Wrapping<$t> {
87 type Output = Wrapping<$t>;
88
3b2f2976 89 #[inline]
c34b1796 90 fn shl(self, other: $f) -> Wrapping<$t> {
9cc50fc6
SL
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 }
e1599b0c 98 forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f,
60c5eb7d 99 #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
9cc50fc6 100
c30ab7b3 101 #[stable(feature = "op_assign_traits", since = "1.8.0")]
9cc50fc6 102 impl ShlAssign<$f> for Wrapping<$t> {
3b2f2976 103 #[inline]
9cc50fc6
SL
104 fn shl_assign(&mut self, other: $f) {
105 *self = *self << other;
106 }
107 }
ea8adc8c 108 forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f }
9cc50fc6
SL
109
110 #[stable(feature = "rust1", since = "1.0.0")]
111 impl Shr<$f> for Wrapping<$t> {
112 type Output = Wrapping<$t>;
113
3b2f2976 114 #[inline]
9cc50fc6
SL
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 }
e1599b0c 123 forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f,
60c5eb7d 124 #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
9cc50fc6 125
c30ab7b3 126 #[stable(feature = "op_assign_traits", since = "1.8.0")]
9cc50fc6 127 impl ShrAssign<$f> for Wrapping<$t> {
3b2f2976 128 #[inline]
9cc50fc6
SL
129 fn shr_assign(&mut self, other: $f) {
130 *self = *self >> other;
131 }
132 }
ea8adc8c 133 forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f }
60c5eb7d 134 };
9cc50fc6
SL
135}
136
137macro_rules! sh_impl_unsigned {
60c5eb7d 138 ($t:ident, $f:ident) => {
9cc50fc6
SL
139 #[stable(feature = "rust1", since = "1.0.0")]
140 impl Shl<$f> for Wrapping<$t> {
141 type Output = Wrapping<$t>;
142
3b2f2976 143 #[inline]
9cc50fc6
SL
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 }
e1599b0c 148 forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f,
60c5eb7d 149 #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
9cc50fc6 150
c30ab7b3 151 #[stable(feature = "op_assign_traits", since = "1.8.0")]
9cc50fc6 152 impl ShlAssign<$f> for Wrapping<$t> {
3b2f2976 153 #[inline]
9cc50fc6
SL
154 fn shl_assign(&mut self, other: $f) {
155 *self = *self << other;
c34b1796
AL
156 }
157 }
ea8adc8c 158 forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f }
c34b1796
AL
159
160 #[stable(feature = "rust1", since = "1.0.0")]
161 impl Shr<$f> for Wrapping<$t> {
162 type Output = Wrapping<$t>;
163
3b2f2976 164 #[inline]
c34b1796 165 fn shr(self, other: $f) -> Wrapping<$t> {
9cc50fc6
SL
166 Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32))
167 }
168 }
e1599b0c 169 forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f,
60c5eb7d 170 #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
9cc50fc6 171
c30ab7b3 172 #[stable(feature = "op_assign_traits", since = "1.8.0")]
9cc50fc6 173 impl ShrAssign<$f> for Wrapping<$t> {
3b2f2976 174 #[inline]
9cc50fc6
SL
175 fn shr_assign(&mut self, other: $f) {
176 *self = *self >> other;
c34b1796
AL
177 }
178 }
ea8adc8c 179 forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f }
60c5eb7d 180 };
c34b1796
AL
181}
182
183// FIXME (#23545): uncomment the remaining impls
184macro_rules! sh_impl_all {
9cc50fc6
SL
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 }
94b46f34 190 //sh_impl_unsigned! { $t, u128 }
9cc50fc6
SL
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 }
94b46f34 197 //sh_impl_signed! { $t, i128 }
9cc50fc6 198 //sh_impl_signed! { $t, isize }
c34b1796
AL
199 )*)
200}
201
94b46f34 202sh_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
c34b1796 203
9cc50fc6 204// FIXME(30524): impl Op<T> for Wrapping<T>, impl OpAssign<T> for Wrapping<T>
c34b1796
AL
205macro_rules! wrapping_impl {
206 ($($t:ty)*) => ($(
c34b1796
AL
207 #[stable(feature = "rust1", since = "1.0.0")]
208 impl Add for Wrapping<$t> {
209 type Output = Wrapping<$t>;
210
3b2f2976 211 #[inline]
c34b1796
AL
212 fn add(self, other: Wrapping<$t>) -> Wrapping<$t> {
213 Wrapping(self.0.wrapping_add(other.0))
214 }
215 }
8bb4bdeb
XL
216 forward_ref_binop! { impl Add, add for Wrapping<$t>, Wrapping<$t>,
217 #[stable(feature = "wrapping_ref", since = "1.14.0")] }
c34b1796 218
7453a54e 219 #[stable(feature = "op_assign_traits", since = "1.8.0")]
9cc50fc6 220 impl AddAssign for Wrapping<$t> {
3b2f2976 221 #[inline]
9cc50fc6
SL
222 fn add_assign(&mut self, other: Wrapping<$t>) {
223 *self = *self + other;
224 }
225 }
ea8adc8c 226 forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> }
9cc50fc6 227
c34b1796
AL
228 #[stable(feature = "rust1", since = "1.0.0")]
229 impl Sub for Wrapping<$t> {
230 type Output = Wrapping<$t>;
231
3b2f2976 232 #[inline]
c34b1796
AL
233 fn sub(self, other: Wrapping<$t>) -> Wrapping<$t> {
234 Wrapping(self.0.wrapping_sub(other.0))
235 }
236 }
8bb4bdeb
XL
237 forward_ref_binop! { impl Sub, sub for Wrapping<$t>, Wrapping<$t>,
238 #[stable(feature = "wrapping_ref", since = "1.14.0")] }
c34b1796 239
7453a54e 240 #[stable(feature = "op_assign_traits", since = "1.8.0")]
9cc50fc6 241 impl SubAssign for Wrapping<$t> {
3b2f2976 242 #[inline]
9cc50fc6
SL
243 fn sub_assign(&mut self, other: Wrapping<$t>) {
244 *self = *self - other;
245 }
246 }
ea8adc8c 247 forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> }
9cc50fc6 248
c34b1796
AL
249 #[stable(feature = "rust1", since = "1.0.0")]
250 impl Mul for Wrapping<$t> {
251 type Output = Wrapping<$t>;
252
3b2f2976 253 #[inline]
c34b1796
AL
254 fn mul(self, other: Wrapping<$t>) -> Wrapping<$t> {
255 Wrapping(self.0.wrapping_mul(other.0))
256 }
257 }
8bb4bdeb
XL
258 forward_ref_binop! { impl Mul, mul for Wrapping<$t>, Wrapping<$t>,
259 #[stable(feature = "wrapping_ref", since = "1.14.0")] }
c34b1796 260
7453a54e 261 #[stable(feature = "op_assign_traits", since = "1.8.0")]
9cc50fc6 262 impl MulAssign for Wrapping<$t> {
3b2f2976 263 #[inline]
9cc50fc6
SL
264 fn mul_assign(&mut self, other: Wrapping<$t>) {
265 *self = *self * other;
266 }
267 }
ea8adc8c 268 forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> }
9cc50fc6 269
c1a9b12d
SL
270 #[stable(feature = "wrapping_div", since = "1.3.0")]
271 impl Div for Wrapping<$t> {
272 type Output = Wrapping<$t>;
273
3b2f2976 274 #[inline]
c1a9b12d
SL
275 fn div(self, other: Wrapping<$t>) -> Wrapping<$t> {
276 Wrapping(self.0.wrapping_div(other.0))
277 }
278 }
8bb4bdeb
XL
279 forward_ref_binop! { impl Div, div for Wrapping<$t>, Wrapping<$t>,
280 #[stable(feature = "wrapping_ref", since = "1.14.0")] }
c1a9b12d 281
7453a54e 282 #[stable(feature = "op_assign_traits", since = "1.8.0")]
9cc50fc6 283 impl DivAssign for Wrapping<$t> {
3b2f2976 284 #[inline]
9cc50fc6
SL
285 fn div_assign(&mut self, other: Wrapping<$t>) {
286 *self = *self / other;
287 }
288 }
ea8adc8c 289 forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> }
9cc50fc6 290
54a0048b 291 #[stable(feature = "wrapping_impls", since = "1.7.0")]
9cc50fc6
SL
292 impl Rem for Wrapping<$t> {
293 type Output = Wrapping<$t>;
294
3b2f2976 295 #[inline]
9cc50fc6
SL
296 fn rem(self, other: Wrapping<$t>) -> Wrapping<$t> {
297 Wrapping(self.0.wrapping_rem(other.0))
298 }
299 }
8bb4bdeb
XL
300 forward_ref_binop! { impl Rem, rem for Wrapping<$t>, Wrapping<$t>,
301 #[stable(feature = "wrapping_ref", since = "1.14.0")] }
9cc50fc6 302
7453a54e 303 #[stable(feature = "op_assign_traits", since = "1.8.0")]
9cc50fc6 304 impl RemAssign for Wrapping<$t> {
3b2f2976 305 #[inline]
9cc50fc6
SL
306 fn rem_assign(&mut self, other: Wrapping<$t>) {
307 *self = *self % other;
308 }
309 }
ea8adc8c 310 forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> }
9cc50fc6 311
c34b1796
AL
312 #[stable(feature = "rust1", since = "1.0.0")]
313 impl Not for Wrapping<$t> {
314 type Output = Wrapping<$t>;
315
3b2f2976 316 #[inline]
c34b1796
AL
317 fn not(self) -> Wrapping<$t> {
318 Wrapping(!self.0)
319 }
320 }
8bb4bdeb
XL
321 forward_ref_unop! { impl Not, not for Wrapping<$t>,
322 #[stable(feature = "wrapping_ref", since = "1.14.0")] }
c34b1796
AL
323
324 #[stable(feature = "rust1", since = "1.0.0")]
325 impl BitXor for Wrapping<$t> {
326 type Output = Wrapping<$t>;
327
3b2f2976 328 #[inline]
c34b1796
AL
329 fn bitxor(self, other: Wrapping<$t>) -> Wrapping<$t> {
330 Wrapping(self.0 ^ other.0)
331 }
332 }
8bb4bdeb
XL
333 forward_ref_binop! { impl BitXor, bitxor for Wrapping<$t>, Wrapping<$t>,
334 #[stable(feature = "wrapping_ref", since = "1.14.0")] }
c34b1796 335
7453a54e 336 #[stable(feature = "op_assign_traits", since = "1.8.0")]
9cc50fc6 337 impl BitXorAssign for Wrapping<$t> {
3b2f2976 338 #[inline]
9cc50fc6
SL
339 fn bitxor_assign(&mut self, other: Wrapping<$t>) {
340 *self = *self ^ other;
341 }
342 }
ea8adc8c 343 forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> }
9cc50fc6 344
c34b1796
AL
345 #[stable(feature = "rust1", since = "1.0.0")]
346 impl BitOr for Wrapping<$t> {
347 type Output = Wrapping<$t>;
348
3b2f2976 349 #[inline]
c34b1796
AL
350 fn bitor(self, other: Wrapping<$t>) -> Wrapping<$t> {
351 Wrapping(self.0 | other.0)
352 }
353 }
8bb4bdeb
XL
354 forward_ref_binop! { impl BitOr, bitor for Wrapping<$t>, Wrapping<$t>,
355 #[stable(feature = "wrapping_ref", since = "1.14.0")] }
c34b1796 356
7453a54e 357 #[stable(feature = "op_assign_traits", since = "1.8.0")]
9cc50fc6 358 impl BitOrAssign for Wrapping<$t> {
3b2f2976 359 #[inline]
9cc50fc6
SL
360 fn bitor_assign(&mut self, other: Wrapping<$t>) {
361 *self = *self | other;
362 }
363 }
ea8adc8c 364 forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> }
9cc50fc6 365
c34b1796
AL
366 #[stable(feature = "rust1", since = "1.0.0")]
367 impl BitAnd for Wrapping<$t> {
368 type Output = Wrapping<$t>;
369
3b2f2976 370 #[inline]
c34b1796
AL
371 fn bitand(self, other: Wrapping<$t>) -> Wrapping<$t> {
372 Wrapping(self.0 & other.0)
373 }
374 }
8bb4bdeb
XL
375 forward_ref_binop! { impl BitAnd, bitand for Wrapping<$t>, Wrapping<$t>,
376 #[stable(feature = "wrapping_ref", since = "1.14.0")] }
9cc50fc6 377
7453a54e 378 #[stable(feature = "op_assign_traits", since = "1.8.0")]
9cc50fc6 379 impl BitAndAssign for Wrapping<$t> {
3b2f2976 380 #[inline]
9cc50fc6
SL
381 fn bitand_assign(&mut self, other: Wrapping<$t>) {
382 *self = *self & other;
383 }
384 }
ea8adc8c 385 forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> }
a7813a04
XL
386
387 #[stable(feature = "wrapping_neg", since = "1.10.0")]
388 impl Neg for Wrapping<$t> {
389 type Output = Self;
3b2f2976 390 #[inline]
a7813a04
XL
391 fn neg(self) -> Self {
392 Wrapping(0) - self
393 }
394 }
8bb4bdeb
XL
395 forward_ref_unop! { impl Neg, neg for Wrapping<$t>,
396 #[stable(feature = "wrapping_ref", since = "1.14.0")] }
0531ce1d 397
c34b1796
AL
398 )*)
399}
400
8bb4bdeb 401wrapping_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
c34b1796 402
0531ce1d
XL
403macro_rules! wrapping_int_impl {
404 ($($t:ty)*) => ($(
405 impl Wrapping<$t> {
94b46f34
XL
406 doc_comment! {
407 concat!("Returns the smallest value that can be represented by this integer type.
408
409# Examples
410
411Basic usage:
412
413```
414#![feature(wrapping_int_impl)]
415use std::num::Wrapping;
416
f9f354fc 417assert_eq!(<Wrapping<", stringify!($t), ">>::MIN, Wrapping(", stringify!($t), "::MIN));
94b46f34
XL
418```"),
419 #[unstable(feature = "wrapping_int_impl", issue = "32463")]
f9f354fc 420 pub const MIN: Self = Self(<$t>::MIN);
0531ce1d
XL
421 }
422
94b46f34
XL
423 doc_comment! {
424 concat!("Returns the largest value that can be represented by this integer type.
425
426# Examples
427
428Basic usage:
429
430```
431#![feature(wrapping_int_impl)]
432use std::num::Wrapping;
433
f9f354fc 434assert_eq!(<Wrapping<", stringify!($t), ">>::MAX, Wrapping(", stringify!($t), "::MAX));
94b46f34
XL
435```"),
436 #[unstable(feature = "wrapping_int_impl", issue = "32463")]
f9f354fc 437 pub const MAX: Self = Self(<$t>::MAX);
0531ce1d
XL
438 }
439
94b46f34
XL
440 doc_comment! {
441 concat!("Returns the number of ones in the binary representation of `self`.
442
443# Examples
444
445Basic usage:
446
447```
448#![feature(wrapping_int_impl)]
449use std::num::Wrapping;
450
451let n = Wrapping(0b01001100", stringify!($t), ");
452
453assert_eq!(n.count_ones(), 3);
454```"),
455 #[inline]
456 #[unstable(feature = "wrapping_int_impl", issue = "32463")]
a1dfa0c6 457 pub const fn count_ones(self) -> u32 {
94b46f34
XL
458 self.0.count_ones()
459 }
0531ce1d
XL
460 }
461
94b46f34
XL
462 doc_comment! {
463 concat!("Returns the number of zeros in the binary representation of `self`.
464
465# Examples
466
467Basic usage:
468
469```
470#![feature(wrapping_int_impl)]
471use std::num::Wrapping;
472
473assert_eq!(Wrapping(!0", stringify!($t), ").count_zeros(), 0);
474```"),
475 #[inline]
476 #[unstable(feature = "wrapping_int_impl", issue = "32463")]
a1dfa0c6 477 pub const fn count_zeros(self) -> u32 {
94b46f34
XL
478 self.0.count_zeros()
479 }
480 }
481
482 doc_comment! {
483 concat!("Returns the number of trailing zeros in the binary representation
484of `self`.
485
486# Examples
487
488Basic usage:
489
490```
491#![feature(wrapping_int_impl)]
492use std::num::Wrapping;
493
494let n = Wrapping(0b0101000", stringify!($t), ");
495
496assert_eq!(n.trailing_zeros(), 3);
497```"),
498 #[inline]
499 #[unstable(feature = "wrapping_int_impl", issue = "32463")]
a1dfa0c6 500 pub const fn trailing_zeros(self) -> u32 {
94b46f34
XL
501 self.0.trailing_zeros()
502 }
0531ce1d
XL
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 ///
e74abb32 509 /// Please note this isn't the same operation as the `<<` shifting
532ac7d7 510 /// operator!
0531ce1d
XL
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")]
a1dfa0c6 527 pub const fn rotate_left(self, n: u32) -> Self {
0531ce1d
XL
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 ///
e74abb32 535 /// Please note this isn't the same operation as the `>>` shifting
532ac7d7 536 /// operator!
0531ce1d
XL
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")]
a1dfa0c6 553 pub const fn rotate_right(self, n: u32) -> Self {
0531ce1d
XL
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")]
a1dfa0c6 577 pub const fn swap_bytes(self) -> Self {
0531ce1d
XL
578 Wrapping(self.0.swap_bytes())
579 }
580
94b46f34 581 /// Reverses the bit pattern of the integer.
0531ce1d
XL
582 ///
583 /// # Examples
584 ///
94b46f34
XL
585 /// Please note that this example is shared between integer types.
586 /// Which explains why `i16` is used here.
587 ///
0531ce1d
XL
588 /// Basic usage:
589 ///
590 /// ```
0531ce1d
XL
591 /// use std::num::Wrapping;
592 ///
94b46f34
XL
593 /// let n = Wrapping(0b0000000_01010101i16);
594 /// assert_eq!(n, Wrapping(85));
595 ///
596 /// let m = n.reverse_bits();
0531ce1d 597 ///
94b46f34
XL
598 /// assert_eq!(m.0 as u16, 0b10101010_00000000);
599 /// assert_eq!(m, Wrapping(-22016));
0531ce1d 600 /// ```
dc9dc135 601 #[stable(feature = "reverse_bits", since = "1.37.0")]
dfeec247 602 #[rustc_const_stable(feature = "const_reverse_bits", since = "1.37.0")]
0531ce1d 603 #[inline]
dc9dc135 604 #[must_use]
a1dfa0c6 605 pub const fn reverse_bits(self) -> Self {
94b46f34 606 Wrapping(self.0.reverse_bits())
0531ce1d
XL
607 }
608
94b46f34
XL
609 doc_comment! {
610 concat!("Converts an integer from big endian to the target's endianness.
611
612On big endian this is a no-op. On little endian the bytes are
613swapped.
614
615# Examples
616
617Basic usage:
618
619```
620#![feature(wrapping_int_impl)]
621use std::num::Wrapping;
622
623let n = Wrapping(0x1A", stringify!($t), ");
624
625if 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")]
a1dfa0c6 633 pub const fn from_be(x: Self) -> Self {
94b46f34
XL
634 Wrapping(<$t>::from_be(x.0))
635 }
0531ce1d
XL
636 }
637
94b46f34
XL
638 doc_comment! {
639 concat!("Converts an integer from little endian to the target's endianness.
640
641On little endian this is a no-op. On big endian the bytes are
642swapped.
643
644# Examples
645
646Basic usage:
647
648```
649#![feature(wrapping_int_impl)]
650use std::num::Wrapping;
651
652let n = Wrapping(0x1A", stringify!($t), ");
653
654if 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")]
a1dfa0c6 662 pub const fn from_le(x: Self) -> Self {
94b46f34
XL
663 Wrapping(<$t>::from_le(x.0))
664 }
0531ce1d
XL
665 }
666
94b46f34
XL
667 doc_comment! {
668 concat!("Converts `self` to big endian from the target's endianness.
669
670On big endian this is a no-op. On little endian the bytes are
671swapped.
672
673# Examples
674
675Basic usage:
676
677```
678#![feature(wrapping_int_impl)]
679use std::num::Wrapping;
680
681let n = Wrapping(0x1A", stringify!($t), ");
682
683if 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")]
a1dfa0c6 691 pub const fn to_be(self) -> Self {
94b46f34
XL
692 Wrapping(self.0.to_be())
693 }
0531ce1d
XL
694 }
695
94b46f34
XL
696 doc_comment! {
697 concat!("Converts `self` to little endian from the target's endianness.
698
699On little endian this is a no-op. On big endian the bytes are
700swapped.
701
702# Examples
703
704Basic usage:
705
706```
707#![feature(wrapping_int_impl)]
708use std::num::Wrapping;
709
710let n = Wrapping(0x1A", stringify!($t), ");
711
712if 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")]
a1dfa0c6 720 pub const fn to_le(self) -> Self {
94b46f34
XL
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
730Basic usage:
731
732```
733#![feature(wrapping_int_impl)]
734use std::num::Wrapping;
735
736assert_eq!(Wrapping(3", stringify!($t), ").pow(4), Wrapping(81));
737```
738
739Results that are too large are wrapped:
740
741```
742#![feature(wrapping_int_impl)]
743use std::num::Wrapping;
744
745assert_eq!(Wrapping(3i8).pow(5), Wrapping(-13));
746assert_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 }
0531ce1d
XL
753 }
754 }
755 )*)
756}
757
758wrapping_int_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
759
94b46f34
XL
760macro_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
768Basic usage:
769
770```
771#![feature(wrapping_int_impl)]
772use std::num::Wrapping;
773
f035d41b 774let n = Wrapping(", stringify!($t), "::MAX) >> 2;
94b46f34
XL
775
776assert_eq!(n.leading_zeros(), 3);
777```"),
778 #[inline]
779 #[unstable(feature = "wrapping_int_impl", issue = "32463")]
a1dfa0c6 780 pub const fn leading_zeros(self) -> u32 {
94b46f34
XL
781 self.0.leading_zeros()
782 }
783 }
784
785 doc_comment! {
786 concat!("Computes the absolute value of `self`, wrapping around at
787the boundary of the type.
788
789The only case where such wrapping can occur is when one takes the absolute value of the negative
790minimal value for the type this is a positive value that is too large to represent in the type. In
791such a case, this function returns `MIN` itself.
792
793# Examples
794
795Basic usage:
796
797```
798#![feature(wrapping_int_impl)]
799use std::num::Wrapping;
800
801assert_eq!(Wrapping(100", stringify!($t), ").abs(), Wrapping(100));
802assert_eq!(Wrapping(-100", stringify!($t), ").abs(), Wrapping(100));
f035d41b 803assert_eq!(Wrapping(", stringify!($t), "::MIN).abs(), Wrapping(", stringify!($t), "::MIN));
94b46f34
XL
804assert_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
822Basic usage:
823
824```
825#![feature(wrapping_int_impl)]
826use std::num::Wrapping;
827
828assert_eq!(Wrapping(10", stringify!($t), ").signum(), Wrapping(1));
829assert_eq!(Wrapping(0", stringify!($t), ").signum(), Wrapping(0));
830assert_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
841negative.
842
843# Examples
844
845Basic usage:
846
847```
848#![feature(wrapping_int_impl)]
849use std::num::Wrapping;
850
851assert!(Wrapping(10", stringify!($t), ").is_positive());
852assert!(!Wrapping(-10", stringify!($t), ").is_positive());
853```"),
854 #[inline]
855 #[unstable(feature = "wrapping_int_impl", issue = "32463")]
a1dfa0c6 856 pub const fn is_positive(self) -> bool {
94b46f34
XL
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
863positive.
864
865# Examples
866
867Basic usage:
868
869```
870#![feature(wrapping_int_impl)]
871use std::num::Wrapping;
872
873assert!(Wrapping(-10", stringify!($t), ").is_negative());
874assert!(!Wrapping(10", stringify!($t), ").is_negative());
875```"),
876 #[inline]
877 #[unstable(feature = "wrapping_int_impl", issue = "32463")]
a1dfa0c6 878 pub const fn is_negative(self) -> bool {
94b46f34
XL
879 self.0.is_negative()
880 }
881 }
882 }
883 )*)
884}
885
886wrapping_int_impl_signed! { isize i8 i16 i32 i64 i128 }
887
888macro_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
896Basic usage:
897
898```
899#![feature(wrapping_int_impl)]
900use std::num::Wrapping;
901
f035d41b 902let n = Wrapping(", stringify!($t), "::MAX) >> 2;
94b46f34
XL
903
904assert_eq!(n.leading_zeros(), 2);
905```"),
906 #[inline]
907 #[unstable(feature = "wrapping_int_impl", issue = "32463")]
a1dfa0c6 908 pub const fn leading_zeros(self) -> u32 {
94b46f34
XL
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
918Basic usage:
919
920```
921#![feature(wrapping_int_impl)]
922use std::num::Wrapping;
923
924assert!(Wrapping(16", stringify!($t), ").is_power_of_two());
925assert!(!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
0731742a 937When return value overflows (i.e., `self > (1 << (N-1))` for type
94b46f34
XL
938`uN`), overflows to `2^N = 0`.
939
940# Examples
941
942Basic usage:
943
944```
945#![feature(wrapping_next_power_of_two)]
946use std::num::Wrapping;
947
948assert_eq!(Wrapping(2", stringify!($t), ").next_power_of_two(), Wrapping(2));
949assert_eq!(Wrapping(3", stringify!($t), ").next_power_of_two(), Wrapping(4));
950assert_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
963wrapping_int_impl_unsigned! { usize u8 u16 u32 u64 u128 }
0531ce1d 964
c34b1796
AL
965mod shift_max {
966 #![allow(non_upper_case_globals)]
967
3157f602
XL
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
9cc50fc6
SL
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
c30ab7b3 986 pub const i8: u32 = (1 << 3) - 1;
c34b1796
AL
987 pub const i16: u32 = (1 << 4) - 1;
988 pub const i32: u32 = (1 << 5) - 1;
989 pub const i64: u32 = (1 << 6) - 1;
94b46f34 990 pub const i128: u32 = (1 << 7) - 1;
9cc50fc6 991 pub use self::platform::isize;
c34b1796 992
c30ab7b3 993 pub const u8: u32 = i8;
c34b1796
AL
994 pub const u16: u32 = i16;
995 pub const u32: u32 = i32;
996 pub const u64: u32 = i64;
94b46f34 997 pub const u128: u32 = i128;
9cc50fc6 998 pub use self::platform::usize;
c34b1796 999}