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