]>
Commit | Line | Data |
---|---|---|
1b1a35ee | 1 | macro_rules! uint_impl { |
5869c6ff | 2 | ($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr, |
1b1a35ee XL |
3 | $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr, |
4 | $reversed:expr, $le_bytes:expr, $be_bytes:expr, | |
5 | $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => { | |
5869c6ff XL |
6 | /// The smallest value that can be represented by this integer type. |
7 | /// | |
8 | /// # Examples | |
9 | /// | |
10 | /// Basic usage: | |
11 | /// | |
12 | /// ``` | |
13 | #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN, 0);")] | |
14 | /// ``` | |
15 | #[stable(feature = "assoc_int_consts", since = "1.43.0")] | |
16 | pub const MIN: Self = 0; | |
1b1a35ee | 17 | |
5869c6ff XL |
18 | /// The largest value that can be represented by this integer type. |
19 | /// | |
20 | /// # Examples | |
21 | /// | |
22 | /// Basic usage: | |
23 | /// | |
24 | /// ``` | |
25 | #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($MaxV), ");")] | |
26 | /// ``` | |
27 | #[stable(feature = "assoc_int_consts", since = "1.43.0")] | |
28 | pub const MAX: Self = !0; | |
1b1a35ee | 29 | |
5869c6ff XL |
30 | /// The size of this integer type in bits. |
31 | /// | |
32 | /// # Examples | |
33 | /// | |
34 | /// ``` | |
5869c6ff XL |
35 | #[doc = concat!("assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");")] |
36 | /// ``` | |
cdc7bbd5 | 37 | #[stable(feature = "int_bits_const", since = "1.53.0")] |
5869c6ff | 38 | pub const BITS: u32 = $BITS; |
1b1a35ee | 39 | |
5869c6ff XL |
40 | /// Converts a string slice in a given base to an integer. |
41 | /// | |
42 | /// The string is expected to be an optional `+` sign | |
43 | /// followed by digits. | |
44 | /// Leading and trailing whitespace represent an error. | |
45 | /// Digits are a subset of these characters, depending on `radix`: | |
46 | /// | |
47 | /// * `0-9` | |
48 | /// * `a-z` | |
49 | /// * `A-Z` | |
50 | /// | |
51 | /// # Panics | |
52 | /// | |
53 | /// This function panics if `radix` is not in the range from 2 to 36. | |
54 | /// | |
55 | /// # Examples | |
56 | /// | |
57 | /// Basic usage: | |
58 | /// | |
59 | /// ``` | |
60 | #[doc = concat!("assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));")] | |
61 | /// ``` | |
62 | #[stable(feature = "rust1", since = "1.0.0")] | |
63 | pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> { | |
64 | from_str_radix(src, radix) | |
1b1a35ee XL |
65 | } |
66 | ||
5869c6ff XL |
67 | /// Returns the number of ones in the binary representation of `self`. |
68 | /// | |
69 | /// # Examples | |
70 | /// | |
71 | /// Basic usage: | |
72 | /// | |
73 | /// ``` | |
74 | #[doc = concat!("let n = 0b01001100", stringify!($SelfT), ";")] | |
75 | /// | |
76 | /// assert_eq!(n.count_ones(), 3); | |
77 | /// ``` | |
78 | #[stable(feature = "rust1", since = "1.0.0")] | |
79 | #[rustc_const_stable(feature = "const_math", since = "1.32.0")] | |
80 | #[doc(alias = "popcount")] | |
81 | #[doc(alias = "popcnt")] | |
cdc7bbd5 | 82 | #[inline(always)] |
5869c6ff XL |
83 | pub const fn count_ones(self) -> u32 { |
84 | intrinsics::ctpop(self as $ActualT) as u32 | |
1b1a35ee XL |
85 | } |
86 | ||
5869c6ff XL |
87 | /// Returns the number of zeros in the binary representation of `self`. |
88 | /// | |
89 | /// # Examples | |
90 | /// | |
91 | /// Basic usage: | |
92 | /// | |
93 | /// ``` | |
94 | #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.count_zeros(), 0);")] | |
95 | /// ``` | |
96 | #[stable(feature = "rust1", since = "1.0.0")] | |
97 | #[rustc_const_stable(feature = "const_math", since = "1.32.0")] | |
cdc7bbd5 | 98 | #[inline(always)] |
5869c6ff XL |
99 | pub const fn count_zeros(self) -> u32 { |
100 | (!self).count_ones() | |
1b1a35ee XL |
101 | } |
102 | ||
5869c6ff XL |
103 | /// Returns the number of leading zeros in the binary representation of `self`. |
104 | /// | |
105 | /// # Examples | |
106 | /// | |
107 | /// Basic usage: | |
108 | /// | |
109 | /// ``` | |
110 | #[doc = concat!("let n = ", stringify!($SelfT), "::MAX >> 2;")] | |
111 | /// | |
112 | /// assert_eq!(n.leading_zeros(), 2); | |
113 | /// ``` | |
114 | #[stable(feature = "rust1", since = "1.0.0")] | |
115 | #[rustc_const_stable(feature = "const_math", since = "1.32.0")] | |
cdc7bbd5 | 116 | #[inline(always)] |
5869c6ff XL |
117 | pub const fn leading_zeros(self) -> u32 { |
118 | intrinsics::ctlz(self as $ActualT) as u32 | |
1b1a35ee XL |
119 | } |
120 | ||
5869c6ff XL |
121 | /// Returns the number of trailing zeros in the binary representation |
122 | /// of `self`. | |
123 | /// | |
124 | /// # Examples | |
125 | /// | |
126 | /// Basic usage: | |
127 | /// | |
128 | /// ``` | |
129 | #[doc = concat!("let n = 0b0101000", stringify!($SelfT), ";")] | |
130 | /// | |
131 | /// assert_eq!(n.trailing_zeros(), 3); | |
132 | /// ``` | |
133 | #[stable(feature = "rust1", since = "1.0.0")] | |
134 | #[rustc_const_stable(feature = "const_math", since = "1.32.0")] | |
cdc7bbd5 | 135 | #[inline(always)] |
5869c6ff XL |
136 | pub const fn trailing_zeros(self) -> u32 { |
137 | intrinsics::cttz(self) as u32 | |
1b1a35ee XL |
138 | } |
139 | ||
5869c6ff XL |
140 | /// Returns the number of leading ones in the binary representation of `self`. |
141 | /// | |
142 | /// # Examples | |
143 | /// | |
144 | /// Basic usage: | |
145 | /// | |
146 | /// ``` | |
147 | #[doc = concat!("let n = !(", stringify!($SelfT), "::MAX >> 2);")] | |
148 | /// | |
149 | /// assert_eq!(n.leading_ones(), 2); | |
150 | /// ``` | |
151 | #[stable(feature = "leading_trailing_ones", since = "1.46.0")] | |
152 | #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")] | |
cdc7bbd5 | 153 | #[inline(always)] |
5869c6ff XL |
154 | pub const fn leading_ones(self) -> u32 { |
155 | (!self).leading_zeros() | |
1b1a35ee XL |
156 | } |
157 | ||
5869c6ff XL |
158 | /// Returns the number of trailing ones in the binary representation |
159 | /// of `self`. | |
160 | /// | |
161 | /// # Examples | |
162 | /// | |
163 | /// Basic usage: | |
164 | /// | |
165 | /// ``` | |
166 | #[doc = concat!("let n = 0b1010111", stringify!($SelfT), ";")] | |
167 | /// | |
168 | /// assert_eq!(n.trailing_ones(), 3); | |
169 | /// ``` | |
170 | #[stable(feature = "leading_trailing_ones", since = "1.46.0")] | |
171 | #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")] | |
cdc7bbd5 | 172 | #[inline(always)] |
5869c6ff XL |
173 | pub const fn trailing_ones(self) -> u32 { |
174 | (!self).trailing_zeros() | |
1b1a35ee XL |
175 | } |
176 | ||
5869c6ff XL |
177 | /// Shifts the bits to the left by a specified amount, `n`, |
178 | /// wrapping the truncated bits to the end of the resulting integer. | |
179 | /// | |
180 | /// Please note this isn't the same operation as the `<<` shifting operator! | |
181 | /// | |
182 | /// # Examples | |
183 | /// | |
184 | /// Basic usage: | |
185 | /// | |
186 | /// ``` | |
187 | #[doc = concat!("let n = ", $rot_op, stringify!($SelfT), ";")] | |
188 | #[doc = concat!("let m = ", $rot_result, ";")] | |
189 | /// | |
190 | #[doc = concat!("assert_eq!(n.rotate_left(", $rot, "), m);")] | |
191 | /// ``` | |
192 | #[stable(feature = "rust1", since = "1.0.0")] | |
193 | #[rustc_const_stable(feature = "const_math", since = "1.32.0")] | |
194 | #[must_use = "this returns the result of the operation, \ | |
195 | without modifying the original"] | |
cdc7bbd5 | 196 | #[inline(always)] |
5869c6ff XL |
197 | pub const fn rotate_left(self, n: u32) -> Self { |
198 | intrinsics::rotate_left(self, n as $SelfT) | |
1b1a35ee XL |
199 | } |
200 | ||
5869c6ff XL |
201 | /// Shifts the bits to the right by a specified amount, `n`, |
202 | /// wrapping the truncated bits to the beginning of the resulting | |
203 | /// integer. | |
204 | /// | |
205 | /// Please note this isn't the same operation as the `>>` shifting operator! | |
206 | /// | |
207 | /// # Examples | |
208 | /// | |
209 | /// Basic usage: | |
210 | /// | |
211 | /// ``` | |
212 | #[doc = concat!("let n = ", $rot_result, stringify!($SelfT), ";")] | |
213 | #[doc = concat!("let m = ", $rot_op, ";")] | |
214 | /// | |
215 | #[doc = concat!("assert_eq!(n.rotate_right(", $rot, "), m);")] | |
216 | /// ``` | |
217 | #[stable(feature = "rust1", since = "1.0.0")] | |
218 | #[rustc_const_stable(feature = "const_math", since = "1.32.0")] | |
219 | #[must_use = "this returns the result of the operation, \ | |
220 | without modifying the original"] | |
cdc7bbd5 | 221 | #[inline(always)] |
5869c6ff XL |
222 | pub const fn rotate_right(self, n: u32) -> Self { |
223 | intrinsics::rotate_right(self, n as $SelfT) | |
1b1a35ee XL |
224 | } |
225 | ||
5869c6ff XL |
226 | /// Reverses the byte order of the integer. |
227 | /// | |
228 | /// # Examples | |
229 | /// | |
230 | /// Basic usage: | |
231 | /// | |
232 | /// ``` | |
233 | #[doc = concat!("let n = ", $swap_op, stringify!($SelfT), ";")] | |
234 | /// let m = n.swap_bytes(); | |
235 | /// | |
236 | #[doc = concat!("assert_eq!(m, ", $swapped, ");")] | |
237 | /// ``` | |
238 | #[stable(feature = "rust1", since = "1.0.0")] | |
239 | #[rustc_const_stable(feature = "const_math", since = "1.32.0")] | |
cdc7bbd5 | 240 | #[inline(always)] |
5869c6ff XL |
241 | pub const fn swap_bytes(self) -> Self { |
242 | intrinsics::bswap(self as $ActualT) as Self | |
1b1a35ee XL |
243 | } |
244 | ||
5869c6ff XL |
245 | /// Reverses the order of bits in the integer. The least significant bit becomes the most significant bit, |
246 | /// second least-significant bit becomes second most-significant bit, etc. | |
247 | /// | |
248 | /// # Examples | |
249 | /// | |
250 | /// Basic usage: | |
251 | /// | |
252 | /// ``` | |
253 | #[doc = concat!("let n = ", $swap_op, stringify!($SelfT), ";")] | |
254 | /// let m = n.reverse_bits(); | |
255 | /// | |
256 | #[doc = concat!("assert_eq!(m, ", $reversed, ");")] | |
257 | #[doc = concat!("assert_eq!(0, 0", stringify!($SelfT), ".reverse_bits());")] | |
258 | /// ``` | |
259 | #[stable(feature = "reverse_bits", since = "1.37.0")] | |
cdc7bbd5 XL |
260 | #[rustc_const_stable(feature = "const_math", since = "1.37.0")] |
261 | #[inline(always)] | |
5869c6ff XL |
262 | #[must_use] |
263 | pub const fn reverse_bits(self) -> Self { | |
264 | intrinsics::bitreverse(self as $ActualT) as Self | |
1b1a35ee XL |
265 | } |
266 | ||
5869c6ff XL |
267 | /// Converts an integer from big endian to the target's endianness. |
268 | /// | |
269 | /// On big endian this is a no-op. On little endian the bytes are | |
270 | /// swapped. | |
271 | /// | |
272 | /// # Examples | |
273 | /// | |
274 | /// Basic usage: | |
275 | /// | |
276 | /// ``` | |
277 | #[doc = concat!("let n = 0x1A", stringify!($SelfT), ";")] | |
278 | /// | |
279 | /// if cfg!(target_endian = "big") { | |
280 | #[doc = concat!(" assert_eq!(", stringify!($SelfT), "::from_be(n), n)")] | |
281 | /// } else { | |
282 | #[doc = concat!(" assert_eq!(", stringify!($SelfT), "::from_be(n), n.swap_bytes())")] | |
283 | /// } | |
284 | /// ``` | |
285 | #[stable(feature = "rust1", since = "1.0.0")] | |
286 | #[rustc_const_stable(feature = "const_math", since = "1.32.0")] | |
cdc7bbd5 | 287 | #[inline(always)] |
5869c6ff XL |
288 | pub const fn from_be(x: Self) -> Self { |
289 | #[cfg(target_endian = "big")] | |
290 | { | |
291 | x | |
1b1a35ee | 292 | } |
5869c6ff XL |
293 | #[cfg(not(target_endian = "big"))] |
294 | { | |
295 | x.swap_bytes() | |
1b1a35ee XL |
296 | } |
297 | } | |
298 | ||
5869c6ff XL |
299 | /// Converts an integer from little endian to the target's endianness. |
300 | /// | |
301 | /// On little endian this is a no-op. On big endian the bytes are | |
302 | /// swapped. | |
303 | /// | |
304 | /// # Examples | |
305 | /// | |
306 | /// Basic usage: | |
307 | /// | |
308 | /// ``` | |
309 | #[doc = concat!("let n = 0x1A", stringify!($SelfT), ";")] | |
310 | /// | |
311 | /// if cfg!(target_endian = "little") { | |
312 | #[doc = concat!(" assert_eq!(", stringify!($SelfT), "::from_le(n), n)")] | |
313 | /// } else { | |
314 | #[doc = concat!(" assert_eq!(", stringify!($SelfT), "::from_le(n), n.swap_bytes())")] | |
315 | /// } | |
316 | /// ``` | |
317 | #[stable(feature = "rust1", since = "1.0.0")] | |
318 | #[rustc_const_stable(feature = "const_math", since = "1.32.0")] | |
cdc7bbd5 | 319 | #[inline(always)] |
5869c6ff XL |
320 | pub const fn from_le(x: Self) -> Self { |
321 | #[cfg(target_endian = "little")] | |
322 | { | |
323 | x | |
1b1a35ee | 324 | } |
5869c6ff XL |
325 | #[cfg(not(target_endian = "little"))] |
326 | { | |
327 | x.swap_bytes() | |
1b1a35ee XL |
328 | } |
329 | } | |
330 | ||
5869c6ff XL |
331 | /// Converts `self` to big endian from the target's endianness. |
332 | /// | |
333 | /// On big endian this is a no-op. On little endian the bytes are | |
334 | /// swapped. | |
335 | /// | |
336 | /// # Examples | |
337 | /// | |
338 | /// Basic usage: | |
339 | /// | |
340 | /// ``` | |
341 | #[doc = concat!("let n = 0x1A", stringify!($SelfT), ";")] | |
342 | /// | |
343 | /// if cfg!(target_endian = "big") { | |
344 | /// assert_eq!(n.to_be(), n) | |
345 | /// } else { | |
346 | /// assert_eq!(n.to_be(), n.swap_bytes()) | |
347 | /// } | |
348 | /// ``` | |
349 | #[stable(feature = "rust1", since = "1.0.0")] | |
350 | #[rustc_const_stable(feature = "const_math", since = "1.32.0")] | |
cdc7bbd5 | 351 | #[inline(always)] |
5869c6ff XL |
352 | pub const fn to_be(self) -> Self { // or not to be? |
353 | #[cfg(target_endian = "big")] | |
354 | { | |
355 | self | |
1b1a35ee | 356 | } |
5869c6ff XL |
357 | #[cfg(not(target_endian = "big"))] |
358 | { | |
359 | self.swap_bytes() | |
1b1a35ee XL |
360 | } |
361 | } | |
362 | ||
5869c6ff XL |
363 | /// Converts `self` to little endian from the target's endianness. |
364 | /// | |
365 | /// On little endian this is a no-op. On big endian the bytes are | |
366 | /// swapped. | |
367 | /// | |
368 | /// # Examples | |
369 | /// | |
370 | /// Basic usage: | |
371 | /// | |
372 | /// ``` | |
373 | #[doc = concat!("let n = 0x1A", stringify!($SelfT), ";")] | |
374 | /// | |
375 | /// if cfg!(target_endian = "little") { | |
376 | /// assert_eq!(n.to_le(), n) | |
377 | /// } else { | |
378 | /// assert_eq!(n.to_le(), n.swap_bytes()) | |
379 | /// } | |
380 | /// ``` | |
381 | #[stable(feature = "rust1", since = "1.0.0")] | |
382 | #[rustc_const_stable(feature = "const_math", since = "1.32.0")] | |
cdc7bbd5 | 383 | #[inline(always)] |
5869c6ff XL |
384 | pub const fn to_le(self) -> Self { |
385 | #[cfg(target_endian = "little")] | |
386 | { | |
387 | self | |
1b1a35ee | 388 | } |
5869c6ff XL |
389 | #[cfg(not(target_endian = "little"))] |
390 | { | |
391 | self.swap_bytes() | |
1b1a35ee XL |
392 | } |
393 | } | |
394 | ||
5869c6ff XL |
395 | /// Checked integer addition. Computes `self + rhs`, returning `None` |
396 | /// if overflow occurred. | |
397 | /// | |
398 | /// # Examples | |
399 | /// | |
400 | /// Basic usage: | |
401 | /// | |
402 | /// ``` | |
403 | #[doc = concat!( | |
404 | "assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(1), ", | |
405 | "Some(", stringify!($SelfT), "::MAX - 1));" | |
406 | )] | |
407 | #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(3), None);")] | |
408 | /// ``` | |
409 | #[stable(feature = "rust1", since = "1.0.0")] | |
410 | #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] | |
411 | #[must_use = "this returns the result of the operation, \ | |
412 | without modifying the original"] | |
413 | #[inline] | |
414 | pub const fn checked_add(self, rhs: Self) -> Option<Self> { | |
415 | let (a, b) = self.overflowing_add(rhs); | |
416 | if unlikely!(b) {None} else {Some(a)} | |
417 | } | |
418 | ||
419 | /// Unchecked integer addition. Computes `self + rhs`, assuming overflow | |
420 | /// cannot occur. This results in undefined behavior when | |
421 | #[doc = concat!("`self + rhs > ", stringify!($SelfT), "::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`.")] | |
422 | #[unstable( | |
423 | feature = "unchecked_math", | |
424 | reason = "niche optimization path", | |
425 | issue = "none", | |
426 | )] | |
427 | #[must_use = "this returns the result of the operation, \ | |
428 | without modifying the original"] | |
cdc7bbd5 | 429 | #[inline(always)] |
5869c6ff XL |
430 | pub unsafe fn unchecked_add(self, rhs: Self) -> Self { |
431 | // SAFETY: the caller must uphold the safety contract for | |
432 | // `unchecked_add`. | |
433 | unsafe { intrinsics::unchecked_add(self, rhs) } | |
1b1a35ee XL |
434 | } |
435 | ||
5869c6ff XL |
436 | /// Checked integer subtraction. Computes `self - rhs`, returning |
437 | /// `None` if overflow occurred. | |
438 | /// | |
439 | /// # Examples | |
440 | /// | |
441 | /// Basic usage: | |
442 | /// | |
443 | /// ``` | |
444 | #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_sub(1), Some(0));")] | |
445 | #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".checked_sub(1), None);")] | |
446 | /// ``` | |
447 | #[stable(feature = "rust1", since = "1.0.0")] | |
448 | #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] | |
449 | #[must_use = "this returns the result of the operation, \ | |
450 | without modifying the original"] | |
451 | #[inline] | |
452 | pub const fn checked_sub(self, rhs: Self) -> Option<Self> { | |
453 | let (a, b) = self.overflowing_sub(rhs); | |
454 | if unlikely!(b) {None} else {Some(a)} | |
455 | } | |
456 | ||
457 | /// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow | |
458 | /// cannot occur. This results in undefined behavior when | |
459 | #[doc = concat!("`self - rhs > ", stringify!($SelfT), "::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`.")] | |
460 | #[unstable( | |
461 | feature = "unchecked_math", | |
462 | reason = "niche optimization path", | |
463 | issue = "none", | |
464 | )] | |
465 | #[must_use = "this returns the result of the operation, \ | |
466 | without modifying the original"] | |
cdc7bbd5 | 467 | #[inline(always)] |
5869c6ff XL |
468 | pub unsafe fn unchecked_sub(self, rhs: Self) -> Self { |
469 | // SAFETY: the caller must uphold the safety contract for | |
470 | // `unchecked_sub`. | |
471 | unsafe { intrinsics::unchecked_sub(self, rhs) } | |
1b1a35ee XL |
472 | } |
473 | ||
5869c6ff XL |
474 | /// Checked integer multiplication. Computes `self * rhs`, returning |
475 | /// `None` if overflow occurred. | |
476 | /// | |
477 | /// # Examples | |
478 | /// | |
479 | /// Basic usage: | |
480 | /// | |
481 | /// ``` | |
482 | #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_mul(1), Some(5));")] | |
483 | #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.checked_mul(2), None);")] | |
484 | /// ``` | |
485 | #[stable(feature = "rust1", since = "1.0.0")] | |
486 | #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] | |
487 | #[must_use = "this returns the result of the operation, \ | |
488 | without modifying the original"] | |
489 | #[inline] | |
490 | pub const fn checked_mul(self, rhs: Self) -> Option<Self> { | |
491 | let (a, b) = self.overflowing_mul(rhs); | |
492 | if unlikely!(b) {None} else {Some(a)} | |
493 | } | |
494 | ||
495 | /// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow | |
496 | /// cannot occur. This results in undefined behavior when | |
497 | #[doc = concat!("`self * rhs > ", stringify!($SelfT), "::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`.")] | |
498 | #[unstable( | |
499 | feature = "unchecked_math", | |
500 | reason = "niche optimization path", | |
501 | issue = "none", | |
502 | )] | |
503 | #[must_use = "this returns the result of the operation, \ | |
504 | without modifying the original"] | |
cdc7bbd5 | 505 | #[inline(always)] |
5869c6ff XL |
506 | pub unsafe fn unchecked_mul(self, rhs: Self) -> Self { |
507 | // SAFETY: the caller must uphold the safety contract for | |
508 | // `unchecked_mul`. | |
509 | unsafe { intrinsics::unchecked_mul(self, rhs) } | |
1b1a35ee XL |
510 | } |
511 | ||
5869c6ff XL |
512 | /// Checked integer division. Computes `self / rhs`, returning `None` |
513 | /// if `rhs == 0`. | |
514 | /// | |
515 | /// # Examples | |
516 | /// | |
517 | /// Basic usage: | |
518 | /// | |
519 | /// ``` | |
520 | #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".checked_div(2), Some(64));")] | |
521 | #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);")] | |
522 | /// ``` | |
523 | #[stable(feature = "rust1", since = "1.0.0")] | |
6a06907d | 524 | #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")] |
5869c6ff XL |
525 | #[must_use = "this returns the result of the operation, \ |
526 | without modifying the original"] | |
527 | #[inline] | |
528 | pub const fn checked_div(self, rhs: Self) -> Option<Self> { | |
529 | if unlikely!(rhs == 0) { | |
530 | None | |
531 | } else { | |
532 | // SAFETY: div by zero has been checked above and unsigned types have no other | |
533 | // failure modes for division | |
534 | Some(unsafe { intrinsics::unchecked_div(self, rhs) }) | |
1b1a35ee XL |
535 | } |
536 | } | |
537 | ||
5869c6ff XL |
538 | /// Checked Euclidean division. Computes `self.div_euclid(rhs)`, returning `None` |
539 | /// if `rhs == 0`. | |
540 | /// | |
541 | /// # Examples | |
542 | /// | |
543 | /// Basic usage: | |
544 | /// | |
545 | /// ``` | |
546 | #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".checked_div_euclid(2), Some(64));")] | |
547 | #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_div_euclid(0), None);")] | |
548 | /// ``` | |
549 | #[stable(feature = "euclidean_division", since = "1.38.0")] | |
6a06907d | 550 | #[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")] |
5869c6ff XL |
551 | #[must_use = "this returns the result of the operation, \ |
552 | without modifying the original"] | |
553 | #[inline] | |
554 | pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> { | |
555 | if unlikely!(rhs == 0) { | |
556 | None | |
557 | } else { | |
558 | Some(self.div_euclid(rhs)) | |
1b1a35ee XL |
559 | } |
560 | } | |
561 | ||
562 | ||
5869c6ff XL |
563 | /// Checked integer remainder. Computes `self % rhs`, returning `None` |
564 | /// if `rhs == 0`. | |
565 | /// | |
566 | /// # Examples | |
567 | /// | |
568 | /// Basic usage: | |
569 | /// | |
570 | /// ``` | |
571 | #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem(2), Some(1));")] | |
572 | #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);")] | |
573 | /// ``` | |
574 | #[stable(feature = "wrapping", since = "1.7.0")] | |
6a06907d | 575 | #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.52.0")] |
5869c6ff XL |
576 | #[must_use = "this returns the result of the operation, \ |
577 | without modifying the original"] | |
578 | #[inline] | |
579 | pub const fn checked_rem(self, rhs: Self) -> Option<Self> { | |
580 | if unlikely!(rhs == 0) { | |
581 | None | |
582 | } else { | |
583 | // SAFETY: div by zero has been checked above and unsigned types have no other | |
584 | // failure modes for division | |
585 | Some(unsafe { intrinsics::unchecked_rem(self, rhs) }) | |
1b1a35ee XL |
586 | } |
587 | } | |
588 | ||
5869c6ff XL |
589 | /// Checked Euclidean modulo. Computes `self.rem_euclid(rhs)`, returning `None` |
590 | /// if `rhs == 0`. | |
591 | /// | |
592 | /// # Examples | |
593 | /// | |
594 | /// Basic usage: | |
595 | /// | |
596 | /// ``` | |
597 | #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1));")] | |
598 | #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);")] | |
599 | /// ``` | |
600 | #[stable(feature = "euclidean_division", since = "1.38.0")] | |
6a06907d | 601 | #[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")] |
5869c6ff XL |
602 | #[must_use = "this returns the result of the operation, \ |
603 | without modifying the original"] | |
604 | #[inline] | |
605 | pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> { | |
606 | if unlikely!(rhs == 0) { | |
607 | None | |
608 | } else { | |
609 | Some(self.rem_euclid(rhs)) | |
1b1a35ee XL |
610 | } |
611 | } | |
612 | ||
5869c6ff XL |
613 | /// Checked negation. Computes `-self`, returning `None` unless `self == |
614 | /// 0`. | |
615 | /// | |
616 | /// Note that negating any positive integer will overflow. | |
617 | /// | |
618 | /// # Examples | |
619 | /// | |
620 | /// Basic usage: | |
621 | /// | |
622 | /// ``` | |
623 | #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".checked_neg(), Some(0));")] | |
624 | #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_neg(), None);")] | |
625 | /// ``` | |
626 | #[stable(feature = "wrapping", since = "1.7.0")] | |
627 | #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] | |
628 | #[inline] | |
629 | pub const fn checked_neg(self) -> Option<Self> { | |
630 | let (a, b) = self.overflowing_neg(); | |
631 | if unlikely!(b) {None} else {Some(a)} | |
1b1a35ee XL |
632 | } |
633 | ||
5869c6ff XL |
634 | /// Checked shift left. Computes `self << rhs`, returning `None` |
635 | /// if `rhs` is larger than or equal to the number of bits in `self`. | |
636 | /// | |
637 | /// # Examples | |
638 | /// | |
639 | /// Basic usage: | |
640 | /// | |
641 | /// ``` | |
642 | #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".checked_shl(4), Some(0x10));")] | |
643 | #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".checked_shl(129), None);")] | |
644 | /// ``` | |
645 | #[stable(feature = "wrapping", since = "1.7.0")] | |
646 | #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] | |
647 | #[must_use = "this returns the result of the operation, \ | |
648 | without modifying the original"] | |
649 | #[inline] | |
650 | pub const fn checked_shl(self, rhs: u32) -> Option<Self> { | |
651 | let (a, b) = self.overflowing_shl(rhs); | |
652 | if unlikely!(b) {None} else {Some(a)} | |
1b1a35ee XL |
653 | } |
654 | ||
5869c6ff XL |
655 | /// Checked shift right. Computes `self >> rhs`, returning `None` |
656 | /// if `rhs` is larger than or equal to the number of bits in `self`. | |
657 | /// | |
658 | /// # Examples | |
659 | /// | |
660 | /// Basic usage: | |
661 | /// | |
662 | /// ``` | |
663 | #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".checked_shr(4), Some(0x1));")] | |
664 | #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".checked_shr(129), None);")] | |
665 | /// ``` | |
666 | #[stable(feature = "wrapping", since = "1.7.0")] | |
667 | #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] | |
668 | #[must_use = "this returns the result of the operation, \ | |
669 | without modifying the original"] | |
670 | #[inline] | |
671 | pub const fn checked_shr(self, rhs: u32) -> Option<Self> { | |
672 | let (a, b) = self.overflowing_shr(rhs); | |
673 | if unlikely!(b) {None} else {Some(a)} | |
1b1a35ee XL |
674 | } |
675 | ||
5869c6ff XL |
676 | /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if |
677 | /// overflow occurred. | |
678 | /// | |
679 | /// # Examples | |
680 | /// | |
681 | /// Basic usage: | |
682 | /// | |
683 | /// ``` | |
684 | #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".checked_pow(5), Some(32));")] | |
685 | #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.checked_pow(2), None);")] | |
686 | /// ``` | |
687 | #[stable(feature = "no_panic_pow", since = "1.34.0")] | |
688 | #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] | |
689 | #[must_use = "this returns the result of the operation, \ | |
690 | without modifying the original"] | |
691 | #[inline] | |
692 | pub const fn checked_pow(self, mut exp: u32) -> Option<Self> { | |
693 | if exp == 0 { | |
694 | return Some(1); | |
695 | } | |
696 | let mut base = self; | |
697 | let mut acc: Self = 1; | |
1b1a35ee | 698 | |
5869c6ff XL |
699 | while exp > 1 { |
700 | if (exp & 1) == 1 { | |
701 | acc = try_opt!(acc.checked_mul(base)); | |
1b1a35ee | 702 | } |
5869c6ff XL |
703 | exp /= 2; |
704 | base = try_opt!(base.checked_mul(base)); | |
1b1a35ee | 705 | } |
1b1a35ee | 706 | |
5869c6ff XL |
707 | // since exp!=0, finally the exp must be 1. |
708 | // Deal with the final bit of the exponent separately, since | |
709 | // squaring the base afterwards is not necessary and may cause a | |
710 | // needless overflow. | |
1b1a35ee | 711 | |
5869c6ff | 712 | Some(try_opt!(acc.checked_mul(base))) |
1b1a35ee XL |
713 | } |
714 | ||
5869c6ff XL |
715 | /// Saturating integer addition. Computes `self + rhs`, saturating at |
716 | /// the numeric bounds instead of overflowing. | |
717 | /// | |
718 | /// # Examples | |
719 | /// | |
720 | /// Basic usage: | |
721 | /// | |
722 | /// ``` | |
723 | #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);")] | |
724 | #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.saturating_add(127), ", stringify!($SelfT), "::MAX);")] | |
725 | /// ``` | |
726 | #[stable(feature = "rust1", since = "1.0.0")] | |
727 | #[must_use = "this returns the result of the operation, \ | |
728 | without modifying the original"] | |
729 | #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")] | |
cdc7bbd5 | 730 | #[inline(always)] |
5869c6ff XL |
731 | pub const fn saturating_add(self, rhs: Self) -> Self { |
732 | intrinsics::saturating_add(self, rhs) | |
1b1a35ee XL |
733 | } |
734 | ||
5869c6ff XL |
735 | /// Saturating integer subtraction. Computes `self - rhs`, saturating |
736 | /// at the numeric bounds instead of overflowing. | |
737 | /// | |
738 | /// # Examples | |
739 | /// | |
740 | /// Basic usage: | |
741 | /// | |
742 | /// ``` | |
743 | #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".saturating_sub(27), 73);")] | |
744 | #[doc = concat!("assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);")] | |
745 | /// ``` | |
746 | #[stable(feature = "rust1", since = "1.0.0")] | |
747 | #[must_use = "this returns the result of the operation, \ | |
748 | without modifying the original"] | |
749 | #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")] | |
cdc7bbd5 | 750 | #[inline(always)] |
5869c6ff XL |
751 | pub const fn saturating_sub(self, rhs: Self) -> Self { |
752 | intrinsics::saturating_sub(self, rhs) | |
1b1a35ee XL |
753 | } |
754 | ||
5869c6ff XL |
755 | /// Saturating integer multiplication. Computes `self * rhs`, |
756 | /// saturating at the numeric bounds instead of overflowing. | |
757 | /// | |
758 | /// # Examples | |
759 | /// | |
760 | /// Basic usage: | |
761 | /// | |
762 | /// ``` | |
763 | #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".saturating_mul(10), 20);")] | |
764 | #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($SelfT),"::MAX);")] | |
765 | /// ``` | |
766 | #[stable(feature = "wrapping", since = "1.7.0")] | |
767 | #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")] | |
768 | #[must_use = "this returns the result of the operation, \ | |
769 | without modifying the original"] | |
770 | #[inline] | |
771 | pub const fn saturating_mul(self, rhs: Self) -> Self { | |
772 | match self.checked_mul(rhs) { | |
773 | Some(x) => x, | |
774 | None => Self::MAX, | |
1b1a35ee XL |
775 | } |
776 | } | |
777 | ||
5869c6ff XL |
778 | /// Saturating integer exponentiation. Computes `self.pow(exp)`, |
779 | /// saturating at the numeric bounds instead of overflowing. | |
780 | /// | |
781 | /// # Examples | |
782 | /// | |
783 | /// Basic usage: | |
784 | /// | |
785 | /// ``` | |
786 | #[doc = concat!("assert_eq!(4", stringify!($SelfT), ".saturating_pow(3), 64);")] | |
787 | #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.saturating_pow(2), ", stringify!($SelfT), "::MAX);")] | |
788 | /// ``` | |
789 | #[stable(feature = "no_panic_pow", since = "1.34.0")] | |
790 | #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] | |
791 | #[must_use = "this returns the result of the operation, \ | |
792 | without modifying the original"] | |
793 | #[inline] | |
794 | pub const fn saturating_pow(self, exp: u32) -> Self { | |
795 | match self.checked_pow(exp) { | |
796 | Some(x) => x, | |
797 | None => Self::MAX, | |
1b1a35ee XL |
798 | } |
799 | } | |
800 | ||
5869c6ff XL |
801 | /// Wrapping (modular) addition. Computes `self + rhs`, |
802 | /// wrapping around at the boundary of the type. | |
803 | /// | |
804 | /// # Examples | |
805 | /// | |
806 | /// Basic usage: | |
807 | /// | |
808 | /// ``` | |
809 | #[doc = concat!("assert_eq!(200", stringify!($SelfT), ".wrapping_add(55), 255);")] | |
810 | #[doc = concat!("assert_eq!(200", stringify!($SelfT), ".wrapping_add(", stringify!($SelfT), "::MAX), 199);")] | |
811 | /// ``` | |
812 | #[stable(feature = "rust1", since = "1.0.0")] | |
813 | #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] | |
814 | #[must_use = "this returns the result of the operation, \ | |
815 | without modifying the original"] | |
cdc7bbd5 | 816 | #[inline(always)] |
5869c6ff XL |
817 | pub const fn wrapping_add(self, rhs: Self) -> Self { |
818 | intrinsics::wrapping_add(self, rhs) | |
819 | } | |
1b1a35ee | 820 | |
5869c6ff XL |
821 | /// Wrapping (modular) subtraction. Computes `self - rhs`, |
822 | /// wrapping around at the boundary of the type. | |
823 | /// | |
824 | /// # Examples | |
825 | /// | |
826 | /// Basic usage: | |
827 | /// | |
828 | /// ``` | |
829 | #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_sub(100), 0);")] | |
830 | #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_sub(", stringify!($SelfT), "::MAX), 101);")] | |
831 | /// ``` | |
832 | #[stable(feature = "rust1", since = "1.0.0")] | |
833 | #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] | |
834 | #[must_use = "this returns the result of the operation, \ | |
835 | without modifying the original"] | |
cdc7bbd5 | 836 | #[inline(always)] |
5869c6ff XL |
837 | pub const fn wrapping_sub(self, rhs: Self) -> Self { |
838 | intrinsics::wrapping_sub(self, rhs) | |
1b1a35ee XL |
839 | } |
840 | ||
841 | /// Wrapping (modular) multiplication. Computes `self * | |
842 | /// rhs`, wrapping around at the boundary of the type. | |
843 | /// | |
844 | /// # Examples | |
845 | /// | |
846 | /// Basic usage: | |
847 | /// | |
848 | /// Please note that this example is shared between integer types. | |
849 | /// Which explains why `u8` is used here. | |
850 | /// | |
851 | /// ``` | |
5869c6ff XL |
852 | /// assert_eq!(10u8.wrapping_mul(12), 120); |
853 | /// assert_eq!(25u8.wrapping_mul(12), 44); | |
854 | /// ``` | |
855 | #[stable(feature = "rust1", since = "1.0.0")] | |
856 | #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] | |
857 | #[must_use = "this returns the result of the operation, \ | |
858 | without modifying the original"] | |
cdc7bbd5 | 859 | #[inline(always)] |
5869c6ff XL |
860 | pub const fn wrapping_mul(self, rhs: Self) -> Self { |
861 | intrinsics::wrapping_mul(self, rhs) | |
862 | } | |
863 | ||
864 | /// Wrapping (modular) division. Computes `self / rhs`. | |
865 | /// Wrapped division on unsigned types is just normal division. | |
866 | /// There's no way wrapping could ever happen. | |
867 | /// This function exists, so that all operations | |
868 | /// are accounted for in the wrapping operations. | |
869 | /// | |
870 | /// # Examples | |
871 | /// | |
872 | /// Basic usage: | |
873 | /// | |
874 | /// ``` | |
875 | #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);")] | |
876 | /// ``` | |
877 | #[stable(feature = "num_wrapping", since = "1.2.0")] | |
6a06907d | 878 | #[rustc_const_stable(feature = "const_wrapping_int_methods", since = "1.52.0")] |
5869c6ff XL |
879 | #[must_use = "this returns the result of the operation, \ |
880 | without modifying the original"] | |
cdc7bbd5 | 881 | #[inline(always)] |
5869c6ff XL |
882 | pub const fn wrapping_div(self, rhs: Self) -> Self { |
883 | self / rhs | |
884 | } | |
885 | ||
886 | /// Wrapping Euclidean division. Computes `self.div_euclid(rhs)`. | |
887 | /// Wrapped division on unsigned types is just normal division. | |
888 | /// There's no way wrapping could ever happen. | |
889 | /// This function exists, so that all operations | |
890 | /// are accounted for in the wrapping operations. | |
891 | /// Since, for the positive integers, all common | |
892 | /// definitions of division are equal, this | |
893 | /// is exactly equal to `self.wrapping_div(rhs)`. | |
894 | /// | |
895 | /// # Examples | |
896 | /// | |
897 | /// Basic usage: | |
898 | /// | |
899 | /// ``` | |
900 | #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);")] | |
901 | /// ``` | |
902 | #[stable(feature = "euclidean_division", since = "1.38.0")] | |
6a06907d | 903 | #[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")] |
5869c6ff XL |
904 | #[must_use = "this returns the result of the operation, \ |
905 | without modifying the original"] | |
cdc7bbd5 | 906 | #[inline(always)] |
5869c6ff XL |
907 | pub const fn wrapping_div_euclid(self, rhs: Self) -> Self { |
908 | self / rhs | |
909 | } | |
910 | ||
911 | /// Wrapping (modular) remainder. Computes `self % rhs`. | |
912 | /// Wrapped remainder calculation on unsigned types is | |
913 | /// just the regular remainder calculation. | |
914 | /// There's no way wrapping could ever happen. | |
915 | /// This function exists, so that all operations | |
916 | /// are accounted for in the wrapping operations. | |
917 | /// | |
918 | /// # Examples | |
919 | /// | |
920 | /// Basic usage: | |
921 | /// | |
922 | /// ``` | |
923 | #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);")] | |
924 | /// ``` | |
925 | #[stable(feature = "num_wrapping", since = "1.2.0")] | |
6a06907d | 926 | #[rustc_const_stable(feature = "const_wrapping_int_methods", since = "1.52.0")] |
5869c6ff XL |
927 | #[must_use = "this returns the result of the operation, \ |
928 | without modifying the original"] | |
cdc7bbd5 | 929 | #[inline(always)] |
5869c6ff XL |
930 | pub const fn wrapping_rem(self, rhs: Self) -> Self { |
931 | self % rhs | |
932 | } | |
933 | ||
934 | /// Wrapping Euclidean modulo. Computes `self.rem_euclid(rhs)`. | |
935 | /// Wrapped modulo calculation on unsigned types is | |
936 | /// just the regular remainder calculation. | |
937 | /// There's no way wrapping could ever happen. | |
938 | /// This function exists, so that all operations | |
939 | /// are accounted for in the wrapping operations. | |
940 | /// Since, for the positive integers, all common | |
941 | /// definitions of division are equal, this | |
942 | /// is exactly equal to `self.wrapping_rem(rhs)`. | |
943 | /// | |
944 | /// # Examples | |
945 | /// | |
946 | /// Basic usage: | |
947 | /// | |
948 | /// ``` | |
949 | #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);")] | |
1b1a35ee | 950 | /// ``` |
5869c6ff | 951 | #[stable(feature = "euclidean_division", since = "1.38.0")] |
6a06907d | 952 | #[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")] |
1b1a35ee | 953 | #[must_use = "this returns the result of the operation, \ |
5869c6ff | 954 | without modifying the original"] |
cdc7bbd5 | 955 | #[inline(always)] |
5869c6ff XL |
956 | pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self { |
957 | self % rhs | |
1b1a35ee XL |
958 | } |
959 | ||
960 | /// Wrapping (modular) negation. Computes `-self`, | |
961 | /// wrapping around at the boundary of the type. | |
962 | /// | |
963 | /// Since unsigned types do not have negative equivalents | |
964 | /// all applications of this function will wrap (except for `-0`). | |
965 | /// For values smaller than the corresponding signed type's maximum | |
966 | /// the result is the same as casting the corresponding signed value. | |
967 | /// Any larger values are equivalent to `MAX + 1 - (val - MAX - 1)` where | |
968 | /// `MAX` is the corresponding signed type's maximum. | |
969 | /// | |
970 | /// # Examples | |
971 | /// | |
972 | /// Basic usage: | |
973 | /// | |
974 | /// Please note that this example is shared between integer types. | |
975 | /// Which explains why `i8` is used here. | |
976 | /// | |
977 | /// ``` | |
978 | /// assert_eq!(100i8.wrapping_neg(), -100); | |
979 | /// assert_eq!((-128i8).wrapping_neg(), -128); | |
980 | /// ``` | |
981 | #[stable(feature = "num_wrapping", since = "1.2.0")] | |
982 | #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] | |
983 | #[inline] | |
984 | pub const fn wrapping_neg(self) -> Self { | |
985 | self.overflowing_neg().0 | |
986 | } | |
987 | ||
5869c6ff XL |
988 | /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, |
989 | /// where `mask` removes any high-order bits of `rhs` that | |
990 | /// would cause the shift to exceed the bitwidth of the type. | |
991 | /// | |
992 | /// Note that this is *not* the same as a rotate-left; the | |
993 | /// RHS of a wrapping shift-left is restricted to the range | |
994 | /// of the type, rather than the bits shifted out of the LHS | |
995 | /// being returned to the other end. The primitive integer | |
6a06907d | 996 | /// types all implement a [`rotate_left`](Self::rotate_left) function, |
5869c6ff XL |
997 | /// which may be what you want instead. |
998 | /// | |
999 | /// # Examples | |
1000 | /// | |
1001 | /// Basic usage: | |
1002 | /// | |
1003 | /// ``` | |
1004 | #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_shl(7), 128);")] | |
1005 | #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);")] | |
1006 | /// ``` | |
1007 | #[stable(feature = "num_wrapping", since = "1.2.0")] | |
1008 | #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] | |
1009 | #[must_use = "this returns the result of the operation, \ | |
1010 | without modifying the original"] | |
cdc7bbd5 | 1011 | #[inline(always)] |
5869c6ff XL |
1012 | pub const fn wrapping_shl(self, rhs: u32) -> Self { |
1013 | // SAFETY: the masking by the bitsize of the type ensures that we do not shift | |
1014 | // out of bounds | |
1015 | unsafe { | |
1016 | intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT) | |
1b1a35ee XL |
1017 | } |
1018 | } | |
1019 | ||
5869c6ff XL |
1020 | /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, |
1021 | /// where `mask` removes any high-order bits of `rhs` that | |
1022 | /// would cause the shift to exceed the bitwidth of the type. | |
1023 | /// | |
1024 | /// Note that this is *not* the same as a rotate-right; the | |
1025 | /// RHS of a wrapping shift-right is restricted to the range | |
1026 | /// of the type, rather than the bits shifted out of the LHS | |
1027 | /// being returned to the other end. The primitive integer | |
6a06907d | 1028 | /// types all implement a [`rotate_right`](Self::rotate_right) function, |
5869c6ff XL |
1029 | /// which may be what you want instead. |
1030 | /// | |
1031 | /// # Examples | |
1032 | /// | |
1033 | /// Basic usage: | |
1034 | /// | |
1035 | /// ``` | |
1036 | #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".wrapping_shr(7), 1);")] | |
1037 | #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);")] | |
1038 | /// ``` | |
1039 | #[stable(feature = "num_wrapping", since = "1.2.0")] | |
1040 | #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] | |
1041 | #[must_use = "this returns the result of the operation, \ | |
1042 | without modifying the original"] | |
cdc7bbd5 | 1043 | #[inline(always)] |
5869c6ff XL |
1044 | pub const fn wrapping_shr(self, rhs: u32) -> Self { |
1045 | // SAFETY: the masking by the bitsize of the type ensures that we do not shift | |
1046 | // out of bounds | |
1047 | unsafe { | |
1048 | intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT) | |
1b1a35ee XL |
1049 | } |
1050 | } | |
1051 | ||
5869c6ff XL |
1052 | /// Wrapping (modular) exponentiation. Computes `self.pow(exp)`, |
1053 | /// wrapping around at the boundary of the type. | |
1054 | /// | |
1055 | /// # Examples | |
1056 | /// | |
1057 | /// Basic usage: | |
1058 | /// | |
1059 | /// ``` | |
1060 | #[doc = concat!("assert_eq!(3", stringify!($SelfT), ".wrapping_pow(5), 243);")] | |
1061 | /// assert_eq!(3u8.wrapping_pow(6), 217); | |
1062 | /// ``` | |
1063 | #[stable(feature = "no_panic_pow", since = "1.34.0")] | |
1064 | #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] | |
1065 | #[must_use = "this returns the result of the operation, \ | |
1066 | without modifying the original"] | |
1067 | #[inline] | |
1068 | pub const fn wrapping_pow(self, mut exp: u32) -> Self { | |
1069 | if exp == 0 { | |
1070 | return 1; | |
1071 | } | |
1072 | let mut base = self; | |
1073 | let mut acc: Self = 1; | |
1b1a35ee | 1074 | |
5869c6ff XL |
1075 | while exp > 1 { |
1076 | if (exp & 1) == 1 { | |
1077 | acc = acc.wrapping_mul(base); | |
1b1a35ee | 1078 | } |
5869c6ff XL |
1079 | exp /= 2; |
1080 | base = base.wrapping_mul(base); | |
1b1a35ee | 1081 | } |
1b1a35ee | 1082 | |
5869c6ff XL |
1083 | // since exp!=0, finally the exp must be 1. |
1084 | // Deal with the final bit of the exponent separately, since | |
1085 | // squaring the base afterwards is not necessary and may cause a | |
1086 | // needless overflow. | |
1087 | acc.wrapping_mul(base) | |
1b1a35ee XL |
1088 | } |
1089 | ||
5869c6ff XL |
1090 | /// Calculates `self` + `rhs` |
1091 | /// | |
1092 | /// Returns a tuple of the addition along with a boolean indicating | |
1093 | /// whether an arithmetic overflow would occur. If an overflow would | |
1094 | /// have occurred then the wrapped value is returned. | |
1095 | /// | |
1096 | /// # Examples | |
1097 | /// | |
1098 | /// Basic usage | |
1099 | /// | |
1100 | /// ``` | |
1101 | /// | |
1102 | #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));")] | |
1103 | #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (0, true));")] | |
1104 | /// ``` | |
1105 | #[stable(feature = "wrapping", since = "1.7.0")] | |
1106 | #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] | |
1107 | #[must_use = "this returns the result of the operation, \ | |
1108 | without modifying the original"] | |
cdc7bbd5 | 1109 | #[inline(always)] |
5869c6ff XL |
1110 | pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) { |
1111 | let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT); | |
1112 | (a as Self, b) | |
1113 | } | |
1b1a35ee | 1114 | |
5869c6ff XL |
1115 | /// Calculates `self` - `rhs` |
1116 | /// | |
1117 | /// Returns a tuple of the subtraction along with a boolean indicating | |
1118 | /// whether an arithmetic overflow would occur. If an overflow would | |
1119 | /// have occurred then the wrapped value is returned. | |
1120 | /// | |
1121 | /// # Examples | |
1122 | /// | |
1123 | /// Basic usage | |
1124 | /// | |
1125 | /// ``` | |
1126 | /// | |
1127 | #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false));")] | |
1128 | #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".overflowing_sub(1), (", stringify!($SelfT), "::MAX, true));")] | |
1129 | /// ``` | |
1130 | #[stable(feature = "wrapping", since = "1.7.0")] | |
1131 | #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] | |
1132 | #[must_use = "this returns the result of the operation, \ | |
1133 | without modifying the original"] | |
cdc7bbd5 | 1134 | #[inline(always)] |
5869c6ff XL |
1135 | pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) { |
1136 | let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT); | |
1137 | (a as Self, b) | |
1b1a35ee XL |
1138 | } |
1139 | ||
1140 | /// Calculates the multiplication of `self` and `rhs`. | |
1141 | /// | |
1142 | /// Returns a tuple of the multiplication along with a boolean | |
1143 | /// indicating whether an arithmetic overflow would occur. If an | |
1144 | /// overflow would have occurred then the wrapped value is returned. | |
1145 | /// | |
1146 | /// # Examples | |
1147 | /// | |
1148 | /// Basic usage: | |
1149 | /// | |
1150 | /// Please note that this example is shared between integer types. | |
1151 | /// Which explains why `u32` is used here. | |
1152 | /// | |
1153 | /// ``` | |
1154 | /// assert_eq!(5u32.overflowing_mul(2), (10, false)); | |
1155 | /// assert_eq!(1_000_000_000u32.overflowing_mul(10), (1410065408, true)); | |
1156 | /// ``` | |
1157 | #[stable(feature = "wrapping", since = "1.7.0")] | |
1158 | #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] | |
1159 | #[must_use = "this returns the result of the operation, \ | |
1160 | without modifying the original"] | |
cdc7bbd5 | 1161 | #[inline(always)] |
1b1a35ee XL |
1162 | pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) { |
1163 | let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT); | |
1164 | (a as Self, b) | |
1165 | } | |
1166 | ||
5869c6ff XL |
1167 | /// Calculates the divisor when `self` is divided by `rhs`. |
1168 | /// | |
1169 | /// Returns a tuple of the divisor along with a boolean indicating | |
1170 | /// whether an arithmetic overflow would occur. Note that for unsigned | |
1171 | /// integers overflow never occurs, so the second value is always | |
1172 | /// `false`. | |
1173 | /// | |
1174 | /// # Panics | |
1175 | /// | |
1176 | /// This function will panic if `rhs` is 0. | |
1177 | /// | |
1178 | /// # Examples | |
1179 | /// | |
1180 | /// Basic usage | |
1181 | /// | |
1182 | /// ``` | |
1183 | #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_div(2), (2, false));")] | |
1184 | /// ``` | |
cdc7bbd5 | 1185 | #[inline(always)] |
5869c6ff | 1186 | #[stable(feature = "wrapping", since = "1.7.0")] |
6a06907d | 1187 | #[rustc_const_stable(feature = "const_overflowing_int_methods", since = "1.52.0")] |
5869c6ff XL |
1188 | #[must_use = "this returns the result of the operation, \ |
1189 | without modifying the original"] | |
1190 | pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) { | |
1191 | (self / rhs, false) | |
1b1a35ee XL |
1192 | } |
1193 | ||
5869c6ff XL |
1194 | /// Calculates the quotient of Euclidean division `self.div_euclid(rhs)`. |
1195 | /// | |
1196 | /// Returns a tuple of the divisor along with a boolean indicating | |
1197 | /// whether an arithmetic overflow would occur. Note that for unsigned | |
1198 | /// integers overflow never occurs, so the second value is always | |
1199 | /// `false`. | |
1200 | /// Since, for the positive integers, all common | |
1201 | /// definitions of division are equal, this | |
1202 | /// is exactly equal to `self.overflowing_div(rhs)`. | |
1203 | /// | |
1204 | /// # Panics | |
1205 | /// | |
1206 | /// This function will panic if `rhs` is 0. | |
1207 | /// | |
1208 | /// # Examples | |
1209 | /// | |
1210 | /// Basic usage | |
1211 | /// | |
1212 | /// ``` | |
1213 | #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));")] | |
1214 | /// ``` | |
cdc7bbd5 | 1215 | #[inline(always)] |
5869c6ff | 1216 | #[stable(feature = "euclidean_division", since = "1.38.0")] |
6a06907d | 1217 | #[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")] |
5869c6ff XL |
1218 | #[must_use = "this returns the result of the operation, \ |
1219 | without modifying the original"] | |
1220 | pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { | |
1221 | (self / rhs, false) | |
1b1a35ee XL |
1222 | } |
1223 | ||
5869c6ff XL |
1224 | /// Calculates the remainder when `self` is divided by `rhs`. |
1225 | /// | |
1226 | /// Returns a tuple of the remainder after dividing along with a boolean | |
1227 | /// indicating whether an arithmetic overflow would occur. Note that for | |
1228 | /// unsigned integers overflow never occurs, so the second value is | |
1229 | /// always `false`. | |
1230 | /// | |
1231 | /// # Panics | |
1232 | /// | |
1233 | /// This function will panic if `rhs` is 0. | |
1234 | /// | |
1235 | /// # Examples | |
1236 | /// | |
1237 | /// Basic usage | |
1238 | /// | |
1239 | /// ``` | |
1240 | #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_rem(2), (1, false));")] | |
1241 | /// ``` | |
cdc7bbd5 | 1242 | #[inline(always)] |
5869c6ff | 1243 | #[stable(feature = "wrapping", since = "1.7.0")] |
6a06907d | 1244 | #[rustc_const_stable(feature = "const_overflowing_int_methods", since = "1.52.0")] |
5869c6ff XL |
1245 | #[must_use = "this returns the result of the operation, \ |
1246 | without modifying the original"] | |
1247 | pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) { | |
1248 | (self % rhs, false) | |
1b1a35ee XL |
1249 | } |
1250 | ||
5869c6ff XL |
1251 | /// Calculates the remainder `self.rem_euclid(rhs)` as if by Euclidean division. |
1252 | /// | |
1253 | /// Returns a tuple of the modulo after dividing along with a boolean | |
1254 | /// indicating whether an arithmetic overflow would occur. Note that for | |
1255 | /// unsigned integers overflow never occurs, so the second value is | |
1256 | /// always `false`. | |
1257 | /// Since, for the positive integers, all common | |
1258 | /// definitions of division are equal, this operation | |
1259 | /// is exactly equal to `self.overflowing_rem(rhs)`. | |
1260 | /// | |
1261 | /// # Panics | |
1262 | /// | |
1263 | /// This function will panic if `rhs` is 0. | |
1264 | /// | |
1265 | /// # Examples | |
1266 | /// | |
1267 | /// Basic usage | |
1268 | /// | |
1269 | /// ``` | |
1270 | #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));")] | |
1271 | /// ``` | |
cdc7bbd5 | 1272 | #[inline(always)] |
5869c6ff | 1273 | #[stable(feature = "euclidean_division", since = "1.38.0")] |
6a06907d | 1274 | #[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")] |
5869c6ff XL |
1275 | #[must_use = "this returns the result of the operation, \ |
1276 | without modifying the original"] | |
1277 | pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { | |
1278 | (self % rhs, false) | |
1b1a35ee XL |
1279 | } |
1280 | ||
5869c6ff XL |
1281 | /// Negates self in an overflowing fashion. |
1282 | /// | |
1283 | /// Returns `!self + 1` using wrapping operations to return the value | |
1284 | /// that represents the negation of this unsigned value. Note that for | |
1285 | /// positive unsigned values overflow always occurs, but negating 0 does | |
1286 | /// not overflow. | |
1287 | /// | |
1288 | /// # Examples | |
1289 | /// | |
1290 | /// Basic usage | |
1291 | /// | |
1292 | /// ``` | |
1293 | #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".overflowing_neg(), (0, false));")] | |
1294 | #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2i32 as ", stringify!($SelfT), ", true));")] | |
1295 | /// ``` | |
cdc7bbd5 | 1296 | #[inline(always)] |
5869c6ff XL |
1297 | #[stable(feature = "wrapping", since = "1.7.0")] |
1298 | #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] | |
1299 | pub const fn overflowing_neg(self) -> (Self, bool) { | |
1300 | ((!self).wrapping_add(1), self != 0) | |
1b1a35ee XL |
1301 | } |
1302 | ||
5869c6ff XL |
1303 | /// Shifts self left by `rhs` bits. |
1304 | /// | |
1305 | /// Returns a tuple of the shifted version of self along with a boolean | |
1306 | /// indicating whether the shift value was larger than or equal to the | |
1307 | /// number of bits. If the shift value is too large, then value is | |
1308 | /// masked (N-1) where N is the number of bits, and this value is then | |
1309 | /// used to perform the shift. | |
1310 | /// | |
1311 | /// # Examples | |
1312 | /// | |
1313 | /// Basic usage | |
1314 | /// | |
1315 | /// ``` | |
1316 | #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(4), (0x10, false));")] | |
1317 | #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(132), (0x10, true));")] | |
1318 | /// ``` | |
1319 | #[stable(feature = "wrapping", since = "1.7.0")] | |
1320 | #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] | |
1321 | #[must_use = "this returns the result of the operation, \ | |
1322 | without modifying the original"] | |
cdc7bbd5 | 1323 | #[inline(always)] |
5869c6ff XL |
1324 | pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) { |
1325 | (self.wrapping_shl(rhs), (rhs > ($BITS - 1))) | |
1b1a35ee XL |
1326 | } |
1327 | ||
5869c6ff XL |
1328 | /// Shifts self right by `rhs` bits. |
1329 | /// | |
1330 | /// Returns a tuple of the shifted version of self along with a boolean | |
1331 | /// indicating whether the shift value was larger than or equal to the | |
1332 | /// number of bits. If the shift value is too large, then value is | |
1333 | /// masked (N-1) where N is the number of bits, and this value is then | |
1334 | /// used to perform the shift. | |
1335 | /// | |
1336 | /// # Examples | |
1337 | /// | |
1338 | /// Basic usage | |
1339 | /// | |
1340 | /// ``` | |
1341 | #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(4), (0x1, false));")] | |
1342 | #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));")] | |
1343 | /// ``` | |
1344 | #[stable(feature = "wrapping", since = "1.7.0")] | |
1345 | #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] | |
1346 | #[must_use = "this returns the result of the operation, \ | |
1347 | without modifying the original"] | |
cdc7bbd5 | 1348 | #[inline(always)] |
5869c6ff XL |
1349 | pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) { |
1350 | (self.wrapping_shr(rhs), (rhs > ($BITS - 1))) | |
1351 | } | |
1b1a35ee | 1352 | |
5869c6ff XL |
1353 | /// Raises self to the power of `exp`, using exponentiation by squaring. |
1354 | /// | |
1355 | /// Returns a tuple of the exponentiation along with a bool indicating | |
1356 | /// whether an overflow happened. | |
1357 | /// | |
1358 | /// # Examples | |
1359 | /// | |
1360 | /// Basic usage: | |
1361 | /// | |
1362 | /// ``` | |
1363 | #[doc = concat!("assert_eq!(3", stringify!($SelfT), ".overflowing_pow(5), (243, false));")] | |
1364 | /// assert_eq!(3u8.overflowing_pow(6), (217, true)); | |
1365 | /// ``` | |
1366 | #[stable(feature = "no_panic_pow", since = "1.34.0")] | |
1367 | #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] | |
1368 | #[must_use = "this returns the result of the operation, \ | |
1369 | without modifying the original"] | |
1370 | #[inline] | |
1371 | pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) { | |
1372 | if exp == 0{ | |
1373 | return (1,false); | |
1374 | } | |
1375 | let mut base = self; | |
1376 | let mut acc: Self = 1; | |
1377 | let mut overflown = false; | |
1378 | // Scratch space for storing results of overflowing_mul. | |
1379 | let mut r; | |
1b1a35ee | 1380 | |
5869c6ff XL |
1381 | while exp > 1 { |
1382 | if (exp & 1) == 1 { | |
1383 | r = acc.overflowing_mul(base); | |
1384 | acc = r.0; | |
1b1a35ee XL |
1385 | overflown |= r.1; |
1386 | } | |
5869c6ff XL |
1387 | exp /= 2; |
1388 | r = base.overflowing_mul(base); | |
1389 | base = r.0; | |
1390 | overflown |= r.1; | |
1b1a35ee | 1391 | } |
1b1a35ee | 1392 | |
5869c6ff XL |
1393 | // since exp!=0, finally the exp must be 1. |
1394 | // Deal with the final bit of the exponent separately, since | |
1395 | // squaring the base afterwards is not necessary and may cause a | |
1396 | // needless overflow. | |
1397 | r = acc.overflowing_mul(base); | |
1398 | r.1 |= overflown; | |
1b1a35ee | 1399 | |
5869c6ff XL |
1400 | r |
1401 | } | |
1b1a35ee | 1402 | |
5869c6ff XL |
1403 | /// Raises self to the power of `exp`, using exponentiation by squaring. |
1404 | /// | |
1405 | /// # Examples | |
1406 | /// | |
1407 | /// Basic usage: | |
1408 | /// | |
1409 | /// ``` | |
1410 | #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".pow(5), 32);")] | |
1411 | /// ``` | |
1b1a35ee | 1412 | #[stable(feature = "rust1", since = "1.0.0")] |
fc512014 | 1413 | #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] |
1b1a35ee XL |
1414 | #[must_use = "this returns the result of the operation, \ |
1415 | without modifying the original"] | |
1416 | #[inline] | |
1417 | #[rustc_inherit_overflow_checks] | |
1418 | pub const fn pow(self, mut exp: u32) -> Self { | |
1419 | if exp == 0 { | |
1420 | return 1; | |
1421 | } | |
1422 | let mut base = self; | |
1423 | let mut acc = 1; | |
1424 | ||
1425 | while exp > 1 { | |
1426 | if (exp & 1) == 1 { | |
1427 | acc = acc * base; | |
1428 | } | |
1429 | exp /= 2; | |
1430 | base = base * base; | |
1431 | } | |
1432 | ||
1433 | // since exp!=0, finally the exp must be 1. | |
1434 | // Deal with the final bit of the exponent separately, since | |
1435 | // squaring the base afterwards is not necessary and may cause a | |
1436 | // needless overflow. | |
1437 | acc * base | |
1438 | } | |
1b1a35ee | 1439 | |
5869c6ff XL |
1440 | /// Performs Euclidean division. |
1441 | /// | |
1442 | /// Since, for the positive integers, all common | |
1443 | /// definitions of division are equal, this | |
1444 | /// is exactly equal to `self / rhs`. | |
1445 | /// | |
1446 | /// # Panics | |
1447 | /// | |
1448 | /// This function will panic if `rhs` is 0. | |
1449 | /// | |
1450 | /// # Examples | |
1451 | /// | |
1452 | /// Basic usage: | |
1453 | /// | |
1454 | /// ``` | |
1455 | #[doc = concat!("assert_eq!(7", stringify!($SelfT), ".div_euclid(4), 1); // or any other integer type")] | |
1456 | /// ``` | |
1457 | #[stable(feature = "euclidean_division", since = "1.38.0")] | |
6a06907d | 1458 | #[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")] |
5869c6ff XL |
1459 | #[must_use = "this returns the result of the operation, \ |
1460 | without modifying the original"] | |
cdc7bbd5 | 1461 | #[inline(always)] |
5869c6ff XL |
1462 | #[rustc_inherit_overflow_checks] |
1463 | pub const fn div_euclid(self, rhs: Self) -> Self { | |
1464 | self / rhs | |
1b1a35ee XL |
1465 | } |
1466 | ||
1467 | ||
5869c6ff XL |
1468 | /// Calculates the least remainder of `self (mod rhs)`. |
1469 | /// | |
1470 | /// Since, for the positive integers, all common | |
1471 | /// definitions of division are equal, this | |
1472 | /// is exactly equal to `self % rhs`. | |
1473 | /// | |
1474 | /// # Panics | |
1475 | /// | |
1476 | /// This function will panic if `rhs` is 0. | |
1477 | /// | |
1478 | /// # Examples | |
1479 | /// | |
1480 | /// Basic usage: | |
1481 | /// | |
1482 | /// ``` | |
1483 | #[doc = concat!("assert_eq!(7", stringify!($SelfT), ".rem_euclid(4), 3); // or any other integer type")] | |
1484 | /// ``` | |
1485 | #[stable(feature = "euclidean_division", since = "1.38.0")] | |
6a06907d | 1486 | #[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")] |
5869c6ff XL |
1487 | #[must_use = "this returns the result of the operation, \ |
1488 | without modifying the original"] | |
cdc7bbd5 | 1489 | #[inline(always)] |
5869c6ff XL |
1490 | #[rustc_inherit_overflow_checks] |
1491 | pub const fn rem_euclid(self, rhs: Self) -> Self { | |
1492 | self % rhs | |
1b1a35ee XL |
1493 | } |
1494 | ||
5869c6ff XL |
1495 | /// Returns `true` if and only if `self == 2^k` for some `k`. |
1496 | /// | |
1497 | /// # Examples | |
1498 | /// | |
1499 | /// Basic usage: | |
1500 | /// | |
1501 | /// ``` | |
1502 | #[doc = concat!("assert!(16", stringify!($SelfT), ".is_power_of_two());")] | |
1503 | #[doc = concat!("assert!(!10", stringify!($SelfT), ".is_power_of_two());")] | |
1504 | /// ``` | |
1505 | #[stable(feature = "rust1", since = "1.0.0")] | |
1506 | #[rustc_const_stable(feature = "const_is_power_of_two", since = "1.32.0")] | |
cdc7bbd5 | 1507 | #[inline(always)] |
5869c6ff XL |
1508 | pub const fn is_power_of_two(self) -> bool { |
1509 | self.count_ones() == 1 | |
1b1a35ee XL |
1510 | } |
1511 | ||
1512 | // Returns one less than next power of two. | |
1513 | // (For 8u8 next power of two is 8u8 and for 6u8 it is 8u8) | |
1514 | // | |
1515 | // 8u8.one_less_than_next_power_of_two() == 7 | |
1516 | // 6u8.one_less_than_next_power_of_two() == 7 | |
1517 | // | |
1518 | // This method cannot overflow, as in the `next_power_of_two` | |
1519 | // overflow cases it instead ends up returning the maximum value | |
1520 | // of the type, and can return 0 for 0. | |
1521 | #[inline] | |
fc512014 | 1522 | #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] |
1b1a35ee XL |
1523 | const fn one_less_than_next_power_of_two(self) -> Self { |
1524 | if self <= 1 { return 0; } | |
1525 | ||
1526 | let p = self - 1; | |
1527 | // SAFETY: Because `p > 0`, it cannot consist entirely of leading zeros. | |
1528 | // That means the shift is always in-bounds, and some processors | |
1529 | // (such as intel pre-haswell) have more efficient ctlz | |
1530 | // intrinsics when the argument is non-zero. | |
1531 | let z = unsafe { intrinsics::ctlz_nonzero(p) }; | |
1532 | <$SelfT>::MAX >> z | |
1533 | } | |
1534 | ||
5869c6ff XL |
1535 | /// Returns the smallest power of two greater than or equal to `self`. |
1536 | /// | |
1537 | /// When return value overflows (i.e., `self > (1 << (N-1))` for type | |
1538 | /// `uN`), it panics in debug mode and return value is wrapped to 0 in | |
1539 | /// release mode (the only situation in which method can return 0). | |
1540 | /// | |
1541 | /// # Examples | |
1542 | /// | |
1543 | /// Basic usage: | |
1544 | /// | |
1545 | /// ``` | |
1546 | #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".next_power_of_two(), 2);")] | |
1547 | #[doc = concat!("assert_eq!(3", stringify!($SelfT), ".next_power_of_two(), 4);")] | |
1548 | /// ``` | |
1549 | #[stable(feature = "rust1", since = "1.0.0")] | |
1550 | #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] | |
1551 | #[inline] | |
1552 | #[rustc_inherit_overflow_checks] | |
1553 | pub const fn next_power_of_two(self) -> Self { | |
1554 | self.one_less_than_next_power_of_two() + 1 | |
1b1a35ee XL |
1555 | } |
1556 | ||
5869c6ff XL |
1557 | /// Returns the smallest power of two greater than or equal to `n`. If |
1558 | /// the next power of two is greater than the type's maximum value, | |
1559 | /// `None` is returned, otherwise the power of two is wrapped in `Some`. | |
1560 | /// | |
1561 | /// # Examples | |
1562 | /// | |
1563 | /// Basic usage: | |
1564 | /// | |
1565 | /// ``` | |
1566 | #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".checked_next_power_of_two(), Some(2));")] | |
1567 | #[doc = concat!("assert_eq!(3", stringify!($SelfT), ".checked_next_power_of_two(), Some(4));")] | |
1568 | #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.checked_next_power_of_two(), None);")] | |
1569 | /// ``` | |
1570 | #[inline] | |
1571 | #[stable(feature = "rust1", since = "1.0.0")] | |
1572 | #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] | |
1573 | pub const fn checked_next_power_of_two(self) -> Option<Self> { | |
1574 | self.one_less_than_next_power_of_two().checked_add(1) | |
1b1a35ee XL |
1575 | } |
1576 | ||
5869c6ff XL |
1577 | /// Returns the smallest power of two greater than or equal to `n`. If |
1578 | /// the next power of two is greater than the type's maximum value, | |
1579 | /// the return value is wrapped to `0`. | |
1580 | /// | |
1581 | /// # Examples | |
1582 | /// | |
1583 | /// Basic usage: | |
1584 | /// | |
1585 | /// ``` | |
1586 | /// #![feature(wrapping_next_power_of_two)] | |
1587 | /// | |
1588 | #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".wrapping_next_power_of_two(), 2);")] | |
1589 | #[doc = concat!("assert_eq!(3", stringify!($SelfT), ".wrapping_next_power_of_two(), 4);")] | |
1590 | #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.wrapping_next_power_of_two(), 0);")] | |
1591 | /// ``` | |
1592 | #[unstable(feature = "wrapping_next_power_of_two", issue = "32463", | |
1593 | reason = "needs decision on wrapping behaviour")] | |
1594 | #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] | |
1595 | pub const fn wrapping_next_power_of_two(self) -> Self { | |
1596 | self.one_less_than_next_power_of_two().wrapping_add(1) | |
1b1a35ee XL |
1597 | } |
1598 | ||
5869c6ff XL |
1599 | /// Return the memory representation of this integer as a byte array in |
1600 | /// big-endian (network) byte order. | |
1601 | /// | |
1602 | #[doc = $to_xe_bytes_doc] | |
1603 | /// | |
1604 | /// # Examples | |
1605 | /// | |
1606 | /// ``` | |
1607 | #[doc = concat!("let bytes = ", $swap_op, stringify!($SelfT), ".to_be_bytes();")] | |
1608 | #[doc = concat!("assert_eq!(bytes, ", $be_bytes, ");")] | |
1609 | /// ``` | |
1610 | #[stable(feature = "int_to_from_bytes", since = "1.32.0")] | |
1611 | #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] | |
1612 | #[inline] | |
1613 | pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] { | |
1614 | self.to_be().to_ne_bytes() | |
1b1a35ee XL |
1615 | } |
1616 | ||
5869c6ff XL |
1617 | /// Return the memory representation of this integer as a byte array in |
1618 | /// little-endian byte order. | |
1619 | /// | |
1620 | #[doc = $to_xe_bytes_doc] | |
1621 | /// | |
1622 | /// # Examples | |
1623 | /// | |
1624 | /// ``` | |
1625 | #[doc = concat!("let bytes = ", $swap_op, stringify!($SelfT), ".to_le_bytes();")] | |
1626 | #[doc = concat!("assert_eq!(bytes, ", $le_bytes, ");")] | |
1627 | /// ``` | |
1628 | #[stable(feature = "int_to_from_bytes", since = "1.32.0")] | |
1629 | #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] | |
1630 | #[inline] | |
1631 | pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] { | |
1632 | self.to_le().to_ne_bytes() | |
1b1a35ee XL |
1633 | } |
1634 | ||
5869c6ff XL |
1635 | /// Return the memory representation of this integer as a byte array in |
1636 | /// native byte order. | |
1637 | /// | |
1638 | /// As the target platform's native endianness is used, portable code | |
1639 | /// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, | |
1640 | /// instead. | |
1641 | /// | |
1642 | #[doc = $to_xe_bytes_doc] | |
1643 | /// | |
6a06907d XL |
1644 | /// [`to_be_bytes`]: Self::to_be_bytes |
1645 | /// [`to_le_bytes`]: Self::to_le_bytes | |
5869c6ff XL |
1646 | /// |
1647 | /// # Examples | |
1648 | /// | |
1649 | /// ``` | |
1650 | #[doc = concat!("let bytes = ", $swap_op, stringify!($SelfT), ".to_ne_bytes();")] | |
1651 | /// assert_eq!( | |
1652 | /// bytes, | |
1653 | /// if cfg!(target_endian = "big") { | |
1654 | #[doc = concat!(" ", $be_bytes)] | |
1655 | /// } else { | |
1656 | #[doc = concat!(" ", $le_bytes)] | |
1657 | /// } | |
1658 | /// ); | |
1659 | /// ``` | |
1660 | #[stable(feature = "int_to_from_bytes", since = "1.32.0")] | |
1661 | #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] | |
1662 | // SAFETY: const sound because integers are plain old datatypes so we can always | |
1663 | // transmute them to arrays of bytes | |
1664 | #[rustc_allow_const_fn_unstable(const_fn_transmute)] | |
1665 | #[inline] | |
1666 | pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] { | |
1667 | // SAFETY: integers are plain old datatypes so we can always transmute them to | |
1668 | // arrays of bytes | |
1669 | unsafe { mem::transmute(self) } | |
29967ef6 XL |
1670 | } |
1671 | ||
5869c6ff XL |
1672 | /// Return the memory representation of this integer as a byte array in |
1673 | /// native byte order. | |
1674 | /// | |
1675 | /// [`to_ne_bytes`] should be preferred over this whenever possible. | |
1676 | /// | |
6a06907d | 1677 | /// [`to_ne_bytes`]: Self::to_ne_bytes |
5869c6ff XL |
1678 | /// |
1679 | /// # Examples | |
1680 | /// | |
1681 | /// ``` | |
1682 | /// #![feature(num_as_ne_bytes)] | |
1683 | #[doc = concat!("let num = ", $swap_op, stringify!($SelfT), ";")] | |
1684 | /// let bytes = num.as_ne_bytes(); | |
1685 | /// assert_eq!( | |
1686 | /// bytes, | |
1687 | /// if cfg!(target_endian = "big") { | |
1688 | #[doc = concat!(" &", $be_bytes)] | |
1689 | /// } else { | |
1690 | #[doc = concat!(" &", $le_bytes)] | |
1691 | /// } | |
1692 | /// ); | |
1693 | /// ``` | |
1694 | #[unstable(feature = "num_as_ne_bytes", issue = "76976")] | |
1695 | #[inline] | |
1696 | pub fn as_ne_bytes(&self) -> &[u8; mem::size_of::<Self>()] { | |
1697 | // SAFETY: integers are plain old datatypes so we can always transmute them to | |
1698 | // arrays of bytes | |
1699 | unsafe { &*(self as *const Self as *const _) } | |
1b1a35ee XL |
1700 | } |
1701 | ||
5869c6ff XL |
1702 | /// Create a native endian integer value from its representation |
1703 | /// as a byte array in big endian. | |
1704 | /// | |
1705 | #[doc = $from_xe_bytes_doc] | |
1706 | /// | |
1707 | /// # Examples | |
1708 | /// | |
1709 | /// ``` | |
1710 | #[doc = concat!("let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, ");")] | |
1711 | #[doc = concat!("assert_eq!(value, ", $swap_op, ");")] | |
1712 | /// ``` | |
1713 | /// | |
1714 | /// When starting from a slice rather than an array, fallible conversion APIs can be used: | |
1715 | /// | |
1716 | /// ``` | |
1717 | /// use std::convert::TryInto; | |
1718 | /// | |
1719 | #[doc = concat!("fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")] | |
1720 | #[doc = concat!(" let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")] | |
1721 | /// *input = rest; | |
1722 | #[doc = concat!(" ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())")] | |
1723 | /// } | |
1724 | /// ``` | |
1725 | #[stable(feature = "int_to_from_bytes", since = "1.32.0")] | |
1726 | #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] | |
1727 | #[inline] | |
1728 | pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self { | |
1729 | Self::from_be(Self::from_ne_bytes(bytes)) | |
1b1a35ee XL |
1730 | } |
1731 | ||
5869c6ff XL |
1732 | /// Create a native endian integer value from its representation |
1733 | /// as a byte array in little endian. | |
1734 | /// | |
1735 | #[doc = $from_xe_bytes_doc] | |
1736 | /// | |
1737 | /// # Examples | |
1738 | /// | |
1739 | /// ``` | |
1740 | #[doc = concat!("let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, ");")] | |
1741 | #[doc = concat!("assert_eq!(value, ", $swap_op, ");")] | |
1742 | /// ``` | |
1743 | /// | |
1744 | /// When starting from a slice rather than an array, fallible conversion APIs can be used: | |
1745 | /// | |
1746 | /// ``` | |
1747 | /// use std::convert::TryInto; | |
1748 | /// | |
1749 | #[doc = concat!("fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")] | |
1750 | #[doc = concat!(" let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")] | |
1751 | /// *input = rest; | |
1752 | #[doc = concat!(" ", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())")] | |
1753 | /// } | |
1754 | /// ``` | |
1755 | #[stable(feature = "int_to_from_bytes", since = "1.32.0")] | |
1756 | #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] | |
1757 | #[inline] | |
1758 | pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self { | |
1759 | Self::from_le(Self::from_ne_bytes(bytes)) | |
1b1a35ee XL |
1760 | } |
1761 | ||
5869c6ff XL |
1762 | /// Create a native endian integer value from its memory representation |
1763 | /// as a byte array in native endianness. | |
1764 | /// | |
1765 | /// As the target platform's native endianness is used, portable code | |
1766 | /// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as | |
1767 | /// appropriate instead. | |
1768 | /// | |
6a06907d XL |
1769 | /// [`from_be_bytes`]: Self::from_be_bytes |
1770 | /// [`from_le_bytes`]: Self::from_le_bytes | |
5869c6ff XL |
1771 | /// |
1772 | #[doc = $from_xe_bytes_doc] | |
1773 | /// | |
1774 | /// # Examples | |
1775 | /// | |
1776 | /// ``` | |
1777 | #[doc = concat!("let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"big\") {")] | |
1778 | #[doc = concat!(" ", $be_bytes, "")] | |
1779 | /// } else { | |
1780 | #[doc = concat!(" ", $le_bytes, "")] | |
1781 | /// }); | |
1782 | #[doc = concat!("assert_eq!(value, ", $swap_op, ");")] | |
1783 | /// ``` | |
1784 | /// | |
1785 | /// When starting from a slice rather than an array, fallible conversion APIs can be used: | |
1786 | /// | |
1787 | /// ``` | |
1788 | /// use std::convert::TryInto; | |
1789 | /// | |
1790 | #[doc = concat!("fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")] | |
1791 | #[doc = concat!(" let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")] | |
1792 | /// *input = rest; | |
1793 | #[doc = concat!(" ", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())")] | |
1794 | /// } | |
1795 | /// ``` | |
1796 | #[stable(feature = "int_to_from_bytes", since = "1.32.0")] | |
1797 | #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] | |
1798 | // SAFETY: const sound because integers are plain old datatypes so we can always | |
1799 | // transmute to them | |
1800 | #[rustc_allow_const_fn_unstable(const_fn_transmute)] | |
1801 | #[inline] | |
1802 | pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self { | |
1803 | // SAFETY: integers are plain old datatypes so we can always transmute to them | |
1804 | unsafe { mem::transmute(bytes) } | |
1b1a35ee XL |
1805 | } |
1806 | ||
5869c6ff | 1807 | /// New code should prefer to use |
6a06907d | 1808 | #[doc = concat!("[`", stringify!($SelfT), "::MIN", "`] instead.")] |
5869c6ff XL |
1809 | /// |
1810 | /// Returns the smallest value that can be represented by this integer type. | |
1811 | #[stable(feature = "rust1", since = "1.0.0")] | |
1812 | #[rustc_promotable] | |
1813 | #[inline(always)] | |
1814 | #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")] | |
1815 | #[rustc_deprecated(since = "TBD", reason = "replaced by the `MIN` associated constant on this type")] | |
1816 | pub const fn min_value() -> Self { Self::MIN } | |
1817 | ||
1818 | /// New code should prefer to use | |
6a06907d | 1819 | #[doc = concat!("[`", stringify!($SelfT), "::MAX", "`] instead.")] |
5869c6ff XL |
1820 | /// |
1821 | /// Returns the largest value that can be represented by this integer type. | |
1822 | #[stable(feature = "rust1", since = "1.0.0")] | |
1823 | #[rustc_promotable] | |
1824 | #[inline(always)] | |
1825 | #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")] | |
1826 | #[rustc_deprecated(since = "TBD", reason = "replaced by the `MAX` associated constant on this type")] | |
1827 | pub const fn max_value() -> Self { Self::MAX } | |
1b1a35ee XL |
1828 | } |
1829 | } |