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