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