]> git.lizzy.rs Git - rust.git/blob - library/core/src/num/mod.rs
Rollup merge of #103315 - RalfJung:interpret-switchint-ice, r=bjorn3
[rust.git] / library / core / src / 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 use crate::ascii;
6 use crate::error::Error;
7 use crate::intrinsics;
8 use crate::mem;
9 use crate::ops::{Add, Mul, Sub};
10 use crate::str::FromStr;
11
12 // Used because the `?` operator is not allowed in a const context.
13 macro_rules! try_opt {
14     ($e:expr) => {
15         match $e {
16             Some(x) => x,
17             None => return None,
18         }
19     };
20 }
21
22 #[allow_internal_unstable(const_likely)]
23 macro_rules! unlikely {
24     ($e: expr) => {
25         intrinsics::unlikely($e)
26     };
27 }
28
29 // All these modules are technically private and only exposed for coretests:
30 #[cfg(not(no_fp_fmt_parse))]
31 pub mod bignum;
32 #[cfg(not(no_fp_fmt_parse))]
33 pub mod dec2flt;
34 #[cfg(not(no_fp_fmt_parse))]
35 pub mod diy_float;
36 #[cfg(not(no_fp_fmt_parse))]
37 pub mod flt2dec;
38 pub mod fmt;
39
40 #[macro_use]
41 mod int_macros; // import int_impl!
42 #[macro_use]
43 mod uint_macros; // import uint_impl!
44
45 mod error;
46 mod int_log10;
47 mod nonzero;
48 #[unstable(feature = "saturating_int_impl", issue = "87920")]
49 mod saturating;
50 mod wrapping;
51
52 #[unstable(feature = "saturating_int_impl", issue = "87920")]
53 pub use saturating::Saturating;
54 #[stable(feature = "rust1", since = "1.0.0")]
55 pub use wrapping::Wrapping;
56
57 #[stable(feature = "rust1", since = "1.0.0")]
58 #[cfg(not(no_fp_fmt_parse))]
59 pub use dec2flt::ParseFloatError;
60
61 #[cfg(not(no_fp_fmt_parse))]
62 #[stable(feature = "rust1", since = "1.0.0")]
63 impl Error for ParseFloatError {
64     #[allow(deprecated)]
65     fn description(&self) -> &str {
66         self.__description()
67     }
68 }
69
70 #[stable(feature = "rust1", since = "1.0.0")]
71 pub use error::ParseIntError;
72
73 #[stable(feature = "nonzero", since = "1.28.0")]
74 pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
75
76 #[stable(feature = "signed_nonzero", since = "1.34.0")]
77 pub use nonzero::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
78
79 #[stable(feature = "try_from", since = "1.34.0")]
80 pub use error::TryFromIntError;
81
82 #[stable(feature = "int_error_matching", since = "1.55.0")]
83 pub use error::IntErrorKind;
84
85 macro_rules! usize_isize_to_xe_bytes_doc {
86     () => {
87         "
88
89 **Note**: This function returns an array of length 2, 4 or 8 bytes
90 depending on the target pointer size.
91
92 "
93     };
94 }
95
96 macro_rules! usize_isize_from_xe_bytes_doc {
97     () => {
98         "
99
100 **Note**: This function takes an array of length 2, 4 or 8 bytes
101 depending on the target pointer size.
102
103 "
104     };
105 }
106
107 macro_rules! widening_impl {
108     ($SelfT:ty, $WideT:ty, $BITS:literal, unsigned) => {
109         /// Calculates the complete product `self * rhs` without the possibility to overflow.
110         ///
111         /// This returns the low-order (wrapping) bits and the high-order (overflow) bits
112         /// of the result as two separate values, in that order.
113         ///
114         /// If you also need to add a carry to the wide result, then you want
115         /// [`Self::carrying_mul`] instead.
116         ///
117         /// # Examples
118         ///
119         /// Basic usage:
120         ///
121         /// Please note that this example is shared between integer types.
122         /// Which explains why `u32` is used here.
123         ///
124         /// ```
125         /// #![feature(bigint_helper_methods)]
126         /// assert_eq!(5u32.widening_mul(2), (10, 0));
127         /// assert_eq!(1_000_000_000u32.widening_mul(10), (1410065408, 2));
128         /// ```
129         #[unstable(feature = "bigint_helper_methods", issue = "85532")]
130         #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")]
131         #[must_use = "this returns the result of the operation, \
132                       without modifying the original"]
133         #[inline]
134         pub const fn widening_mul(self, rhs: Self) -> (Self, Self) {
135             // note: longer-term this should be done via an intrinsic,
136             //   but for now we can deal without an impl for u128/i128
137             // SAFETY: overflow will be contained within the wider types
138             let wide = unsafe { (self as $WideT).unchecked_mul(rhs as $WideT) };
139             (wide as $SelfT, (wide >> $BITS) as $SelfT)
140         }
141
142         /// Calculates the "full multiplication" `self * rhs + carry`
143         /// without the possibility to overflow.
144         ///
145         /// This returns the low-order (wrapping) bits and the high-order (overflow) bits
146         /// of the result as two separate values, in that order.
147         ///
148         /// Performs "long multiplication" which takes in an extra amount to add, and may return an
149         /// additional amount of overflow. This allows for chaining together multiple
150         /// multiplications to create "big integers" which represent larger values.
151         ///
152         /// If you don't need the `carry`, then you can use [`Self::widening_mul`] instead.
153         ///
154         /// # Examples
155         ///
156         /// Basic usage:
157         ///
158         /// Please note that this example is shared between integer types.
159         /// Which explains why `u32` is used here.
160         ///
161         /// ```
162         /// #![feature(bigint_helper_methods)]
163         /// assert_eq!(5u32.carrying_mul(2, 0), (10, 0));
164         /// assert_eq!(5u32.carrying_mul(2, 10), (20, 0));
165         /// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2));
166         /// assert_eq!(1_000_000_000u32.carrying_mul(10, 10), (1410065418, 2));
167         #[doc = concat!("assert_eq!(",
168             stringify!($SelfT), "::MAX.carrying_mul(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ",
169             "(0, ", stringify!($SelfT), "::MAX));"
170         )]
171         /// ```
172         ///
173         /// This is the core operation needed for scalar multiplication when
174         /// implementing it for wider-than-native types.
175         ///
176         /// ```
177         /// #![feature(bigint_helper_methods)]
178         /// fn scalar_mul_eq(little_endian_digits: &mut Vec<u16>, multiplicand: u16) {
179         ///     let mut carry = 0;
180         ///     for d in little_endian_digits.iter_mut() {
181         ///         (*d, carry) = d.carrying_mul(multiplicand, carry);
182         ///     }
183         ///     if carry != 0 {
184         ///         little_endian_digits.push(carry);
185         ///     }
186         /// }
187         ///
188         /// let mut v = vec![10, 20];
189         /// scalar_mul_eq(&mut v, 3);
190         /// assert_eq!(v, [30, 60]);
191         ///
192         /// assert_eq!(0x87654321_u64 * 0xFEED, 0x86D3D159E38D);
193         /// let mut v = vec![0x4321, 0x8765];
194         /// scalar_mul_eq(&mut v, 0xFEED);
195         /// assert_eq!(v, [0xE38D, 0xD159, 0x86D3]);
196         /// ```
197         ///
198         /// If `carry` is zero, this is similar to [`overflowing_mul`](Self::overflowing_mul),
199         /// except that it gives the value of the overflow instead of just whether one happened:
200         ///
201         /// ```
202         /// #![feature(bigint_helper_methods)]
203         /// let r = u8::carrying_mul(7, 13, 0);
204         /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(7, 13));
205         /// let r = u8::carrying_mul(13, 42, 0);
206         /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(13, 42));
207         /// ```
208         ///
209         /// The value of the first field in the returned tuple matches what you'd get
210         /// by combining the [`wrapping_mul`](Self::wrapping_mul) and
211         /// [`wrapping_add`](Self::wrapping_add) methods:
212         ///
213         /// ```
214         /// #![feature(bigint_helper_methods)]
215         /// assert_eq!(
216         ///     789_u16.carrying_mul(456, 123).0,
217         ///     789_u16.wrapping_mul(456).wrapping_add(123),
218         /// );
219         /// ```
220         #[unstable(feature = "bigint_helper_methods", issue = "85532")]
221         #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
222         #[must_use = "this returns the result of the operation, \
223                       without modifying the original"]
224         #[inline]
225         pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) {
226             // note: longer-term this should be done via an intrinsic,
227             //   but for now we can deal without an impl for u128/i128
228             // SAFETY: overflow will be contained within the wider types
229             let wide = unsafe {
230                 (self as $WideT).unchecked_mul(rhs as $WideT).unchecked_add(carry as $WideT)
231             };
232             (wide as $SelfT, (wide >> $BITS) as $SelfT)
233         }
234     };
235 }
236
237 impl i8 {
238     int_impl! { i8, i8, u8, 8, 7, -128, 127, 2, "-0x7e", "0xa", "0x12", "0x12", "0x48",
239     "[0x12]", "[0x12]", "", "", "" }
240 }
241
242 impl i16 {
243     int_impl! { i16, i16, u16, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234", "0x3412",
244     "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", "", "", "" }
245 }
246
247 impl i32 {
248     int_impl! { i32, i32, u32, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
249     "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
250     "[0x12, 0x34, 0x56, 0x78]", "", "", "" }
251 }
252
253 impl i64 {
254     int_impl! { i64, i64, u64, 64, 63, -9223372036854775808, 9223372036854775807, 12,
255     "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412",
256     "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
257     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", "", "", "" }
258 }
259
260 impl i128 {
261     int_impl! { i128, i128, u128, 128, 127, -170141183460469231731687303715884105728,
262     170141183460469231731687303715884105727, 16,
263     "0x13f40000000000000000000000004f76", "0x4f7613f4", "0x12345678901234567890123456789012",
264     "0x12907856341290785634129078563412", "0x48091e6a2c48091e6a2c48091e6a2c48",
265     "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
266       0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
267     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
268       0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]", "", "", "" }
269 }
270
271 #[cfg(target_pointer_width = "16")]
272 impl isize {
273     int_impl! { isize, i16, usize, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234",
274     "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]",
275     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!(),
276     " on 16-bit targets" }
277 }
278
279 #[cfg(target_pointer_width = "32")]
280 impl isize {
281     int_impl! { isize, i32, usize, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
282     "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
283     "[0x12, 0x34, 0x56, 0x78]",
284     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!(),
285     " on 32-bit targets" }
286 }
287
288 #[cfg(target_pointer_width = "64")]
289 impl isize {
290     int_impl! { isize, i64, usize, 64, 63, -9223372036854775808, 9223372036854775807,
291     12, "0xaa00000000006e1", "0x6e10aa",  "0x1234567890123456", "0x5634129078563412",
292     "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
293     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
294     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!(),
295     " on 64-bit targets" }
296 }
297
298 /// If 6th bit set ascii is upper case.
299 const ASCII_CASE_MASK: u8 = 0b0010_0000;
300
301 impl u8 {
302     uint_impl! { u8, u8, i8, NonZeroU8, 8, 255, 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]",
303     "[0x12]", "", "", "" }
304     widening_impl! { u8, u16, 8, unsigned }
305
306     /// Checks if the value is within the ASCII range.
307     ///
308     /// # Examples
309     ///
310     /// ```
311     /// let ascii = 97u8;
312     /// let non_ascii = 150u8;
313     ///
314     /// assert!(ascii.is_ascii());
315     /// assert!(!non_ascii.is_ascii());
316     /// ```
317     #[must_use]
318     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
319     #[rustc_const_stable(feature = "const_u8_is_ascii", since = "1.43.0")]
320     #[inline]
321     pub const fn is_ascii(&self) -> bool {
322         *self & 128 == 0
323     }
324
325     /// Makes a copy of the value in its ASCII upper case equivalent.
326     ///
327     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
328     /// but non-ASCII letters are unchanged.
329     ///
330     /// To uppercase the value in-place, use [`make_ascii_uppercase`].
331     ///
332     /// # Examples
333     ///
334     /// ```
335     /// let lowercase_a = 97u8;
336     ///
337     /// assert_eq!(65, lowercase_a.to_ascii_uppercase());
338     /// ```
339     ///
340     /// [`make_ascii_uppercase`]: Self::make_ascii_uppercase
341     #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase()`"]
342     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
343     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
344     #[inline]
345     pub const fn to_ascii_uppercase(&self) -> u8 {
346         // Toggle the fifth bit if this is a lowercase letter
347         *self ^ ((self.is_ascii_lowercase() as u8) * ASCII_CASE_MASK)
348     }
349
350     /// Makes a copy of the value in its ASCII lower case equivalent.
351     ///
352     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
353     /// but non-ASCII letters are unchanged.
354     ///
355     /// To lowercase the value in-place, use [`make_ascii_lowercase`].
356     ///
357     /// # Examples
358     ///
359     /// ```
360     /// let uppercase_a = 65u8;
361     ///
362     /// assert_eq!(97, uppercase_a.to_ascii_lowercase());
363     /// ```
364     ///
365     /// [`make_ascii_lowercase`]: Self::make_ascii_lowercase
366     #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"]
367     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
368     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
369     #[inline]
370     pub const fn to_ascii_lowercase(&self) -> u8 {
371         // Set the fifth bit if this is an uppercase letter
372         *self | (self.is_ascii_uppercase() as u8 * ASCII_CASE_MASK)
373     }
374
375     /// Assumes self is ascii
376     #[inline]
377     pub(crate) const fn ascii_change_case_unchecked(&self) -> u8 {
378         *self ^ ASCII_CASE_MASK
379     }
380
381     /// Checks that two values are an ASCII case-insensitive match.
382     ///
383     /// This is equivalent to `to_ascii_lowercase(a) == to_ascii_lowercase(b)`.
384     ///
385     /// # Examples
386     ///
387     /// ```
388     /// let lowercase_a = 97u8;
389     /// let uppercase_a = 65u8;
390     ///
391     /// assert!(lowercase_a.eq_ignore_ascii_case(&uppercase_a));
392     /// ```
393     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
394     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
395     #[inline]
396     pub const fn eq_ignore_ascii_case(&self, other: &u8) -> bool {
397         self.to_ascii_lowercase() == other.to_ascii_lowercase()
398     }
399
400     /// Converts this value to its ASCII upper case equivalent in-place.
401     ///
402     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
403     /// but non-ASCII letters are unchanged.
404     ///
405     /// To return a new uppercased value without modifying the existing one, use
406     /// [`to_ascii_uppercase`].
407     ///
408     /// # Examples
409     ///
410     /// ```
411     /// let mut byte = b'a';
412     ///
413     /// byte.make_ascii_uppercase();
414     ///
415     /// assert_eq!(b'A', byte);
416     /// ```
417     ///
418     /// [`to_ascii_uppercase`]: Self::to_ascii_uppercase
419     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
420     #[inline]
421     pub fn make_ascii_uppercase(&mut self) {
422         *self = self.to_ascii_uppercase();
423     }
424
425     /// Converts this value to its ASCII lower case equivalent in-place.
426     ///
427     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
428     /// but non-ASCII letters are unchanged.
429     ///
430     /// To return a new lowercased value without modifying the existing one, use
431     /// [`to_ascii_lowercase`].
432     ///
433     /// # Examples
434     ///
435     /// ```
436     /// let mut byte = b'A';
437     ///
438     /// byte.make_ascii_lowercase();
439     ///
440     /// assert_eq!(b'a', byte);
441     /// ```
442     ///
443     /// [`to_ascii_lowercase`]: Self::to_ascii_lowercase
444     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
445     #[inline]
446     pub fn make_ascii_lowercase(&mut self) {
447         *self = self.to_ascii_lowercase();
448     }
449
450     /// Checks if the value is an ASCII alphabetic character:
451     ///
452     /// - U+0041 'A' ..= U+005A 'Z', or
453     /// - U+0061 'a' ..= U+007A 'z'.
454     ///
455     /// # Examples
456     ///
457     /// ```
458     /// let uppercase_a = b'A';
459     /// let uppercase_g = b'G';
460     /// let a = b'a';
461     /// let g = b'g';
462     /// let zero = b'0';
463     /// let percent = b'%';
464     /// let space = b' ';
465     /// let lf = b'\n';
466     /// let esc = b'\x1b';
467     ///
468     /// assert!(uppercase_a.is_ascii_alphabetic());
469     /// assert!(uppercase_g.is_ascii_alphabetic());
470     /// assert!(a.is_ascii_alphabetic());
471     /// assert!(g.is_ascii_alphabetic());
472     /// assert!(!zero.is_ascii_alphabetic());
473     /// assert!(!percent.is_ascii_alphabetic());
474     /// assert!(!space.is_ascii_alphabetic());
475     /// assert!(!lf.is_ascii_alphabetic());
476     /// assert!(!esc.is_ascii_alphabetic());
477     /// ```
478     #[must_use]
479     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
480     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
481     #[inline]
482     pub const fn is_ascii_alphabetic(&self) -> bool {
483         matches!(*self, b'A'..=b'Z' | b'a'..=b'z')
484     }
485
486     /// Checks if the value is an ASCII uppercase character:
487     /// U+0041 'A' ..= U+005A 'Z'.
488     ///
489     /// # Examples
490     ///
491     /// ```
492     /// let uppercase_a = b'A';
493     /// let uppercase_g = b'G';
494     /// let a = b'a';
495     /// let g = b'g';
496     /// let zero = b'0';
497     /// let percent = b'%';
498     /// let space = b' ';
499     /// let lf = b'\n';
500     /// let esc = b'\x1b';
501     ///
502     /// assert!(uppercase_a.is_ascii_uppercase());
503     /// assert!(uppercase_g.is_ascii_uppercase());
504     /// assert!(!a.is_ascii_uppercase());
505     /// assert!(!g.is_ascii_uppercase());
506     /// assert!(!zero.is_ascii_uppercase());
507     /// assert!(!percent.is_ascii_uppercase());
508     /// assert!(!space.is_ascii_uppercase());
509     /// assert!(!lf.is_ascii_uppercase());
510     /// assert!(!esc.is_ascii_uppercase());
511     /// ```
512     #[must_use]
513     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
514     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
515     #[inline]
516     pub const fn is_ascii_uppercase(&self) -> bool {
517         matches!(*self, b'A'..=b'Z')
518     }
519
520     /// Checks if the value is an ASCII lowercase character:
521     /// U+0061 'a' ..= U+007A 'z'.
522     ///
523     /// # Examples
524     ///
525     /// ```
526     /// let uppercase_a = b'A';
527     /// let uppercase_g = b'G';
528     /// let a = b'a';
529     /// let g = b'g';
530     /// let zero = b'0';
531     /// let percent = b'%';
532     /// let space = b' ';
533     /// let lf = b'\n';
534     /// let esc = b'\x1b';
535     ///
536     /// assert!(!uppercase_a.is_ascii_lowercase());
537     /// assert!(!uppercase_g.is_ascii_lowercase());
538     /// assert!(a.is_ascii_lowercase());
539     /// assert!(g.is_ascii_lowercase());
540     /// assert!(!zero.is_ascii_lowercase());
541     /// assert!(!percent.is_ascii_lowercase());
542     /// assert!(!space.is_ascii_lowercase());
543     /// assert!(!lf.is_ascii_lowercase());
544     /// assert!(!esc.is_ascii_lowercase());
545     /// ```
546     #[must_use]
547     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
548     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
549     #[inline]
550     pub const fn is_ascii_lowercase(&self) -> bool {
551         matches!(*self, b'a'..=b'z')
552     }
553
554     /// Checks if the value is an ASCII alphanumeric character:
555     ///
556     /// - U+0041 'A' ..= U+005A 'Z', or
557     /// - U+0061 'a' ..= U+007A 'z', or
558     /// - U+0030 '0' ..= U+0039 '9'.
559     ///
560     /// # Examples
561     ///
562     /// ```
563     /// let uppercase_a = b'A';
564     /// let uppercase_g = b'G';
565     /// let a = b'a';
566     /// let g = b'g';
567     /// let zero = b'0';
568     /// let percent = b'%';
569     /// let space = b' ';
570     /// let lf = b'\n';
571     /// let esc = b'\x1b';
572     ///
573     /// assert!(uppercase_a.is_ascii_alphanumeric());
574     /// assert!(uppercase_g.is_ascii_alphanumeric());
575     /// assert!(a.is_ascii_alphanumeric());
576     /// assert!(g.is_ascii_alphanumeric());
577     /// assert!(zero.is_ascii_alphanumeric());
578     /// assert!(!percent.is_ascii_alphanumeric());
579     /// assert!(!space.is_ascii_alphanumeric());
580     /// assert!(!lf.is_ascii_alphanumeric());
581     /// assert!(!esc.is_ascii_alphanumeric());
582     /// ```
583     #[must_use]
584     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
585     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
586     #[inline]
587     pub const fn is_ascii_alphanumeric(&self) -> bool {
588         matches!(*self, b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z')
589     }
590
591     /// Checks if the value is an ASCII decimal digit:
592     /// U+0030 '0' ..= U+0039 '9'.
593     ///
594     /// # Examples
595     ///
596     /// ```
597     /// let uppercase_a = b'A';
598     /// let uppercase_g = b'G';
599     /// let a = b'a';
600     /// let g = b'g';
601     /// let zero = b'0';
602     /// let percent = b'%';
603     /// let space = b' ';
604     /// let lf = b'\n';
605     /// let esc = b'\x1b';
606     ///
607     /// assert!(!uppercase_a.is_ascii_digit());
608     /// assert!(!uppercase_g.is_ascii_digit());
609     /// assert!(!a.is_ascii_digit());
610     /// assert!(!g.is_ascii_digit());
611     /// assert!(zero.is_ascii_digit());
612     /// assert!(!percent.is_ascii_digit());
613     /// assert!(!space.is_ascii_digit());
614     /// assert!(!lf.is_ascii_digit());
615     /// assert!(!esc.is_ascii_digit());
616     /// ```
617     #[must_use]
618     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
619     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
620     #[inline]
621     pub const fn is_ascii_digit(&self) -> bool {
622         matches!(*self, b'0'..=b'9')
623     }
624
625     /// Checks if the value is an ASCII octal digit:
626     /// U+0030 '0' ..= U+0037 '7'.
627     ///
628     /// # Examples
629     ///
630     /// ```
631     /// #![feature(is_ascii_octdigit)]
632     ///
633     /// let uppercase_a = b'A';
634     /// let a = b'a';
635     /// let zero = b'0';
636     /// let seven = b'7';
637     /// let nine = b'9';
638     /// let percent = b'%';
639     /// let lf = b'\n';
640     ///
641     /// assert!(!uppercase_a.is_ascii_octdigit());
642     /// assert!(!a.is_ascii_octdigit());
643     /// assert!(zero.is_ascii_octdigit());
644     /// assert!(seven.is_ascii_octdigit());
645     /// assert!(!nine.is_ascii_octdigit());
646     /// assert!(!percent.is_ascii_octdigit());
647     /// assert!(!lf.is_ascii_octdigit());
648     /// ```
649     #[must_use]
650     #[unstable(feature = "is_ascii_octdigit", issue = "101288")]
651     #[rustc_const_unstable(feature = "is_ascii_octdigit", issue = "101288")]
652     #[inline]
653     pub const fn is_ascii_octdigit(&self) -> bool {
654         matches!(*self, b'0'..=b'7')
655     }
656
657     /// Checks if the value is an ASCII hexadecimal digit:
658     ///
659     /// - U+0030 '0' ..= U+0039 '9', or
660     /// - U+0041 'A' ..= U+0046 'F', or
661     /// - U+0061 'a' ..= U+0066 'f'.
662     ///
663     /// # Examples
664     ///
665     /// ```
666     /// let uppercase_a = b'A';
667     /// let uppercase_g = b'G';
668     /// let a = b'a';
669     /// let g = b'g';
670     /// let zero = b'0';
671     /// let percent = b'%';
672     /// let space = b' ';
673     /// let lf = b'\n';
674     /// let esc = b'\x1b';
675     ///
676     /// assert!(uppercase_a.is_ascii_hexdigit());
677     /// assert!(!uppercase_g.is_ascii_hexdigit());
678     /// assert!(a.is_ascii_hexdigit());
679     /// assert!(!g.is_ascii_hexdigit());
680     /// assert!(zero.is_ascii_hexdigit());
681     /// assert!(!percent.is_ascii_hexdigit());
682     /// assert!(!space.is_ascii_hexdigit());
683     /// assert!(!lf.is_ascii_hexdigit());
684     /// assert!(!esc.is_ascii_hexdigit());
685     /// ```
686     #[must_use]
687     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
688     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
689     #[inline]
690     pub const fn is_ascii_hexdigit(&self) -> bool {
691         matches!(*self, b'0'..=b'9' | b'A'..=b'F' | b'a'..=b'f')
692     }
693
694     /// Checks if the value is an ASCII punctuation character:
695     ///
696     /// - U+0021 ..= U+002F `! " # $ % & ' ( ) * + , - . /`, or
697     /// - U+003A ..= U+0040 `: ; < = > ? @`, or
698     /// - U+005B ..= U+0060 `` [ \ ] ^ _ ` ``, or
699     /// - U+007B ..= U+007E `{ | } ~`
700     ///
701     /// # Examples
702     ///
703     /// ```
704     /// let uppercase_a = b'A';
705     /// let uppercase_g = b'G';
706     /// let a = b'a';
707     /// let g = b'g';
708     /// let zero = b'0';
709     /// let percent = b'%';
710     /// let space = b' ';
711     /// let lf = b'\n';
712     /// let esc = b'\x1b';
713     ///
714     /// assert!(!uppercase_a.is_ascii_punctuation());
715     /// assert!(!uppercase_g.is_ascii_punctuation());
716     /// assert!(!a.is_ascii_punctuation());
717     /// assert!(!g.is_ascii_punctuation());
718     /// assert!(!zero.is_ascii_punctuation());
719     /// assert!(percent.is_ascii_punctuation());
720     /// assert!(!space.is_ascii_punctuation());
721     /// assert!(!lf.is_ascii_punctuation());
722     /// assert!(!esc.is_ascii_punctuation());
723     /// ```
724     #[must_use]
725     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
726     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
727     #[inline]
728     pub const fn is_ascii_punctuation(&self) -> bool {
729         matches!(*self, b'!'..=b'/' | b':'..=b'@' | b'['..=b'`' | b'{'..=b'~')
730     }
731
732     /// Checks if the value is an ASCII graphic character:
733     /// U+0021 '!' ..= U+007E '~'.
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_graphic());
749     /// assert!(uppercase_g.is_ascii_graphic());
750     /// assert!(a.is_ascii_graphic());
751     /// assert!(g.is_ascii_graphic());
752     /// assert!(zero.is_ascii_graphic());
753     /// assert!(percent.is_ascii_graphic());
754     /// assert!(!space.is_ascii_graphic());
755     /// assert!(!lf.is_ascii_graphic());
756     /// assert!(!esc.is_ascii_graphic());
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     pub const fn is_ascii_graphic(&self) -> bool {
763         matches!(*self, b'!'..=b'~')
764     }
765
766     /// Checks if the value is an ASCII whitespace character:
767     /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED,
768     /// U+000C FORM FEED, or U+000D CARRIAGE RETURN.
769     ///
770     /// Rust uses the WhatWG Infra Standard's [definition of ASCII
771     /// whitespace][infra-aw]. There are several other definitions in
772     /// wide use. For instance, [the POSIX locale][pct] includes
773     /// U+000B VERTICAL TAB as well as all the above characters,
774     /// but—from the very same specification—[the default rule for
775     /// "field splitting" in the Bourne shell][bfs] considers *only*
776     /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
777     ///
778     /// If you are writing a program that will process an existing
779     /// file format, check what that format's definition of whitespace is
780     /// before using this function.
781     ///
782     /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
783     /// [pct]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
784     /// [bfs]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
785     ///
786     /// # Examples
787     ///
788     /// ```
789     /// let uppercase_a = b'A';
790     /// let uppercase_g = b'G';
791     /// let a = b'a';
792     /// let g = b'g';
793     /// let zero = b'0';
794     /// let percent = b'%';
795     /// let space = b' ';
796     /// let lf = b'\n';
797     /// let esc = b'\x1b';
798     ///
799     /// assert!(!uppercase_a.is_ascii_whitespace());
800     /// assert!(!uppercase_g.is_ascii_whitespace());
801     /// assert!(!a.is_ascii_whitespace());
802     /// assert!(!g.is_ascii_whitespace());
803     /// assert!(!zero.is_ascii_whitespace());
804     /// assert!(!percent.is_ascii_whitespace());
805     /// assert!(space.is_ascii_whitespace());
806     /// assert!(lf.is_ascii_whitespace());
807     /// assert!(!esc.is_ascii_whitespace());
808     /// ```
809     #[must_use]
810     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
811     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
812     #[inline]
813     pub const fn is_ascii_whitespace(&self) -> bool {
814         matches!(*self, b'\t' | b'\n' | b'\x0C' | b'\r' | b' ')
815     }
816
817     /// Checks if the value is an ASCII control character:
818     /// U+0000 NUL ..= U+001F UNIT SEPARATOR, or U+007F DELETE.
819     /// Note that most ASCII whitespace characters are control
820     /// characters, but SPACE is not.
821     ///
822     /// # Examples
823     ///
824     /// ```
825     /// let uppercase_a = b'A';
826     /// let uppercase_g = b'G';
827     /// let a = b'a';
828     /// let g = b'g';
829     /// let zero = b'0';
830     /// let percent = b'%';
831     /// let space = b' ';
832     /// let lf = b'\n';
833     /// let esc = b'\x1b';
834     ///
835     /// assert!(!uppercase_a.is_ascii_control());
836     /// assert!(!uppercase_g.is_ascii_control());
837     /// assert!(!a.is_ascii_control());
838     /// assert!(!g.is_ascii_control());
839     /// assert!(!zero.is_ascii_control());
840     /// assert!(!percent.is_ascii_control());
841     /// assert!(!space.is_ascii_control());
842     /// assert!(lf.is_ascii_control());
843     /// assert!(esc.is_ascii_control());
844     /// ```
845     #[must_use]
846     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
847     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
848     #[inline]
849     pub const fn is_ascii_control(&self) -> bool {
850         matches!(*self, b'\0'..=b'\x1F' | b'\x7F')
851     }
852
853     /// Returns an iterator that produces an escaped version of a `u8`,
854     /// treating it as an ASCII character.
855     ///
856     /// The behavior is identical to [`ascii::escape_default`].
857     ///
858     /// # Examples
859     ///
860     /// ```
861     ///
862     /// assert_eq!("0", b'0'.escape_ascii().to_string());
863     /// assert_eq!("\\t", b'\t'.escape_ascii().to_string());
864     /// assert_eq!("\\r", b'\r'.escape_ascii().to_string());
865     /// assert_eq!("\\n", b'\n'.escape_ascii().to_string());
866     /// assert_eq!("\\'", b'\''.escape_ascii().to_string());
867     /// assert_eq!("\\\"", b'"'.escape_ascii().to_string());
868     /// assert_eq!("\\\\", b'\\'.escape_ascii().to_string());
869     /// assert_eq!("\\x9d", b'\x9d'.escape_ascii().to_string());
870     /// ```
871     #[must_use = "this returns the escaped byte as an iterator, \
872                   without modifying the original"]
873     #[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
874     #[inline]
875     pub fn escape_ascii(self) -> ascii::EscapeDefault {
876         ascii::escape_default(self)
877     }
878
879     #[inline]
880     pub(crate) const fn is_utf8_char_boundary(self) -> bool {
881         // This is bit magic equivalent to: b < 128 || b >= 192
882         (self as i8) >= -0x40
883     }
884 }
885
886 impl u16 {
887     uint_impl! { u16, u16, i16, NonZeroU16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
888     "[0x34, 0x12]", "[0x12, 0x34]", "", "", "" }
889     widening_impl! { u16, u32, 16, unsigned }
890
891     /// Checks if the value is a Unicode surrogate code point, which are disallowed values for [`char`].
892     ///
893     /// # Examples
894     ///
895     /// ```
896     /// #![feature(utf16_extra)]
897     ///
898     /// let low_non_surrogate = 0xA000u16;
899     /// let low_surrogate = 0xD800u16;
900     /// let high_surrogate = 0xDC00u16;
901     /// let high_non_surrogate = 0xE000u16;
902     ///
903     /// assert!(!low_non_surrogate.is_utf16_surrogate());
904     /// assert!(low_surrogate.is_utf16_surrogate());
905     /// assert!(high_surrogate.is_utf16_surrogate());
906     /// assert!(!high_non_surrogate.is_utf16_surrogate());
907     /// ```
908     #[must_use]
909     #[unstable(feature = "utf16_extra", issue = "94919")]
910     #[rustc_const_unstable(feature = "utf16_extra_const", issue = "94919")]
911     #[inline]
912     pub const fn is_utf16_surrogate(self) -> bool {
913         matches!(self, 0xD800..=0xDFFF)
914     }
915 }
916
917 impl u32 {
918     uint_impl! { u32, u32, i32, NonZeroU32, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
919     "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", "", "", "" }
920     widening_impl! { u32, u64, 32, unsigned }
921 }
922
923 impl u64 {
924     uint_impl! { u64, u64, i64, NonZeroU64, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
925     "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
926     "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
927     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
928     "", "", ""}
929     widening_impl! { u64, u128, 64, unsigned }
930 }
931
932 impl u128 {
933     uint_impl! { u128, u128, i128, NonZeroU128, 128, 340282366920938463463374607431768211455, 16,
934     "0x13f40000000000000000000000004f76", "0x4f7613f4", "0x12345678901234567890123456789012",
935     "0x12907856341290785634129078563412", "0x48091e6a2c48091e6a2c48091e6a2c48",
936     "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
937       0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
938     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
939       0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]",
940      "", "", ""}
941 }
942
943 #[cfg(target_pointer_width = "16")]
944 impl usize {
945     uint_impl! { usize, u16, isize, NonZeroUsize, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
946     "[0x34, 0x12]", "[0x12, 0x34]",
947     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!(),
948     " on 16-bit targets" }
949     widening_impl! { usize, u32, 16, unsigned }
950 }
951 #[cfg(target_pointer_width = "32")]
952 impl usize {
953     uint_impl! { usize, u32, isize, NonZeroUsize, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
954     "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]",
955     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!(),
956     " on 32-bit targets" }
957     widening_impl! { usize, u64, 32, unsigned }
958 }
959
960 #[cfg(target_pointer_width = "64")]
961 impl usize {
962     uint_impl! { usize, u64, isize, NonZeroUsize, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
963     "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
964     "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
965     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
966     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!(),
967     " on 64-bit targets" }
968     widening_impl! { usize, u128, 64, unsigned }
969 }
970
971 impl usize {
972     /// Returns an `usize` where every byte is equal to `x`.
973     #[inline]
974     pub(crate) const fn repeat_u8(x: u8) -> usize {
975         usize::from_ne_bytes([x; mem::size_of::<usize>()])
976     }
977
978     /// Returns an `usize` where every byte pair is equal to `x`.
979     #[inline]
980     pub(crate) const fn repeat_u16(x: u16) -> usize {
981         let mut r = 0usize;
982         let mut i = 0;
983         while i < mem::size_of::<usize>() {
984             // Use `wrapping_shl` to make it work on targets with 16-bit `usize`
985             r = r.wrapping_shl(16) | (x as usize);
986             i += 2;
987         }
988         r
989     }
990 }
991
992 /// A classification of floating point numbers.
993 ///
994 /// This `enum` is used as the return type for [`f32::classify`] and [`f64::classify`]. See
995 /// their documentation for more.
996 ///
997 /// # Examples
998 ///
999 /// ```
1000 /// use std::num::FpCategory;
1001 ///
1002 /// let num = 12.4_f32;
1003 /// let inf = f32::INFINITY;
1004 /// let zero = 0f32;
1005 /// let sub: f32 = 1.1754942e-38;
1006 /// let nan = f32::NAN;
1007 ///
1008 /// assert_eq!(num.classify(), FpCategory::Normal);
1009 /// assert_eq!(inf.classify(), FpCategory::Infinite);
1010 /// assert_eq!(zero.classify(), FpCategory::Zero);
1011 /// assert_eq!(sub.classify(), FpCategory::Subnormal);
1012 /// assert_eq!(nan.classify(), FpCategory::Nan);
1013 /// ```
1014 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
1015 #[stable(feature = "rust1", since = "1.0.0")]
1016 pub enum FpCategory {
1017     /// NaN (not a number): this value results from calculations like `(-1.0).sqrt()`.
1018     ///
1019     /// See [the documentation for `f32`](f32) for more information on the unusual properties
1020     /// of NaN.
1021     #[stable(feature = "rust1", since = "1.0.0")]
1022     Nan,
1023
1024     /// Positive or negative infinity, which often results from dividing a nonzero number
1025     /// by zero.
1026     #[stable(feature = "rust1", since = "1.0.0")]
1027     Infinite,
1028
1029     /// Positive or negative zero.
1030     ///
1031     /// See [the documentation for `f32`](f32) for more information on the signedness of zeroes.
1032     #[stable(feature = "rust1", since = "1.0.0")]
1033     Zero,
1034
1035     /// “Subnormal” or “denormal” floating point representation (less precise, relative to
1036     /// their magnitude, than [`Normal`]).
1037     ///
1038     /// Subnormal numbers are larger in magnitude than [`Zero`] but smaller in magnitude than all
1039     /// [`Normal`] numbers.
1040     ///
1041     /// [`Normal`]: Self::Normal
1042     /// [`Zero`]: Self::Zero
1043     #[stable(feature = "rust1", since = "1.0.0")]
1044     Subnormal,
1045
1046     /// A regular floating point number, not any of the exceptional categories.
1047     ///
1048     /// The smallest positive normal numbers are [`f32::MIN_POSITIVE`] and [`f64::MIN_POSITIVE`],
1049     /// and the largest positive normal numbers are [`f32::MAX`] and [`f64::MAX`]. (Unlike signed
1050     /// integers, floating point numbers are symmetric in their range, so negating any of these
1051     /// constants will produce their negative counterpart.)
1052     #[stable(feature = "rust1", since = "1.0.0")]
1053     Normal,
1054 }
1055
1056 #[doc(hidden)]
1057 trait FromStrRadixHelper:
1058     PartialOrd + Copy + Add<Output = Self> + Sub<Output = Self> + Mul<Output = Self>
1059 {
1060     const MIN: Self;
1061     fn from_u32(u: u32) -> Self;
1062     fn checked_mul(&self, other: u32) -> Option<Self>;
1063     fn checked_sub(&self, other: u32) -> Option<Self>;
1064     fn checked_add(&self, other: u32) -> Option<Self>;
1065 }
1066
1067 macro_rules! from_str_radix_int_impl {
1068     ($($t:ty)*) => {$(
1069         #[stable(feature = "rust1", since = "1.0.0")]
1070         impl FromStr for $t {
1071             type Err = ParseIntError;
1072             fn from_str(src: &str) -> Result<Self, ParseIntError> {
1073                 from_str_radix(src, 10)
1074             }
1075         }
1076     )*}
1077 }
1078 from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }
1079
1080 macro_rules! impl_helper_for {
1081     ($($t:ty)*) => ($(impl FromStrRadixHelper for $t {
1082         const MIN: Self = Self::MIN;
1083         #[inline]
1084         fn from_u32(u: u32) -> Self { u as Self }
1085         #[inline]
1086         fn checked_mul(&self, other: u32) -> Option<Self> {
1087             Self::checked_mul(*self, other as Self)
1088         }
1089         #[inline]
1090         fn checked_sub(&self, other: u32) -> Option<Self> {
1091             Self::checked_sub(*self, other as Self)
1092         }
1093         #[inline]
1094         fn checked_add(&self, other: u32) -> Option<Self> {
1095             Self::checked_add(*self, other as Self)
1096         }
1097     })*)
1098 }
1099 impl_helper_for! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
1100
1101 /// Determines if a string of text of that length of that radix could be guaranteed to be
1102 /// stored in the given type T.
1103 /// Note that if the radix is known to the compiler, it is just the check of digits.len that
1104 /// is done at runtime.
1105 #[doc(hidden)]
1106 #[inline(always)]
1107 #[unstable(issue = "none", feature = "std_internals")]
1108 pub fn can_not_overflow<T>(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool {
1109     radix <= 16 && digits.len() <= mem::size_of::<T>() * 2 - is_signed_ty as usize
1110 }
1111
1112 fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, ParseIntError> {
1113     use self::IntErrorKind::*;
1114     use self::ParseIntError as PIE;
1115
1116     assert!(
1117         (2..=36).contains(&radix),
1118         "from_str_radix_int: must lie in the range `[2, 36]` - found {}",
1119         radix
1120     );
1121
1122     if src.is_empty() {
1123         return Err(PIE { kind: Empty });
1124     }
1125
1126     let is_signed_ty = T::from_u32(0) > T::MIN;
1127
1128     // all valid digits are ascii, so we will just iterate over the utf8 bytes
1129     // and cast them to chars. .to_digit() will safely return None for anything
1130     // other than a valid ascii digit for the given radix, including the first-byte
1131     // of multi-byte sequences
1132     let src = src.as_bytes();
1133
1134     let (is_positive, digits) = match src[0] {
1135         b'+' | b'-' if src[1..].is_empty() => {
1136             return Err(PIE { kind: InvalidDigit });
1137         }
1138         b'+' => (true, &src[1..]),
1139         b'-' if is_signed_ty => (false, &src[1..]),
1140         _ => (true, src),
1141     };
1142
1143     let mut result = T::from_u32(0);
1144
1145     if can_not_overflow::<T>(radix, is_signed_ty, digits) {
1146         // If the len of the str is short compared to the range of the type
1147         // we are parsing into, then we can be certain that an overflow will not occur.
1148         // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
1149         // above is a faster (conservative) approximation of this.
1150         //
1151         // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
1152         // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
1153         // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
1154         macro_rules! run_unchecked_loop {
1155             ($unchecked_additive_op:expr) => {
1156                 for &c in digits {
1157                     result = result * T::from_u32(radix);
1158                     let x = (c as char).to_digit(radix).ok_or(PIE { kind: InvalidDigit })?;
1159                     result = $unchecked_additive_op(result, T::from_u32(x));
1160                 }
1161             };
1162         }
1163         if is_positive {
1164             run_unchecked_loop!(<T as core::ops::Add>::add)
1165         } else {
1166             run_unchecked_loop!(<T as core::ops::Sub>::sub)
1167         };
1168     } else {
1169         macro_rules! run_checked_loop {
1170             ($checked_additive_op:ident, $overflow_err:expr) => {
1171                 for &c in digits {
1172                     // When `radix` is passed in as a literal, rather than doing a slow `imul`
1173                     // the compiler can use shifts if `radix` can be expressed as a
1174                     // sum of powers of 2 (x*10 can be written as x*8 + x*2).
1175                     // When the compiler can't use these optimisations,
1176                     // the latency of the multiplication can be hidden by issuing it
1177                     // before the result is needed to improve performance on
1178                     // modern out-of-order CPU as multiplication here is slower
1179                     // than the other instructions, we can get the end result faster
1180                     // doing multiplication first and let the CPU spends other cycles
1181                     // doing other computation and get multiplication result later.
1182                     let mul = result.checked_mul(radix);
1183                     let x = (c as char).to_digit(radix).ok_or(PIE { kind: InvalidDigit })?;
1184                     result = mul.ok_or_else($overflow_err)?;
1185                     result = T::$checked_additive_op(&result, x).ok_or_else($overflow_err)?;
1186                 }
1187             };
1188         }
1189         if is_positive {
1190             run_checked_loop!(checked_add, || PIE { kind: PosOverflow })
1191         } else {
1192             run_checked_loop!(checked_sub, || PIE { kind: NegOverflow })
1193         };
1194     }
1195     Ok(result)
1196 }