Skip to main content

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