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