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