core/num/mod.rs
1//! Numeric traits and functions for the built-in numeric types.
2
3#![stable(feature = "rust1", since = "1.0.0")]
4
5use crate::panic::const_panic;
6use crate::str::FromStr;
7use crate::ub_checks::assert_unsafe_precondition;
8use crate::{ascii, intrinsics, mem};
9
10// FIXME(const-hack): Used because the `?` operator is not allowed in a const context.
11macro_rules! try_opt {
12 ($e:expr) => {
13 match $e {
14 Some(x) => x,
15 None => return None,
16 }
17 };
18}
19
20// Use this when the generated code should differ between signed and unsigned types.
21macro_rules! sign_dependent_expr {
22 (signed ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
23 $signed_case
24 };
25 (unsigned ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
26 $unsigned_case
27 };
28}
29
30// All these modules are technically private and only exposed for coretests:
31#[cfg(not(no_fp_fmt_parse))]
32pub mod bignum;
33#[cfg(not(no_fp_fmt_parse))]
34pub mod dec2flt;
35#[cfg(not(no_fp_fmt_parse))]
36pub mod diy_float;
37#[cfg(not(no_fp_fmt_parse))]
38pub mod flt2dec;
39pub mod fmt;
40
41#[macro_use]
42mod int_macros; // import int_impl!
43#[macro_use]
44mod uint_macros; // import uint_impl!
45
46mod error;
47mod int_log10;
48mod int_sqrt;
49mod nonzero;
50mod overflow_panic;
51mod saturating;
52mod wrapping;
53
54/// 100% perma-unstable
55#[doc(hidden)]
56pub mod niche_types;
57
58#[stable(feature = "rust1", since = "1.0.0")]
59#[cfg(not(no_fp_fmt_parse))]
60pub use dec2flt::ParseFloatError;
61#[stable(feature = "int_error_matching", since = "1.55.0")]
62pub use error::IntErrorKind;
63#[stable(feature = "rust1", since = "1.0.0")]
64pub use error::ParseIntError;
65#[stable(feature = "try_from", since = "1.34.0")]
66pub use error::TryFromIntError;
67#[stable(feature = "generic_nonzero", since = "1.79.0")]
68pub use nonzero::NonZero;
69#[unstable(
70 feature = "nonzero_internals",
71 reason = "implementation detail which may disappear or be replaced at any time",
72 issue = "none"
73)]
74pub use nonzero::ZeroablePrimitive;
75#[stable(feature = "signed_nonzero", since = "1.34.0")]
76pub use nonzero::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize};
77#[stable(feature = "nonzero", since = "1.28.0")]
78pub use nonzero::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize};
79#[stable(feature = "saturating_int_impl", since = "1.74.0")]
80pub use saturating::Saturating;
81#[stable(feature = "rust1", since = "1.0.0")]
82pub use wrapping::Wrapping;
83
84macro_rules! u8_xe_bytes_doc {
85 () => {
86 "
87
88**Note**: This function is meaningless on `u8`. Byte order does not exist as a
89concept for byte-sized integers. This function is only provided in symmetry
90with larger integer types.
91
92"
93 };
94}
95
96macro_rules! i8_xe_bytes_doc {
97 () => {
98 "
99
100**Note**: This function is meaningless on `i8`. Byte order does not exist as a
101concept for byte-sized integers. This function is only provided in symmetry
102with larger integer types. You can cast from and to `u8` using
103[`cast_signed`](u8::cast_signed) and [`cast_unsigned`](Self::cast_unsigned).
104
105"
106 };
107}
108
109macro_rules! usize_isize_to_xe_bytes_doc {
110 () => {
111 "
112
113**Note**: This function returns an array of length 2, 4 or 8 bytes
114depending on the target pointer size.
115
116"
117 };
118}
119
120macro_rules! usize_isize_from_xe_bytes_doc {
121 () => {
122 "
123
124**Note**: This function takes an array of length 2, 4 or 8 bytes
125depending on the target pointer size.
126
127"
128 };
129}
130
131macro_rules! midpoint_impl {
132 ($SelfT:ty, unsigned) => {
133 /// Calculates the midpoint (average) between `self` and `rhs`.
134 ///
135 /// `midpoint(a, b)` is `(a + b) / 2` as if it were performed in a
136 /// sufficiently-large unsigned integral type. This implies that the result is
137 /// always rounded towards zero and that no overflow will ever occur.
138 ///
139 /// # Examples
140 ///
141 /// ```
142 #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")]
143 #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".midpoint(4), 2);")]
144 /// ```
145 #[stable(feature = "num_midpoint", since = "1.85.0")]
146 #[rustc_const_stable(feature = "num_midpoint", since = "1.85.0")]
147 #[must_use = "this returns the result of the operation, \
148 without modifying the original"]
149 #[doc(alias = "average_floor")]
150 #[doc(alias = "average")]
151 #[inline]
152 pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
153 // Use the well known branchless algorithm from Hacker's Delight to compute
154 // `(a + b) / 2` without overflowing: `((a ^ b) >> 1) + (a & b)`.
155 ((self ^ rhs) >> 1) + (self & rhs)
156 }
157 };
158 ($SelfT:ty, signed) => {
159 /// Calculates the midpoint (average) between `self` and `rhs`.
160 ///
161 /// `midpoint(a, b)` is `(a + b) / 2` as if it were performed in a
162 /// sufficiently-large signed integral type. This implies that the result is
163 /// always rounded towards zero and that no overflow will ever occur.
164 ///
165 /// # Examples
166 ///
167 /// ```
168 #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")]
169 #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").midpoint(2), 0);")]
170 #[doc = concat!("assert_eq!((-7", stringify!($SelfT), ").midpoint(0), -3);")]
171 #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-7), -3);")]
172 #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(7), 3);")]
173 /// ```
174 #[stable(feature = "num_midpoint_signed", since = "1.87.0")]
175 #[rustc_const_stable(feature = "num_midpoint_signed", since = "1.87.0")]
176 #[must_use = "this returns the result of the operation, \
177 without modifying the original"]
178 #[doc(alias = "average_floor")]
179 #[doc(alias = "average_ceil")]
180 #[doc(alias = "average")]
181 #[inline]
182 pub const fn midpoint(self, rhs: Self) -> Self {
183 // Use the well known branchless algorithm from Hacker's Delight to compute
184 // `(a + b) / 2` without overflowing: `((a ^ b) >> 1) + (a & b)`.
185 let t = ((self ^ rhs) >> 1) + (self & rhs);
186 // Except that it fails for integers whose sum is an odd negative number as
187 // their floor is one less than their average. So we adjust the result.
188 t + (if t < 0 { 1 } else { 0 } & (self ^ rhs))
189 }
190 };
191 ($SelfT:ty, $WideT:ty, unsigned) => {
192 /// Calculates the midpoint (average) between `self` and `rhs`.
193 ///
194 /// `midpoint(a, b)` is `(a + b) / 2` as if it were performed in a
195 /// sufficiently-large unsigned integral type. This implies that the result is
196 /// always rounded towards zero and that no overflow will ever occur.
197 ///
198 /// # Examples
199 ///
200 /// ```
201 #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")]
202 #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".midpoint(4), 2);")]
203 /// ```
204 #[stable(feature = "num_midpoint", since = "1.85.0")]
205 #[rustc_const_stable(feature = "num_midpoint", since = "1.85.0")]
206 #[must_use = "this returns the result of the operation, \
207 without modifying the original"]
208 #[doc(alias = "average_floor")]
209 #[doc(alias = "average")]
210 #[inline]
211 pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
212 ((self as $WideT + rhs as $WideT) / 2) as $SelfT
213 }
214 };
215 ($SelfT:ty, $WideT:ty, signed) => {
216 /// Calculates the midpoint (average) between `self` and `rhs`.
217 ///
218 /// `midpoint(a, b)` is `(a + b) / 2` as if it were performed in a
219 /// sufficiently-large signed integral type. This implies that the result is
220 /// always rounded towards zero and that no overflow will ever occur.
221 ///
222 /// # Examples
223 ///
224 /// ```
225 #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")]
226 #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").midpoint(2), 0);")]
227 #[doc = concat!("assert_eq!((-7", stringify!($SelfT), ").midpoint(0), -3);")]
228 #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-7), -3);")]
229 #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(7), 3);")]
230 /// ```
231 #[stable(feature = "num_midpoint_signed", since = "1.87.0")]
232 #[rustc_const_stable(feature = "num_midpoint_signed", since = "1.87.0")]
233 #[must_use = "this returns the result of the operation, \
234 without modifying the original"]
235 #[doc(alias = "average_floor")]
236 #[doc(alias = "average_ceil")]
237 #[doc(alias = "average")]
238 #[inline]
239 pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
240 ((self as $WideT + rhs as $WideT) / 2) as $SelfT
241 }
242 };
243}
244
245impl i8 {
246 int_impl! {
247 Self = i8,
248 ActualT = i8,
249 UnsignedT = u8,
250 BITS = 8,
251 BITS_MINUS_ONE = 7,
252 Min = -128,
253 Max = 127,
254 rot = 2,
255 rot_op = "-0x7e",
256 rot_result = "0xa",
257 swap_op = "0x12",
258 swapped = "0x12",
259 reversed = "0x48",
260 le_bytes = "[0x12]",
261 be_bytes = "[0x12]",
262 to_xe_bytes_doc = i8_xe_bytes_doc!(),
263 from_xe_bytes_doc = i8_xe_bytes_doc!(),
264 bound_condition = "",
265 }
266 midpoint_impl! { i8, i16, signed }
267}
268
269impl i16 {
270 int_impl! {
271 Self = i16,
272 ActualT = i16,
273 UnsignedT = u16,
274 BITS = 16,
275 BITS_MINUS_ONE = 15,
276 Min = -32768,
277 Max = 32767,
278 rot = 4,
279 rot_op = "-0x5ffd",
280 rot_result = "0x3a",
281 swap_op = "0x1234",
282 swapped = "0x3412",
283 reversed = "0x2c48",
284 le_bytes = "[0x34, 0x12]",
285 be_bytes = "[0x12, 0x34]",
286 to_xe_bytes_doc = "",
287 from_xe_bytes_doc = "",
288 bound_condition = "",
289 }
290 midpoint_impl! { i16, i32, signed }
291}
292
293impl i32 {
294 int_impl! {
295 Self = i32,
296 ActualT = i32,
297 UnsignedT = u32,
298 BITS = 32,
299 BITS_MINUS_ONE = 31,
300 Min = -2147483648,
301 Max = 2147483647,
302 rot = 8,
303 rot_op = "0x10000b3",
304 rot_result = "0xb301",
305 swap_op = "0x12345678",
306 swapped = "0x78563412",
307 reversed = "0x1e6a2c48",
308 le_bytes = "[0x78, 0x56, 0x34, 0x12]",
309 be_bytes = "[0x12, 0x34, 0x56, 0x78]",
310 to_xe_bytes_doc = "",
311 from_xe_bytes_doc = "",
312 bound_condition = "",
313 }
314 midpoint_impl! { i32, i64, signed }
315}
316
317impl i64 {
318 int_impl! {
319 Self = i64,
320 ActualT = i64,
321 UnsignedT = u64,
322 BITS = 64,
323 BITS_MINUS_ONE = 63,
324 Min = -9223372036854775808,
325 Max = 9223372036854775807,
326 rot = 12,
327 rot_op = "0xaa00000000006e1",
328 rot_result = "0x6e10aa",
329 swap_op = "0x1234567890123456",
330 swapped = "0x5634129078563412",
331 reversed = "0x6a2c48091e6a2c48",
332 le_bytes = "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
333 be_bytes = "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
334 to_xe_bytes_doc = "",
335 from_xe_bytes_doc = "",
336 bound_condition = "",
337 }
338 midpoint_impl! { i64, signed }
339}
340
341impl i128 {
342 int_impl! {
343 Self = i128,
344 ActualT = i128,
345 UnsignedT = u128,
346 BITS = 128,
347 BITS_MINUS_ONE = 127,
348 Min = -170141183460469231731687303715884105728,
349 Max = 170141183460469231731687303715884105727,
350 rot = 16,
351 rot_op = "0x13f40000000000000000000000004f76",
352 rot_result = "0x4f7613f4",
353 swap_op = "0x12345678901234567890123456789012",
354 swapped = "0x12907856341290785634129078563412",
355 reversed = "0x48091e6a2c48091e6a2c48091e6a2c48",
356 le_bytes = "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
357 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
358 be_bytes = "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
359 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]",
360 to_xe_bytes_doc = "",
361 from_xe_bytes_doc = "",
362 bound_condition = "",
363 }
364 midpoint_impl! { i128, signed }
365}
366
367#[cfg(target_pointer_width = "16")]
368impl isize {
369 int_impl! {
370 Self = isize,
371 ActualT = i16,
372 UnsignedT = usize,
373 BITS = 16,
374 BITS_MINUS_ONE = 15,
375 Min = -32768,
376 Max = 32767,
377 rot = 4,
378 rot_op = "-0x5ffd",
379 rot_result = "0x3a",
380 swap_op = "0x1234",
381 swapped = "0x3412",
382 reversed = "0x2c48",
383 le_bytes = "[0x34, 0x12]",
384 be_bytes = "[0x12, 0x34]",
385 to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(),
386 from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
387 bound_condition = " on 16-bit targets",
388 }
389 midpoint_impl! { isize, i32, signed }
390}
391
392#[cfg(target_pointer_width = "32")]
393impl isize {
394 int_impl! {
395 Self = isize,
396 ActualT = i32,
397 UnsignedT = usize,
398 BITS = 32,
399 BITS_MINUS_ONE = 31,
400 Min = -2147483648,
401 Max = 2147483647,
402 rot = 8,
403 rot_op = "0x10000b3",
404 rot_result = "0xb301",
405 swap_op = "0x12345678",
406 swapped = "0x78563412",
407 reversed = "0x1e6a2c48",
408 le_bytes = "[0x78, 0x56, 0x34, 0x12]",
409 be_bytes = "[0x12, 0x34, 0x56, 0x78]",
410 to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(),
411 from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
412 bound_condition = " on 32-bit targets",
413 }
414 midpoint_impl! { isize, i64, signed }
415}
416
417#[cfg(target_pointer_width = "64")]
418impl isize {
419 int_impl! {
420 Self = isize,
421 ActualT = i64,
422 UnsignedT = usize,
423 BITS = 64,
424 BITS_MINUS_ONE = 63,
425 Min = -9223372036854775808,
426 Max = 9223372036854775807,
427 rot = 12,
428 rot_op = "0xaa00000000006e1",
429 rot_result = "0x6e10aa",
430 swap_op = "0x1234567890123456",
431 swapped = "0x5634129078563412",
432 reversed = "0x6a2c48091e6a2c48",
433 le_bytes = "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
434 be_bytes = "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
435 to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(),
436 from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
437 bound_condition = " on 64-bit targets",
438 }
439 midpoint_impl! { isize, signed }
440}
441
442/// If the bit selected by this mask is set, ascii is lower case.
443const ASCII_CASE_MASK: u8 = 0b0010_0000;
444
445impl u8 {
446 uint_impl! {
447 Self = u8,
448 ActualT = u8,
449 SignedT = i8,
450 BITS = 8,
451 BITS_MINUS_ONE = 7,
452 MAX = 255,
453 rot = 2,
454 rot_op = "0x82",
455 rot_result = "0xa",
456 swap_op = "0x12",
457 swapped = "0x12",
458 reversed = "0x48",
459 le_bytes = "[0x12]",
460 be_bytes = "[0x12]",
461 to_xe_bytes_doc = u8_xe_bytes_doc!(),
462 from_xe_bytes_doc = u8_xe_bytes_doc!(),
463 bound_condition = "",
464 }
465 midpoint_impl! { u8, u16, unsigned }
466
467 /// Checks if the value is within the ASCII range.
468 ///
469 /// # Examples
470 ///
471 /// ```
472 /// let ascii = 97u8;
473 /// let non_ascii = 150u8;
474 ///
475 /// assert!(ascii.is_ascii());
476 /// assert!(!non_ascii.is_ascii());
477 /// ```
478 #[must_use]
479 #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
480 #[rustc_const_stable(feature = "const_u8_is_ascii", since = "1.43.0")]
481 #[inline]
482 pub const fn is_ascii(&self) -> bool {
483 *self <= 127
484 }
485
486 /// If the value of this byte is within the ASCII range, returns it as an
487 /// [ASCII character](ascii::Char). Otherwise, returns `None`.
488 #[must_use]
489 #[unstable(feature = "ascii_char", issue = "110998")]
490 #[inline]
491 pub const fn as_ascii(&self) -> Option<ascii::Char> {
492 ascii::Char::from_u8(*self)
493 }
494
495 /// Makes a copy of the value in its ASCII upper case equivalent.
496 ///
497 /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
498 /// but non-ASCII letters are unchanged.
499 ///
500 /// To uppercase the value in-place, use [`make_ascii_uppercase`].
501 ///
502 /// # Examples
503 ///
504 /// ```
505 /// let lowercase_a = 97u8;
506 ///
507 /// assert_eq!(65, lowercase_a.to_ascii_uppercase());
508 /// ```
509 ///
510 /// [`make_ascii_uppercase`]: Self::make_ascii_uppercase
511 #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase()`"]
512 #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
513 #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
514 #[inline]
515 pub const fn to_ascii_uppercase(&self) -> u8 {
516 // Toggle the 6th bit if this is a lowercase letter
517 *self ^ ((self.is_ascii_lowercase() as u8) * ASCII_CASE_MASK)
518 }
519
520 /// Makes a copy of the value in its ASCII lower case equivalent.
521 ///
522 /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
523 /// but non-ASCII letters are unchanged.
524 ///
525 /// To lowercase the value in-place, use [`make_ascii_lowercase`].
526 ///
527 /// # Examples
528 ///
529 /// ```
530 /// let uppercase_a = 65u8;
531 ///
532 /// assert_eq!(97, uppercase_a.to_ascii_lowercase());
533 /// ```
534 ///
535 /// [`make_ascii_lowercase`]: Self::make_ascii_lowercase
536 #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"]
537 #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
538 #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
539 #[inline]
540 pub const fn to_ascii_lowercase(&self) -> u8 {
541 // Set the 6th bit if this is an uppercase letter
542 *self | (self.is_ascii_uppercase() as u8 * ASCII_CASE_MASK)
543 }
544
545 /// Assumes self is ascii
546 #[inline]
547 pub(crate) const fn ascii_change_case_unchecked(&self) -> u8 {
548 *self ^ ASCII_CASE_MASK
549 }
550
551 /// Checks that two values are an ASCII case-insensitive match.
552 ///
553 /// This is equivalent to `to_ascii_lowercase(a) == to_ascii_lowercase(b)`.
554 ///
555 /// # Examples
556 ///
557 /// ```
558 /// let lowercase_a = 97u8;
559 /// let uppercase_a = 65u8;
560 ///
561 /// assert!(lowercase_a.eq_ignore_ascii_case(&uppercase_a));
562 /// ```
563 #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
564 #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
565 #[inline]
566 pub const fn eq_ignore_ascii_case(&self, other: &u8) -> bool {
567 self.to_ascii_lowercase() == other.to_ascii_lowercase()
568 }
569
570 /// Converts this value to its ASCII upper case equivalent in-place.
571 ///
572 /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
573 /// but non-ASCII letters are unchanged.
574 ///
575 /// To return a new uppercased value without modifying the existing one, use
576 /// [`to_ascii_uppercase`].
577 ///
578 /// # Examples
579 ///
580 /// ```
581 /// let mut byte = b'a';
582 ///
583 /// byte.make_ascii_uppercase();
584 ///
585 /// assert_eq!(b'A', byte);
586 /// ```
587 ///
588 /// [`to_ascii_uppercase`]: Self::to_ascii_uppercase
589 #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
590 #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")]
591 #[inline]
592 pub const fn make_ascii_uppercase(&mut self) {
593 *self = self.to_ascii_uppercase();
594 }
595
596 /// Converts this value to its ASCII lower case equivalent in-place.
597 ///
598 /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
599 /// but non-ASCII letters are unchanged.
600 ///
601 /// To return a new lowercased value without modifying the existing one, use
602 /// [`to_ascii_lowercase`].
603 ///
604 /// # Examples
605 ///
606 /// ```
607 /// let mut byte = b'A';
608 ///
609 /// byte.make_ascii_lowercase();
610 ///
611 /// assert_eq!(b'a', byte);
612 /// ```
613 ///
614 /// [`to_ascii_lowercase`]: Self::to_ascii_lowercase
615 #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
616 #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")]
617 #[inline]
618 pub const fn make_ascii_lowercase(&mut self) {
619 *self = self.to_ascii_lowercase();
620 }
621
622 /// Checks if the value is an ASCII alphabetic character:
623 ///
624 /// - U+0041 'A' ..= U+005A 'Z', or
625 /// - U+0061 'a' ..= U+007A 'z'.
626 ///
627 /// # Examples
628 ///
629 /// ```
630 /// let uppercase_a = b'A';
631 /// let uppercase_g = b'G';
632 /// let a = b'a';
633 /// let g = b'g';
634 /// let zero = b'0';
635 /// let percent = b'%';
636 /// let space = b' ';
637 /// let lf = b'\n';
638 /// let esc = b'\x1b';
639 ///
640 /// assert!(uppercase_a.is_ascii_alphabetic());
641 /// assert!(uppercase_g.is_ascii_alphabetic());
642 /// assert!(a.is_ascii_alphabetic());
643 /// assert!(g.is_ascii_alphabetic());
644 /// assert!(!zero.is_ascii_alphabetic());
645 /// assert!(!percent.is_ascii_alphabetic());
646 /// assert!(!space.is_ascii_alphabetic());
647 /// assert!(!lf.is_ascii_alphabetic());
648 /// assert!(!esc.is_ascii_alphabetic());
649 /// ```
650 #[must_use]
651 #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
652 #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
653 #[inline]
654 pub const fn is_ascii_alphabetic(&self) -> bool {
655 matches!(*self, b'A'..=b'Z' | b'a'..=b'z')
656 }
657
658 /// Checks if the value is an ASCII uppercase character:
659 /// U+0041 'A' ..= U+005A 'Z'.
660 ///
661 /// # Examples
662 ///
663 /// ```
664 /// let uppercase_a = b'A';
665 /// let uppercase_g = b'G';
666 /// let a = b'a';
667 /// let g = b'g';
668 /// let zero = b'0';
669 /// let percent = b'%';
670 /// let space = b' ';
671 /// let lf = b'\n';
672 /// let esc = b'\x1b';
673 ///
674 /// assert!(uppercase_a.is_ascii_uppercase());
675 /// assert!(uppercase_g.is_ascii_uppercase());
676 /// assert!(!a.is_ascii_uppercase());
677 /// assert!(!g.is_ascii_uppercase());
678 /// assert!(!zero.is_ascii_uppercase());
679 /// assert!(!percent.is_ascii_uppercase());
680 /// assert!(!space.is_ascii_uppercase());
681 /// assert!(!lf.is_ascii_uppercase());
682 /// assert!(!esc.is_ascii_uppercase());
683 /// ```
684 #[must_use]
685 #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
686 #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
687 #[inline]
688 pub const fn is_ascii_uppercase(&self) -> bool {
689 matches!(*self, b'A'..=b'Z')
690 }
691
692 /// Checks if the value is an ASCII lowercase character:
693 /// U+0061 'a' ..= U+007A 'z'.
694 ///
695 /// # Examples
696 ///
697 /// ```
698 /// let uppercase_a = b'A';
699 /// let uppercase_g = b'G';
700 /// let a = b'a';
701 /// let g = b'g';
702 /// let zero = b'0';
703 /// let percent = b'%';
704 /// let space = b' ';
705 /// let lf = b'\n';
706 /// let esc = b'\x1b';
707 ///
708 /// assert!(!uppercase_a.is_ascii_lowercase());
709 /// assert!(!uppercase_g.is_ascii_lowercase());
710 /// assert!(a.is_ascii_lowercase());
711 /// assert!(g.is_ascii_lowercase());
712 /// assert!(!zero.is_ascii_lowercase());
713 /// assert!(!percent.is_ascii_lowercase());
714 /// assert!(!space.is_ascii_lowercase());
715 /// assert!(!lf.is_ascii_lowercase());
716 /// assert!(!esc.is_ascii_lowercase());
717 /// ```
718 #[must_use]
719 #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
720 #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
721 #[inline]
722 pub const fn is_ascii_lowercase(&self) -> bool {
723 matches!(*self, b'a'..=b'z')
724 }
725
726 /// Checks if the value is an ASCII alphanumeric character:
727 ///
728 /// - U+0041 'A' ..= U+005A 'Z', or
729 /// - U+0061 'a' ..= U+007A 'z', or
730 /// - U+0030 '0' ..= U+0039 '9'.
731 ///
732 /// # Examples
733 ///
734 /// ```
735 /// let uppercase_a = b'A';
736 /// let uppercase_g = b'G';
737 /// let a = b'a';
738 /// let g = b'g';
739 /// let zero = b'0';
740 /// let percent = b'%';
741 /// let space = b' ';
742 /// let lf = b'\n';
743 /// let esc = b'\x1b';
744 ///
745 /// assert!(uppercase_a.is_ascii_alphanumeric());
746 /// assert!(uppercase_g.is_ascii_alphanumeric());
747 /// assert!(a.is_ascii_alphanumeric());
748 /// assert!(g.is_ascii_alphanumeric());
749 /// assert!(zero.is_ascii_alphanumeric());
750 /// assert!(!percent.is_ascii_alphanumeric());
751 /// assert!(!space.is_ascii_alphanumeric());
752 /// assert!(!lf.is_ascii_alphanumeric());
753 /// assert!(!esc.is_ascii_alphanumeric());
754 /// ```
755 #[must_use]
756 #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
757 #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
758 #[inline]
759 pub const fn is_ascii_alphanumeric(&self) -> bool {
760 matches!(*self, b'0'..=b'9') | matches!(*self, b'A'..=b'Z') | matches!(*self, b'a'..=b'z')
761 }
762
763 /// Checks if the value is an ASCII decimal digit:
764 /// U+0030 '0' ..= U+0039 '9'.
765 ///
766 /// # Examples
767 ///
768 /// ```
769 /// let uppercase_a = b'A';
770 /// let uppercase_g = b'G';
771 /// let a = b'a';
772 /// let g = b'g';
773 /// let zero = b'0';
774 /// let percent = b'%';
775 /// let space = b' ';
776 /// let lf = b'\n';
777 /// let esc = b'\x1b';
778 ///
779 /// assert!(!uppercase_a.is_ascii_digit());
780 /// assert!(!uppercase_g.is_ascii_digit());
781 /// assert!(!a.is_ascii_digit());
782 /// assert!(!g.is_ascii_digit());
783 /// assert!(zero.is_ascii_digit());
784 /// assert!(!percent.is_ascii_digit());
785 /// assert!(!space.is_ascii_digit());
786 /// assert!(!lf.is_ascii_digit());
787 /// assert!(!esc.is_ascii_digit());
788 /// ```
789 #[must_use]
790 #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
791 #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
792 #[inline]
793 pub const fn is_ascii_digit(&self) -> bool {
794 matches!(*self, b'0'..=b'9')
795 }
796
797 /// Checks if the value is an ASCII octal digit:
798 /// U+0030 '0' ..= U+0037 '7'.
799 ///
800 /// # Examples
801 ///
802 /// ```
803 /// #![feature(is_ascii_octdigit)]
804 ///
805 /// let uppercase_a = b'A';
806 /// let a = b'a';
807 /// let zero = b'0';
808 /// let seven = b'7';
809 /// let nine = b'9';
810 /// let percent = b'%';
811 /// let lf = b'\n';
812 ///
813 /// assert!(!uppercase_a.is_ascii_octdigit());
814 /// assert!(!a.is_ascii_octdigit());
815 /// assert!(zero.is_ascii_octdigit());
816 /// assert!(seven.is_ascii_octdigit());
817 /// assert!(!nine.is_ascii_octdigit());
818 /// assert!(!percent.is_ascii_octdigit());
819 /// assert!(!lf.is_ascii_octdigit());
820 /// ```
821 #[must_use]
822 #[unstable(feature = "is_ascii_octdigit", issue = "101288")]
823 #[inline]
824 pub const fn is_ascii_octdigit(&self) -> bool {
825 matches!(*self, b'0'..=b'7')
826 }
827
828 /// Checks if the value is an ASCII hexadecimal digit:
829 ///
830 /// - U+0030 '0' ..= U+0039 '9', or
831 /// - U+0041 'A' ..= U+0046 'F', or
832 /// - U+0061 'a' ..= U+0066 'f'.
833 ///
834 /// # Examples
835 ///
836 /// ```
837 /// let uppercase_a = b'A';
838 /// let uppercase_g = b'G';
839 /// let a = b'a';
840 /// let g = b'g';
841 /// let zero = b'0';
842 /// let percent = b'%';
843 /// let space = b' ';
844 /// let lf = b'\n';
845 /// let esc = b'\x1b';
846 ///
847 /// assert!(uppercase_a.is_ascii_hexdigit());
848 /// assert!(!uppercase_g.is_ascii_hexdigit());
849 /// assert!(a.is_ascii_hexdigit());
850 /// assert!(!g.is_ascii_hexdigit());
851 /// assert!(zero.is_ascii_hexdigit());
852 /// assert!(!percent.is_ascii_hexdigit());
853 /// assert!(!space.is_ascii_hexdigit());
854 /// assert!(!lf.is_ascii_hexdigit());
855 /// assert!(!esc.is_ascii_hexdigit());
856 /// ```
857 #[must_use]
858 #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
859 #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
860 #[inline]
861 pub const fn is_ascii_hexdigit(&self) -> bool {
862 matches!(*self, b'0'..=b'9') | matches!(*self, b'A'..=b'F') | matches!(*self, b'a'..=b'f')
863 }
864
865 /// Checks if the value is an ASCII punctuation character:
866 ///
867 /// - U+0021 ..= U+002F `! " # $ % & ' ( ) * + , - . /`, or
868 /// - U+003A ..= U+0040 `: ; < = > ? @`, or
869 /// - U+005B ..= U+0060 `` [ \ ] ^ _ ` ``, or
870 /// - U+007B ..= U+007E `{ | } ~`
871 ///
872 /// # Examples
873 ///
874 /// ```
875 /// let uppercase_a = b'A';
876 /// let uppercase_g = b'G';
877 /// let a = b'a';
878 /// let g = b'g';
879 /// let zero = b'0';
880 /// let percent = b'%';
881 /// let space = b' ';
882 /// let lf = b'\n';
883 /// let esc = b'\x1b';
884 ///
885 /// assert!(!uppercase_a.is_ascii_punctuation());
886 /// assert!(!uppercase_g.is_ascii_punctuation());
887 /// assert!(!a.is_ascii_punctuation());
888 /// assert!(!g.is_ascii_punctuation());
889 /// assert!(!zero.is_ascii_punctuation());
890 /// assert!(percent.is_ascii_punctuation());
891 /// assert!(!space.is_ascii_punctuation());
892 /// assert!(!lf.is_ascii_punctuation());
893 /// assert!(!esc.is_ascii_punctuation());
894 /// ```
895 #[must_use]
896 #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
897 #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
898 #[inline]
899 pub const fn is_ascii_punctuation(&self) -> bool {
900 matches!(*self, b'!'..=b'/')
901 | matches!(*self, b':'..=b'@')
902 | matches!(*self, b'['..=b'`')
903 | matches!(*self, b'{'..=b'~')
904 }
905
906 /// Checks if the value is an ASCII graphic character:
907 /// U+0021 '!' ..= U+007E '~'.
908 ///
909 /// # Examples
910 ///
911 /// ```
912 /// let uppercase_a = b'A';
913 /// let uppercase_g = b'G';
914 /// let a = b'a';
915 /// let g = b'g';
916 /// let zero = b'0';
917 /// let percent = b'%';
918 /// let space = b' ';
919 /// let lf = b'\n';
920 /// let esc = b'\x1b';
921 ///
922 /// assert!(uppercase_a.is_ascii_graphic());
923 /// assert!(uppercase_g.is_ascii_graphic());
924 /// assert!(a.is_ascii_graphic());
925 /// assert!(g.is_ascii_graphic());
926 /// assert!(zero.is_ascii_graphic());
927 /// assert!(percent.is_ascii_graphic());
928 /// assert!(!space.is_ascii_graphic());
929 /// assert!(!lf.is_ascii_graphic());
930 /// assert!(!esc.is_ascii_graphic());
931 /// ```
932 #[must_use]
933 #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
934 #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
935 #[inline]
936 pub const fn is_ascii_graphic(&self) -> bool {
937 matches!(*self, b'!'..=b'~')
938 }
939
940 /// Checks if the value is an ASCII whitespace character:
941 /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED,
942 /// U+000C FORM FEED, or U+000D CARRIAGE RETURN.
943 ///
944 /// Rust uses the WhatWG Infra Standard's [definition of ASCII
945 /// whitespace][infra-aw]. There are several other definitions in
946 /// wide use. For instance, [the POSIX locale][pct] includes
947 /// U+000B VERTICAL TAB as well as all the above characters,
948 /// but—from the very same specification—[the default rule for
949 /// "field splitting" in the Bourne shell][bfs] considers *only*
950 /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
951 ///
952 /// If you are writing a program that will process an existing
953 /// file format, check what that format's definition of whitespace is
954 /// before using this function.
955 ///
956 /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
957 /// [pct]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
958 /// [bfs]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
959 ///
960 /// # Examples
961 ///
962 /// ```
963 /// let uppercase_a = b'A';
964 /// let uppercase_g = b'G';
965 /// let a = b'a';
966 /// let g = b'g';
967 /// let zero = b'0';
968 /// let percent = b'%';
969 /// let space = b' ';
970 /// let lf = b'\n';
971 /// let esc = b'\x1b';
972 ///
973 /// assert!(!uppercase_a.is_ascii_whitespace());
974 /// assert!(!uppercase_g.is_ascii_whitespace());
975 /// assert!(!a.is_ascii_whitespace());
976 /// assert!(!g.is_ascii_whitespace());
977 /// assert!(!zero.is_ascii_whitespace());
978 /// assert!(!percent.is_ascii_whitespace());
979 /// assert!(space.is_ascii_whitespace());
980 /// assert!(lf.is_ascii_whitespace());
981 /// assert!(!esc.is_ascii_whitespace());
982 /// ```
983 #[must_use]
984 #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
985 #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
986 #[inline]
987 pub const fn is_ascii_whitespace(&self) -> bool {
988 matches!(*self, b'\t' | b'\n' | b'\x0C' | b'\r' | b' ')
989 }
990
991 /// Checks if the value is an ASCII control character:
992 /// U+0000 NUL ..= U+001F UNIT SEPARATOR, or U+007F DELETE.
993 /// Note that most ASCII whitespace characters are control
994 /// characters, but SPACE is not.
995 ///
996 /// # Examples
997 ///
998 /// ```
999 /// let uppercase_a = b'A';
1000 /// let uppercase_g = b'G';
1001 /// let a = b'a';
1002 /// let g = b'g';
1003 /// let zero = b'0';
1004 /// let percent = b'%';
1005 /// let space = b' ';
1006 /// let lf = b'\n';
1007 /// let esc = b'\x1b';
1008 ///
1009 /// assert!(!uppercase_a.is_ascii_control());
1010 /// assert!(!uppercase_g.is_ascii_control());
1011 /// assert!(!a.is_ascii_control());
1012 /// assert!(!g.is_ascii_control());
1013 /// assert!(!zero.is_ascii_control());
1014 /// assert!(!percent.is_ascii_control());
1015 /// assert!(!space.is_ascii_control());
1016 /// assert!(lf.is_ascii_control());
1017 /// assert!(esc.is_ascii_control());
1018 /// ```
1019 #[must_use]
1020 #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1021 #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
1022 #[inline]
1023 pub const fn is_ascii_control(&self) -> bool {
1024 matches!(*self, b'\0'..=b'\x1F' | b'\x7F')
1025 }
1026
1027 /// Returns an iterator that produces an escaped version of a `u8`,
1028 /// treating it as an ASCII character.
1029 ///
1030 /// The behavior is identical to [`ascii::escape_default`].
1031 ///
1032 /// # Examples
1033 ///
1034 /// ```
1035 ///
1036 /// assert_eq!("0", b'0'.escape_ascii().to_string());
1037 /// assert_eq!("\\t", b'\t'.escape_ascii().to_string());
1038 /// assert_eq!("\\r", b'\r'.escape_ascii().to_string());
1039 /// assert_eq!("\\n", b'\n'.escape_ascii().to_string());
1040 /// assert_eq!("\\'", b'\''.escape_ascii().to_string());
1041 /// assert_eq!("\\\"", b'"'.escape_ascii().to_string());
1042 /// assert_eq!("\\\\", b'\\'.escape_ascii().to_string());
1043 /// assert_eq!("\\x9d", b'\x9d'.escape_ascii().to_string());
1044 /// ```
1045 #[must_use = "this returns the escaped byte as an iterator, \
1046 without modifying the original"]
1047 #[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
1048 #[inline]
1049 pub fn escape_ascii(self) -> ascii::EscapeDefault {
1050 ascii::escape_default(self)
1051 }
1052
1053 #[inline]
1054 pub(crate) const fn is_utf8_char_boundary(self) -> bool {
1055 // This is bit magic equivalent to: b < 128 || b >= 192
1056 (self as i8) >= -0x40
1057 }
1058}
1059
1060impl u16 {
1061 uint_impl! {
1062 Self = u16,
1063 ActualT = u16,
1064 SignedT = i16,
1065 BITS = 16,
1066 BITS_MINUS_ONE = 15,
1067 MAX = 65535,
1068 rot = 4,
1069 rot_op = "0xa003",
1070 rot_result = "0x3a",
1071 swap_op = "0x1234",
1072 swapped = "0x3412",
1073 reversed = "0x2c48",
1074 le_bytes = "[0x34, 0x12]",
1075 be_bytes = "[0x12, 0x34]",
1076 to_xe_bytes_doc = "",
1077 from_xe_bytes_doc = "",
1078 bound_condition = "",
1079 }
1080 midpoint_impl! { u16, u32, unsigned }
1081
1082 /// Checks if the value is a Unicode surrogate code point, which are disallowed values for [`char`].
1083 ///
1084 /// # Examples
1085 ///
1086 /// ```
1087 /// #![feature(utf16_extra)]
1088 ///
1089 /// let low_non_surrogate = 0xA000u16;
1090 /// let low_surrogate = 0xD800u16;
1091 /// let high_surrogate = 0xDC00u16;
1092 /// let high_non_surrogate = 0xE000u16;
1093 ///
1094 /// assert!(!low_non_surrogate.is_utf16_surrogate());
1095 /// assert!(low_surrogate.is_utf16_surrogate());
1096 /// assert!(high_surrogate.is_utf16_surrogate());
1097 /// assert!(!high_non_surrogate.is_utf16_surrogate());
1098 /// ```
1099 #[must_use]
1100 #[unstable(feature = "utf16_extra", issue = "94919")]
1101 #[inline]
1102 pub const fn is_utf16_surrogate(self) -> bool {
1103 matches!(self, 0xD800..=0xDFFF)
1104 }
1105}
1106
1107impl u32 {
1108 uint_impl! {
1109 Self = u32,
1110 ActualT = u32,
1111 SignedT = i32,
1112 BITS = 32,
1113 BITS_MINUS_ONE = 31,
1114 MAX = 4294967295,
1115 rot = 8,
1116 rot_op = "0x10000b3",
1117 rot_result = "0xb301",
1118 swap_op = "0x12345678",
1119 swapped = "0x78563412",
1120 reversed = "0x1e6a2c48",
1121 le_bytes = "[0x78, 0x56, 0x34, 0x12]",
1122 be_bytes = "[0x12, 0x34, 0x56, 0x78]",
1123 to_xe_bytes_doc = "",
1124 from_xe_bytes_doc = "",
1125 bound_condition = "",
1126 }
1127 midpoint_impl! { u32, u64, unsigned }
1128}
1129
1130impl u64 {
1131 uint_impl! {
1132 Self = u64,
1133 ActualT = u64,
1134 SignedT = i64,
1135 BITS = 64,
1136 BITS_MINUS_ONE = 63,
1137 MAX = 18446744073709551615,
1138 rot = 12,
1139 rot_op = "0xaa00000000006e1",
1140 rot_result = "0x6e10aa",
1141 swap_op = "0x1234567890123456",
1142 swapped = "0x5634129078563412",
1143 reversed = "0x6a2c48091e6a2c48",
1144 le_bytes = "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
1145 be_bytes = "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
1146 to_xe_bytes_doc = "",
1147 from_xe_bytes_doc = "",
1148 bound_condition = "",
1149 }
1150 midpoint_impl! { u64, u128, unsigned }
1151}
1152
1153impl u128 {
1154 uint_impl! {
1155 Self = u128,
1156 ActualT = u128,
1157 SignedT = i128,
1158 BITS = 128,
1159 BITS_MINUS_ONE = 127,
1160 MAX = 340282366920938463463374607431768211455,
1161 rot = 16,
1162 rot_op = "0x13f40000000000000000000000004f76",
1163 rot_result = "0x4f7613f4",
1164 swap_op = "0x12345678901234567890123456789012",
1165 swapped = "0x12907856341290785634129078563412",
1166 reversed = "0x48091e6a2c48091e6a2c48091e6a2c48",
1167 le_bytes = "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
1168 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
1169 be_bytes = "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
1170 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]",
1171 to_xe_bytes_doc = "",
1172 from_xe_bytes_doc = "",
1173 bound_condition = "",
1174 }
1175 midpoint_impl! { u128, unsigned }
1176}
1177
1178#[cfg(target_pointer_width = "16")]
1179impl usize {
1180 uint_impl! {
1181 Self = usize,
1182 ActualT = u16,
1183 SignedT = isize,
1184 BITS = 16,
1185 BITS_MINUS_ONE = 15,
1186 MAX = 65535,
1187 rot = 4,
1188 rot_op = "0xa003",
1189 rot_result = "0x3a",
1190 swap_op = "0x1234",
1191 swapped = "0x3412",
1192 reversed = "0x2c48",
1193 le_bytes = "[0x34, 0x12]",
1194 be_bytes = "[0x12, 0x34]",
1195 to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(),
1196 from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
1197 bound_condition = " on 16-bit targets",
1198 }
1199 midpoint_impl! { usize, u32, unsigned }
1200}
1201
1202#[cfg(target_pointer_width = "32")]
1203impl usize {
1204 uint_impl! {
1205 Self = usize,
1206 ActualT = u32,
1207 SignedT = isize,
1208 BITS = 32,
1209 BITS_MINUS_ONE = 31,
1210 MAX = 4294967295,
1211 rot = 8,
1212 rot_op = "0x10000b3",
1213 rot_result = "0xb301",
1214 swap_op = "0x12345678",
1215 swapped = "0x78563412",
1216 reversed = "0x1e6a2c48",
1217 le_bytes = "[0x78, 0x56, 0x34, 0x12]",
1218 be_bytes = "[0x12, 0x34, 0x56, 0x78]",
1219 to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(),
1220 from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
1221 bound_condition = " on 32-bit targets",
1222 }
1223 midpoint_impl! { usize, u64, unsigned }
1224}
1225
1226#[cfg(target_pointer_width = "64")]
1227impl usize {
1228 uint_impl! {
1229 Self = usize,
1230 ActualT = u64,
1231 SignedT = isize,
1232 BITS = 64,
1233 BITS_MINUS_ONE = 63,
1234 MAX = 18446744073709551615,
1235 rot = 12,
1236 rot_op = "0xaa00000000006e1",
1237 rot_result = "0x6e10aa",
1238 swap_op = "0x1234567890123456",
1239 swapped = "0x5634129078563412",
1240 reversed = "0x6a2c48091e6a2c48",
1241 le_bytes = "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
1242 be_bytes = "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
1243 to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(),
1244 from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
1245 bound_condition = " on 64-bit targets",
1246 }
1247 midpoint_impl! { usize, u128, unsigned }
1248}
1249
1250impl usize {
1251 /// Returns an `usize` where every byte is equal to `x`.
1252 #[inline]
1253 pub(crate) const fn repeat_u8(x: u8) -> usize {
1254 usize::from_ne_bytes([x; size_of::<usize>()])
1255 }
1256
1257 /// Returns an `usize` where every byte pair is equal to `x`.
1258 #[inline]
1259 pub(crate) const fn repeat_u16(x: u16) -> usize {
1260 let mut r = 0usize;
1261 let mut i = 0;
1262 while i < size_of::<usize>() {
1263 // Use `wrapping_shl` to make it work on targets with 16-bit `usize`
1264 r = r.wrapping_shl(16) | (x as usize);
1265 i += 2;
1266 }
1267 r
1268 }
1269}
1270
1271/// A classification of floating point numbers.
1272///
1273/// This `enum` is used as the return type for [`f32::classify`] and [`f64::classify`]. See
1274/// their documentation for more.
1275///
1276/// # Examples
1277///
1278/// ```
1279/// use std::num::FpCategory;
1280///
1281/// let num = 12.4_f32;
1282/// let inf = f32::INFINITY;
1283/// let zero = 0f32;
1284/// let sub: f32 = 1.1754942e-38;
1285/// let nan = f32::NAN;
1286///
1287/// assert_eq!(num.classify(), FpCategory::Normal);
1288/// assert_eq!(inf.classify(), FpCategory::Infinite);
1289/// assert_eq!(zero.classify(), FpCategory::Zero);
1290/// assert_eq!(sub.classify(), FpCategory::Subnormal);
1291/// assert_eq!(nan.classify(), FpCategory::Nan);
1292/// ```
1293#[derive(Copy, Clone, PartialEq, Eq, Debug)]
1294#[stable(feature = "rust1", since = "1.0.0")]
1295pub enum FpCategory {
1296 /// NaN (not a number): this value results from calculations like `(-1.0).sqrt()`.
1297 ///
1298 /// See [the documentation for `f32`](f32) for more information on the unusual properties
1299 /// of NaN.
1300 #[stable(feature = "rust1", since = "1.0.0")]
1301 Nan,
1302
1303 /// Positive or negative infinity, which often results from dividing a nonzero number
1304 /// by zero.
1305 #[stable(feature = "rust1", since = "1.0.0")]
1306 Infinite,
1307
1308 /// Positive or negative zero.
1309 ///
1310 /// See [the documentation for `f32`](f32) for more information on the signedness of zeroes.
1311 #[stable(feature = "rust1", since = "1.0.0")]
1312 Zero,
1313
1314 /// “Subnormal” or “denormal” floating point representation (less precise, relative to
1315 /// their magnitude, than [`Normal`]).
1316 ///
1317 /// Subnormal numbers are larger in magnitude than [`Zero`] but smaller in magnitude than all
1318 /// [`Normal`] numbers.
1319 ///
1320 /// [`Normal`]: Self::Normal
1321 /// [`Zero`]: Self::Zero
1322 #[stable(feature = "rust1", since = "1.0.0")]
1323 Subnormal,
1324
1325 /// A regular floating point number, not any of the exceptional categories.
1326 ///
1327 /// The smallest positive normal numbers are [`f32::MIN_POSITIVE`] and [`f64::MIN_POSITIVE`],
1328 /// and the largest positive normal numbers are [`f32::MAX`] and [`f64::MAX`]. (Unlike signed
1329 /// integers, floating point numbers are symmetric in their range, so negating any of these
1330 /// constants will produce their negative counterpart.)
1331 #[stable(feature = "rust1", since = "1.0.0")]
1332 Normal,
1333}
1334
1335/// Determines if a string of text of that length of that radix could be guaranteed to be
1336/// stored in the given type T.
1337/// Note that if the radix is known to the compiler, it is just the check of digits.len that
1338/// is done at runtime.
1339#[doc(hidden)]
1340#[inline(always)]
1341#[unstable(issue = "none", feature = "std_internals")]
1342pub const fn can_not_overflow<T>(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool {
1343 radix <= 16 && digits.len() <= size_of::<T>() * 2 - is_signed_ty as usize
1344}
1345
1346#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
1347#[cfg_attr(feature = "panic_immediate_abort", inline)]
1348#[cold]
1349#[track_caller]
1350const fn from_ascii_radix_panic(radix: u32) -> ! {
1351 const_panic!(
1352 "from_ascii_radix: radix must lie in the range `[2, 36]`",
1353 "from_ascii_radix: radix must lie in the range `[2, 36]` - found {radix}",
1354 radix: u32 = radix,
1355 )
1356}
1357
1358macro_rules! from_str_int_impl {
1359 ($signedness:ident $($int_ty:ty)+) => {$(
1360 #[stable(feature = "rust1", since = "1.0.0")]
1361 impl FromStr for $int_ty {
1362 type Err = ParseIntError;
1363
1364 /// Parses an integer from a string slice with decimal digits.
1365 ///
1366 /// The characters are expected to be an optional
1367 #[doc = sign_dependent_expr!{
1368 $signedness ?
1369 if signed {
1370 " `+` or `-` "
1371 }
1372 if unsigned {
1373 " `+` "
1374 }
1375 }]
1376 /// sign followed by only digits. Leading and trailing non-digit characters (including
1377 /// whitespace) represent an error. Underscores (which are accepted in Rust literals)
1378 /// also represent an error.
1379 ///
1380 /// # Examples
1381 ///
1382 /// Basic usage:
1383 /// ```
1384 /// use std::str::FromStr;
1385 ///
1386 #[doc = concat!("assert_eq!(", stringify!($int_ty), "::from_str(\"+10\"), Ok(10));")]
1387 /// ```
1388 /// Trailing space returns error:
1389 /// ```
1390 /// # use std::str::FromStr;
1391 /// #
1392 #[doc = concat!("assert!(", stringify!($int_ty), "::from_str(\"1 \").is_err());")]
1393 /// ```
1394 #[inline]
1395 fn from_str(src: &str) -> Result<$int_ty, ParseIntError> {
1396 <$int_ty>::from_str_radix(src, 10)
1397 }
1398 }
1399
1400 impl $int_ty {
1401 /// Parses an integer from a string slice with digits in a given base.
1402 ///
1403 /// The string is expected to be an optional
1404 #[doc = sign_dependent_expr!{
1405 $signedness ?
1406 if signed {
1407 " `+` or `-` "
1408 }
1409 if unsigned {
1410 " `+` "
1411 }
1412 }]
1413 /// sign followed by only digits. Leading and trailing non-digit characters (including
1414 /// whitespace) represent an error. Underscores (which are accepted in Rust literals)
1415 /// also represent an error.
1416 ///
1417 /// Digits are a subset of these characters, depending on `radix`:
1418 /// * `0-9`
1419 /// * `a-z`
1420 /// * `A-Z`
1421 ///
1422 /// # Panics
1423 ///
1424 /// This function panics if `radix` is not in the range from 2 to 36.
1425 ///
1426 /// # Examples
1427 ///
1428 /// Basic usage:
1429 /// ```
1430 #[doc = concat!("assert_eq!(", stringify!($int_ty), "::from_str_radix(\"A\", 16), Ok(10));")]
1431 /// ```
1432 /// Trailing space returns error:
1433 /// ```
1434 #[doc = concat!("assert!(", stringify!($int_ty), "::from_str_radix(\"1 \", 10).is_err());")]
1435 /// ```
1436 #[stable(feature = "rust1", since = "1.0.0")]
1437 #[rustc_const_stable(feature = "const_int_from_str", since = "1.82.0")]
1438 #[inline]
1439 pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
1440 <$int_ty>::from_ascii_radix(src.as_bytes(), radix)
1441 }
1442
1443 /// Parses an integer from an ASCII-byte slice with decimal digits.
1444 ///
1445 /// The characters are expected to be an optional
1446 #[doc = sign_dependent_expr!{
1447 $signedness ?
1448 if signed {
1449 " `+` or `-` "
1450 }
1451 if unsigned {
1452 " `+` "
1453 }
1454 }]
1455 /// sign followed by only digits. Leading and trailing non-digit characters (including
1456 /// whitespace) represent an error. Underscores (which are accepted in Rust literals)
1457 /// also represent an error.
1458 ///
1459 /// # Examples
1460 ///
1461 /// Basic usage:
1462 /// ```
1463 /// #![feature(int_from_ascii)]
1464 ///
1465 #[doc = concat!("assert_eq!(", stringify!($int_ty), "::from_ascii(b\"+10\"), Ok(10));")]
1466 /// ```
1467 /// Trailing space returns error:
1468 /// ```
1469 /// # #![feature(int_from_ascii)]
1470 /// #
1471 #[doc = concat!("assert!(", stringify!($int_ty), "::from_ascii(b\"1 \").is_err());")]
1472 /// ```
1473 #[unstable(feature = "int_from_ascii", issue = "134821")]
1474 #[inline]
1475 pub const fn from_ascii(src: &[u8]) -> Result<$int_ty, ParseIntError> {
1476 <$int_ty>::from_ascii_radix(src, 10)
1477 }
1478
1479 /// Parses an integer from an ASCII-byte slice with digits in a given base.
1480 ///
1481 /// The characters are expected to be an optional
1482 #[doc = sign_dependent_expr!{
1483 $signedness ?
1484 if signed {
1485 " `+` or `-` "
1486 }
1487 if unsigned {
1488 " `+` "
1489 }
1490 }]
1491 /// sign followed by only digits. Leading and trailing non-digit characters (including
1492 /// whitespace) represent an error. Underscores (which are accepted in Rust literals)
1493 /// also represent an error.
1494 ///
1495 /// Digits are a subset of these characters, depending on `radix`:
1496 /// * `0-9`
1497 /// * `a-z`
1498 /// * `A-Z`
1499 ///
1500 /// # Panics
1501 ///
1502 /// This function panics if `radix` is not in the range from 2 to 36.
1503 ///
1504 /// # Examples
1505 ///
1506 /// Basic usage:
1507 /// ```
1508 /// #![feature(int_from_ascii)]
1509 ///
1510 #[doc = concat!("assert_eq!(", stringify!($int_ty), "::from_ascii_radix(b\"A\", 16), Ok(10));")]
1511 /// ```
1512 /// Trailing space returns error:
1513 /// ```
1514 /// # #![feature(int_from_ascii)]
1515 /// #
1516 #[doc = concat!("assert!(", stringify!($int_ty), "::from_ascii_radix(b\"1 \", 10).is_err());")]
1517 /// ```
1518 #[unstable(feature = "int_from_ascii", issue = "134821")]
1519 #[inline]
1520 pub const fn from_ascii_radix(src: &[u8], radix: u32) -> Result<$int_ty, ParseIntError> {
1521 use self::IntErrorKind::*;
1522 use self::ParseIntError as PIE;
1523
1524 if 2 > radix || radix > 36 {
1525 from_ascii_radix_panic(radix);
1526 }
1527
1528 if src.is_empty() {
1529 return Err(PIE { kind: Empty });
1530 }
1531
1532 #[allow(unused_comparisons)]
1533 let is_signed_ty = 0 > <$int_ty>::MIN;
1534
1535 let (is_positive, mut digits) = match src {
1536 [b'+' | b'-'] => {
1537 return Err(PIE { kind: InvalidDigit });
1538 }
1539 [b'+', rest @ ..] => (true, rest),
1540 [b'-', rest @ ..] if is_signed_ty => (false, rest),
1541 _ => (true, src),
1542 };
1543
1544 let mut result = 0;
1545
1546 macro_rules! unwrap_or_PIE {
1547 ($option:expr, $kind:ident) => {
1548 match $option {
1549 Some(value) => value,
1550 None => return Err(PIE { kind: $kind }),
1551 }
1552 };
1553 }
1554
1555 if can_not_overflow::<$int_ty>(radix, is_signed_ty, digits) {
1556 // If the len of the str is short compared to the range of the type
1557 // we are parsing into, then we can be certain that an overflow will not occur.
1558 // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
1559 // above is a faster (conservative) approximation of this.
1560 //
1561 // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
1562 // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
1563 // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
1564 macro_rules! run_unchecked_loop {
1565 ($unchecked_additive_op:tt) => {{
1566 while let [c, rest @ ..] = digits {
1567 result = result * (radix as $int_ty);
1568 let x = unwrap_or_PIE!((*c as char).to_digit(radix), InvalidDigit);
1569 result = result $unchecked_additive_op (x as $int_ty);
1570 digits = rest;
1571 }
1572 }};
1573 }
1574 if is_positive {
1575 run_unchecked_loop!(+)
1576 } else {
1577 run_unchecked_loop!(-)
1578 };
1579 } else {
1580 macro_rules! run_checked_loop {
1581 ($checked_additive_op:ident, $overflow_err:ident) => {{
1582 while let [c, rest @ ..] = digits {
1583 // When `radix` is passed in as a literal, rather than doing a slow `imul`
1584 // the compiler can use shifts if `radix` can be expressed as a
1585 // sum of powers of 2 (x*10 can be written as x*8 + x*2).
1586 // When the compiler can't use these optimisations,
1587 // the latency of the multiplication can be hidden by issuing it
1588 // before the result is needed to improve performance on
1589 // modern out-of-order CPU as multiplication here is slower
1590 // than the other instructions, we can get the end result faster
1591 // doing multiplication first and let the CPU spends other cycles
1592 // doing other computation and get multiplication result later.
1593 let mul = result.checked_mul(radix as $int_ty);
1594 let x = unwrap_or_PIE!((*c as char).to_digit(radix), InvalidDigit) as $int_ty;
1595 result = unwrap_or_PIE!(mul, $overflow_err);
1596 result = unwrap_or_PIE!(<$int_ty>::$checked_additive_op(result, x), $overflow_err);
1597 digits = rest;
1598 }
1599 }};
1600 }
1601 if is_positive {
1602 run_checked_loop!(checked_add, PosOverflow)
1603 } else {
1604 run_checked_loop!(checked_sub, NegOverflow)
1605 };
1606 }
1607 Ok(result)
1608 }
1609 }
1610 )*}
1611}
1612
1613from_str_int_impl! { signed isize i8 i16 i32 i64 i128 }
1614from_str_int_impl! { unsigned usize u8 u16 u32 u64 u128 }