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