core/num/
mod.rs

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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy