]>
Commit | Line | Data |
---|---|---|
1b1a35ee | 1 | //! Definitions of `Wrapping<T>`. |
c34b1796 | 2 | |
1b1a35ee XL |
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 | } | |
c34b1796 | 81 | |
7cac9316 | 82 | #[allow(unused_macros)] |
9cc50fc6 | 83 | macro_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 | ||
137 | macro_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 | |
184 | macro_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 | 202 | sh_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 |
205 | macro_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 | 401 | wrapping_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } |
c34b1796 | 402 | |
0531ce1d XL |
403 | macro_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 | ||
411 | Basic usage: | |
412 | ||
413 | ``` | |
414 | #![feature(wrapping_int_impl)] | |
415 | use std::num::Wrapping; | |
416 | ||
f9f354fc | 417 | assert_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 | ||
428 | Basic usage: | |
429 | ||
430 | ``` | |
431 | #![feature(wrapping_int_impl)] | |
432 | use std::num::Wrapping; | |
433 | ||
f9f354fc | 434 | assert_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 | ||
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")] | |
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 | ||
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")] | |
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 | |
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")] | |
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 | ||
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")] | |
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 | ||
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")] | |
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 | ||
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")] | |
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 | ||
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")] | |
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 | ||
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 | } | |
0531ce1d XL |
753 | } |
754 | } | |
755 | )*) | |
756 | } | |
757 | ||
758 | wrapping_int_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } | |
759 | ||
94b46f34 XL |
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 | ||
f035d41b | 774 | let n = Wrapping(", stringify!($t), "::MAX) >> 2; |
94b46f34 XL |
775 | |
776 | assert_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 | |
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)); | |
f035d41b | 803 | assert_eq!(Wrapping(", stringify!($t), "::MIN).abs(), Wrapping(", stringify!($t), "::MIN)); |
94b46f34 XL |
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")] | |
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 | |
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")] | |
a1dfa0c6 | 878 | pub const fn is_negative(self) -> bool { |
94b46f34 XL |
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 | ||
f035d41b | 902 | let n = Wrapping(", stringify!($t), "::MAX) >> 2; |
94b46f34 XL |
903 | |
904 | assert_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 | ||
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 | ||
0731742a | 937 | When return value overflows (i.e., `self > (1 << (N-1))` for type |
94b46f34 XL |
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 } | |
0531ce1d | 964 | |
c34b1796 AL |
965 | mod 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 | } |