]> git.lizzy.rs Git - rust.git/blob - library/core/src/num/mod.rs
Rollup merge of #87723 - frogtd:patch-3, r=JohnTitor
[rust.git] / library / core / src / num / mod.rs
1 //! Numeric traits and functions for the built-in numeric types.
2
3 #![stable(feature = "rust1", since = "1.0.0")]
4
5 use crate::ascii;
6 use crate::intrinsics;
7 use crate::mem;
8 use crate::str::FromStr;
9
10 // Used because the `?` operator is not allowed in a const context.
11 macro_rules! try_opt {
12     ($e:expr) => {
13         match $e {
14             Some(x) => x,
15             None => return None,
16         }
17     };
18 }
19
20 #[allow_internal_unstable(const_likely)]
21 macro_rules! unlikely {
22     ($e: expr) => {
23         intrinsics::unlikely($e)
24     };
25 }
26
27 // All these modules are technically private and only exposed for coretests:
28 #[cfg(not(no_fp_fmt_parse))]
29 pub mod bignum;
30 #[cfg(not(no_fp_fmt_parse))]
31 pub mod dec2flt;
32 #[cfg(not(no_fp_fmt_parse))]
33 pub mod diy_float;
34 #[cfg(not(no_fp_fmt_parse))]
35 pub mod flt2dec;
36 pub mod fmt;
37
38 #[macro_use]
39 mod int_macros; // import int_impl!
40 #[macro_use]
41 mod uint_macros; // import uint_impl!
42
43 mod error;
44 mod int_log10;
45 mod nonzero;
46 mod wrapping;
47
48 #[stable(feature = "rust1", since = "1.0.0")]
49 pub use wrapping::Wrapping;
50
51 #[stable(feature = "rust1", since = "1.0.0")]
52 #[cfg(not(no_fp_fmt_parse))]
53 pub use dec2flt::ParseFloatError;
54
55 #[stable(feature = "rust1", since = "1.0.0")]
56 pub use error::ParseIntError;
57
58 #[stable(feature = "nonzero", since = "1.28.0")]
59 pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
60
61 #[stable(feature = "signed_nonzero", since = "1.34.0")]
62 pub use nonzero::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
63
64 #[stable(feature = "try_from", since = "1.34.0")]
65 pub use error::TryFromIntError;
66
67 #[stable(feature = "int_error_matching", since = "1.55.0")]
68 pub use error::IntErrorKind;
69
70 macro_rules! usize_isize_to_xe_bytes_doc {
71     () => {
72         "
73
74 **Note**: This function returns an array of length 2, 4 or 8 bytes
75 depending on the target pointer size.
76
77 "
78     };
79 }
80
81 macro_rules! usize_isize_from_xe_bytes_doc {
82     () => {
83         "
84
85 **Note**: This function takes an array of length 2, 4 or 8 bytes
86 depending on the target pointer size.
87
88 "
89     };
90 }
91
92 #[lang = "i8"]
93 impl i8 {
94     int_impl! { i8, i8, u8, 8, 7, -128, 127, 2, "-0x7e", "0xa", "0x12", "0x12", "0x48",
95     "[0x12]", "[0x12]", "", "" }
96 }
97
98 #[lang = "i16"]
99 impl i16 {
100     int_impl! { i16, i16, u16, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234", "0x3412",
101     "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", "", "" }
102 }
103
104 #[lang = "i32"]
105 impl i32 {
106     int_impl! { i32, i32, u32, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
107     "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
108     "[0x12, 0x34, 0x56, 0x78]", "", "" }
109 }
110
111 #[lang = "i64"]
112 impl i64 {
113     int_impl! { i64, i64, u64, 64, 63, -9223372036854775808, 9223372036854775807, 12,
114     "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412",
115     "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
116     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", "", "" }
117 }
118
119 #[lang = "i128"]
120 impl i128 {
121     int_impl! { i128, i128, u128, 128, 127, -170141183460469231731687303715884105728,
122     170141183460469231731687303715884105727, 16,
123     "0x13f40000000000000000000000004f76", "0x4f7613f4", "0x12345678901234567890123456789012",
124     "0x12907856341290785634129078563412", "0x48091e6a2c48091e6a2c48091e6a2c48",
125     "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
126       0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
127     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
128       0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]", "", "" }
129 }
130
131 #[cfg(target_pointer_width = "16")]
132 #[lang = "isize"]
133 impl isize {
134     int_impl! { isize, i16, usize, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234",
135     "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]",
136     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
137 }
138
139 #[cfg(target_pointer_width = "32")]
140 #[lang = "isize"]
141 impl isize {
142     int_impl! { isize, i32, usize, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
143     "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
144     "[0x12, 0x34, 0x56, 0x78]",
145     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
146 }
147
148 #[cfg(target_pointer_width = "64")]
149 #[lang = "isize"]
150 impl isize {
151     int_impl! { isize, i64, usize, 64, 63, -9223372036854775808, 9223372036854775807,
152     12, "0xaa00000000006e1", "0x6e10aa",  "0x1234567890123456", "0x5634129078563412",
153      "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
154      "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
155      usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
156 }
157
158 /// If 6th bit set ascii is upper case.
159 const ASCII_CASE_MASK: u8 = 0b0010_0000;
160
161 #[lang = "u8"]
162 impl u8 {
163     uint_impl! { u8, u8, 8, 255, 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]",
164     "[0x12]", "", "" }
165
166     /// Checks if the value is within the ASCII range.
167     ///
168     /// # Examples
169     ///
170     /// ```
171     /// let ascii = 97u8;
172     /// let non_ascii = 150u8;
173     ///
174     /// assert!(ascii.is_ascii());
175     /// assert!(!non_ascii.is_ascii());
176     /// ```
177     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
178     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.43.0")]
179     #[inline]
180     pub const fn is_ascii(&self) -> bool {
181         *self & 128 == 0
182     }
183
184     /// Makes a copy of the value in its ASCII upper case equivalent.
185     ///
186     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
187     /// but non-ASCII letters are unchanged.
188     ///
189     /// To uppercase the value in-place, use [`make_ascii_uppercase`].
190     ///
191     /// # Examples
192     ///
193     /// ```
194     /// let lowercase_a = 97u8;
195     ///
196     /// assert_eq!(65, lowercase_a.to_ascii_uppercase());
197     /// ```
198     ///
199     /// [`make_ascii_uppercase`]: Self::make_ascii_uppercase
200     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
201     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
202     #[inline]
203     pub const fn to_ascii_uppercase(&self) -> u8 {
204         // Unset the fifth bit if this is a lowercase letter
205         *self & !((self.is_ascii_lowercase() as u8) * ASCII_CASE_MASK)
206     }
207
208     /// Makes a copy of the value in its ASCII lower case equivalent.
209     ///
210     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
211     /// but non-ASCII letters are unchanged.
212     ///
213     /// To lowercase the value in-place, use [`make_ascii_lowercase`].
214     ///
215     /// # Examples
216     ///
217     /// ```
218     /// let uppercase_a = 65u8;
219     ///
220     /// assert_eq!(97, uppercase_a.to_ascii_lowercase());
221     /// ```
222     ///
223     /// [`make_ascii_lowercase`]: Self::make_ascii_lowercase
224     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
225     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
226     #[inline]
227     pub const fn to_ascii_lowercase(&self) -> u8 {
228         // Set the fifth bit if this is an uppercase letter
229         *self | (self.is_ascii_uppercase() as u8 * ASCII_CASE_MASK)
230     }
231
232     /// Assumes self is ascii
233     #[inline]
234     pub(crate) const fn ascii_change_case_unchecked(&self) -> u8 {
235         *self ^ ASCII_CASE_MASK
236     }
237
238     /// Checks that two values are an ASCII case-insensitive match.
239     ///
240     /// This is equivalent to `to_ascii_lowercase(a) == to_ascii_lowercase(b)`.
241     ///
242     /// # Examples
243     ///
244     /// ```
245     /// let lowercase_a = 97u8;
246     /// let uppercase_a = 65u8;
247     ///
248     /// assert!(lowercase_a.eq_ignore_ascii_case(&uppercase_a));
249     /// ```
250     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
251     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
252     #[inline]
253     pub const fn eq_ignore_ascii_case(&self, other: &u8) -> bool {
254         self.to_ascii_lowercase() == other.to_ascii_lowercase()
255     }
256
257     /// Converts this value to its ASCII upper case equivalent in-place.
258     ///
259     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
260     /// but non-ASCII letters are unchanged.
261     ///
262     /// To return a new uppercased value without modifying the existing one, use
263     /// [`to_ascii_uppercase`].
264     ///
265     /// # Examples
266     ///
267     /// ```
268     /// let mut byte = b'a';
269     ///
270     /// byte.make_ascii_uppercase();
271     ///
272     /// assert_eq!(b'A', byte);
273     /// ```
274     ///
275     /// [`to_ascii_uppercase`]: Self::to_ascii_uppercase
276     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
277     #[inline]
278     pub fn make_ascii_uppercase(&mut self) {
279         *self = self.to_ascii_uppercase();
280     }
281
282     /// Converts this value to its ASCII lower case equivalent in-place.
283     ///
284     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
285     /// but non-ASCII letters are unchanged.
286     ///
287     /// To return a new lowercased value without modifying the existing one, use
288     /// [`to_ascii_lowercase`].
289     ///
290     /// # Examples
291     ///
292     /// ```
293     /// let mut byte = b'A';
294     ///
295     /// byte.make_ascii_lowercase();
296     ///
297     /// assert_eq!(b'a', byte);
298     /// ```
299     ///
300     /// [`to_ascii_lowercase`]: Self::to_ascii_lowercase
301     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
302     #[inline]
303     pub fn make_ascii_lowercase(&mut self) {
304         *self = self.to_ascii_lowercase();
305     }
306
307     /// Checks if the value is an ASCII alphabetic character:
308     ///
309     /// - U+0041 'A' ..= U+005A 'Z', or
310     /// - U+0061 'a' ..= U+007A 'z'.
311     ///
312     /// # Examples
313     ///
314     /// ```
315     /// let uppercase_a = b'A';
316     /// let uppercase_g = b'G';
317     /// let a = b'a';
318     /// let g = b'g';
319     /// let zero = b'0';
320     /// let percent = b'%';
321     /// let space = b' ';
322     /// let lf = b'\n';
323     /// let esc = 0x1b_u8;
324     ///
325     /// assert!(uppercase_a.is_ascii_alphabetic());
326     /// assert!(uppercase_g.is_ascii_alphabetic());
327     /// assert!(a.is_ascii_alphabetic());
328     /// assert!(g.is_ascii_alphabetic());
329     /// assert!(!zero.is_ascii_alphabetic());
330     /// assert!(!percent.is_ascii_alphabetic());
331     /// assert!(!space.is_ascii_alphabetic());
332     /// assert!(!lf.is_ascii_alphabetic());
333     /// assert!(!esc.is_ascii_alphabetic());
334     /// ```
335     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
336     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
337     #[inline]
338     pub const fn is_ascii_alphabetic(&self) -> bool {
339         matches!(*self, b'A'..=b'Z' | b'a'..=b'z')
340     }
341
342     /// Checks if the value is an ASCII uppercase character:
343     /// U+0041 'A' ..= U+005A 'Z'.
344     ///
345     /// # Examples
346     ///
347     /// ```
348     /// let uppercase_a = b'A';
349     /// let uppercase_g = b'G';
350     /// let a = b'a';
351     /// let g = b'g';
352     /// let zero = b'0';
353     /// let percent = b'%';
354     /// let space = b' ';
355     /// let lf = b'\n';
356     /// let esc = 0x1b_u8;
357     ///
358     /// assert!(uppercase_a.is_ascii_uppercase());
359     /// assert!(uppercase_g.is_ascii_uppercase());
360     /// assert!(!a.is_ascii_uppercase());
361     /// assert!(!g.is_ascii_uppercase());
362     /// assert!(!zero.is_ascii_uppercase());
363     /// assert!(!percent.is_ascii_uppercase());
364     /// assert!(!space.is_ascii_uppercase());
365     /// assert!(!lf.is_ascii_uppercase());
366     /// assert!(!esc.is_ascii_uppercase());
367     /// ```
368     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
369     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
370     #[inline]
371     pub const fn is_ascii_uppercase(&self) -> bool {
372         matches!(*self, b'A'..=b'Z')
373     }
374
375     /// Checks if the value is an ASCII lowercase character:
376     /// U+0061 'a' ..= U+007A 'z'.
377     ///
378     /// # Examples
379     ///
380     /// ```
381     /// let uppercase_a = b'A';
382     /// let uppercase_g = b'G';
383     /// let a = b'a';
384     /// let g = b'g';
385     /// let zero = b'0';
386     /// let percent = b'%';
387     /// let space = b' ';
388     /// let lf = b'\n';
389     /// let esc = 0x1b_u8;
390     ///
391     /// assert!(!uppercase_a.is_ascii_lowercase());
392     /// assert!(!uppercase_g.is_ascii_lowercase());
393     /// assert!(a.is_ascii_lowercase());
394     /// assert!(g.is_ascii_lowercase());
395     /// assert!(!zero.is_ascii_lowercase());
396     /// assert!(!percent.is_ascii_lowercase());
397     /// assert!(!space.is_ascii_lowercase());
398     /// assert!(!lf.is_ascii_lowercase());
399     /// assert!(!esc.is_ascii_lowercase());
400     /// ```
401     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
402     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
403     #[inline]
404     pub const fn is_ascii_lowercase(&self) -> bool {
405         matches!(*self, b'a'..=b'z')
406     }
407
408     /// Checks if the value is an ASCII alphanumeric character:
409     ///
410     /// - U+0041 'A' ..= U+005A 'Z', or
411     /// - U+0061 'a' ..= U+007A 'z', or
412     /// - U+0030 '0' ..= U+0039 '9'.
413     ///
414     /// # Examples
415     ///
416     /// ```
417     /// let uppercase_a = b'A';
418     /// let uppercase_g = b'G';
419     /// let a = b'a';
420     /// let g = b'g';
421     /// let zero = b'0';
422     /// let percent = b'%';
423     /// let space = b' ';
424     /// let lf = b'\n';
425     /// let esc = 0x1b_u8;
426     ///
427     /// assert!(uppercase_a.is_ascii_alphanumeric());
428     /// assert!(uppercase_g.is_ascii_alphanumeric());
429     /// assert!(a.is_ascii_alphanumeric());
430     /// assert!(g.is_ascii_alphanumeric());
431     /// assert!(zero.is_ascii_alphanumeric());
432     /// assert!(!percent.is_ascii_alphanumeric());
433     /// assert!(!space.is_ascii_alphanumeric());
434     /// assert!(!lf.is_ascii_alphanumeric());
435     /// assert!(!esc.is_ascii_alphanumeric());
436     /// ```
437     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
438     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
439     #[inline]
440     pub const fn is_ascii_alphanumeric(&self) -> bool {
441         matches!(*self, b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z')
442     }
443
444     /// Checks if the value is an ASCII decimal digit:
445     /// U+0030 '0' ..= U+0039 '9'.
446     ///
447     /// # Examples
448     ///
449     /// ```
450     /// let uppercase_a = b'A';
451     /// let uppercase_g = b'G';
452     /// let a = b'a';
453     /// let g = b'g';
454     /// let zero = b'0';
455     /// let percent = b'%';
456     /// let space = b' ';
457     /// let lf = b'\n';
458     /// let esc = 0x1b_u8;
459     ///
460     /// assert!(!uppercase_a.is_ascii_digit());
461     /// assert!(!uppercase_g.is_ascii_digit());
462     /// assert!(!a.is_ascii_digit());
463     /// assert!(!g.is_ascii_digit());
464     /// assert!(zero.is_ascii_digit());
465     /// assert!(!percent.is_ascii_digit());
466     /// assert!(!space.is_ascii_digit());
467     /// assert!(!lf.is_ascii_digit());
468     /// assert!(!esc.is_ascii_digit());
469     /// ```
470     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
471     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
472     #[inline]
473     pub const fn is_ascii_digit(&self) -> bool {
474         matches!(*self, b'0'..=b'9')
475     }
476
477     /// Checks if the value is an ASCII hexadecimal digit:
478     ///
479     /// - U+0030 '0' ..= U+0039 '9', or
480     /// - U+0041 'A' ..= U+0046 'F', or
481     /// - U+0061 'a' ..= U+0066 'f'.
482     ///
483     /// # Examples
484     ///
485     /// ```
486     /// let uppercase_a = b'A';
487     /// let uppercase_g = b'G';
488     /// let a = b'a';
489     /// let g = b'g';
490     /// let zero = b'0';
491     /// let percent = b'%';
492     /// let space = b' ';
493     /// let lf = b'\n';
494     /// let esc = 0x1b_u8;
495     ///
496     /// assert!(uppercase_a.is_ascii_hexdigit());
497     /// assert!(!uppercase_g.is_ascii_hexdigit());
498     /// assert!(a.is_ascii_hexdigit());
499     /// assert!(!g.is_ascii_hexdigit());
500     /// assert!(zero.is_ascii_hexdigit());
501     /// assert!(!percent.is_ascii_hexdigit());
502     /// assert!(!space.is_ascii_hexdigit());
503     /// assert!(!lf.is_ascii_hexdigit());
504     /// assert!(!esc.is_ascii_hexdigit());
505     /// ```
506     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
507     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
508     #[inline]
509     pub const fn is_ascii_hexdigit(&self) -> bool {
510         matches!(*self, b'0'..=b'9' | b'A'..=b'F' | b'a'..=b'f')
511     }
512
513     /// Checks if the value is an ASCII punctuation character:
514     ///
515     /// - U+0021 ..= U+002F `! " # $ % & ' ( ) * + , - . /`, or
516     /// - U+003A ..= U+0040 `: ; < = > ? @`, or
517     /// - U+005B ..= U+0060 ``[ \ ] ^ _ ` ``, or
518     /// - U+007B ..= U+007E `{ | } ~`
519     ///
520     /// # Examples
521     ///
522     /// ```
523     /// let uppercase_a = b'A';
524     /// let uppercase_g = b'G';
525     /// let a = b'a';
526     /// let g = b'g';
527     /// let zero = b'0';
528     /// let percent = b'%';
529     /// let space = b' ';
530     /// let lf = b'\n';
531     /// let esc = 0x1b_u8;
532     ///
533     /// assert!(!uppercase_a.is_ascii_punctuation());
534     /// assert!(!uppercase_g.is_ascii_punctuation());
535     /// assert!(!a.is_ascii_punctuation());
536     /// assert!(!g.is_ascii_punctuation());
537     /// assert!(!zero.is_ascii_punctuation());
538     /// assert!(percent.is_ascii_punctuation());
539     /// assert!(!space.is_ascii_punctuation());
540     /// assert!(!lf.is_ascii_punctuation());
541     /// assert!(!esc.is_ascii_punctuation());
542     /// ```
543     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
544     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
545     #[inline]
546     pub const fn is_ascii_punctuation(&self) -> bool {
547         matches!(*self, b'!'..=b'/' | b':'..=b'@' | b'['..=b'`' | b'{'..=b'~')
548     }
549
550     /// Checks if the value is an ASCII graphic character:
551     /// U+0021 '!' ..= U+007E '~'.
552     ///
553     /// # Examples
554     ///
555     /// ```
556     /// let uppercase_a = b'A';
557     /// let uppercase_g = b'G';
558     /// let a = b'a';
559     /// let g = b'g';
560     /// let zero = b'0';
561     /// let percent = b'%';
562     /// let space = b' ';
563     /// let lf = b'\n';
564     /// let esc = 0x1b_u8;
565     ///
566     /// assert!(uppercase_a.is_ascii_graphic());
567     /// assert!(uppercase_g.is_ascii_graphic());
568     /// assert!(a.is_ascii_graphic());
569     /// assert!(g.is_ascii_graphic());
570     /// assert!(zero.is_ascii_graphic());
571     /// assert!(percent.is_ascii_graphic());
572     /// assert!(!space.is_ascii_graphic());
573     /// assert!(!lf.is_ascii_graphic());
574     /// assert!(!esc.is_ascii_graphic());
575     /// ```
576     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
577     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
578     #[inline]
579     pub const fn is_ascii_graphic(&self) -> bool {
580         matches!(*self, b'!'..=b'~')
581     }
582
583     /// Checks if the value is an ASCII whitespace character:
584     /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED,
585     /// U+000C FORM FEED, or U+000D CARRIAGE RETURN.
586     ///
587     /// Rust uses the WhatWG Infra Standard's [definition of ASCII
588     /// whitespace][infra-aw]. There are several other definitions in
589     /// wide use. For instance, [the POSIX locale][pct] includes
590     /// U+000B VERTICAL TAB as well as all the above characters,
591     /// but—from the very same specification—[the default rule for
592     /// "field splitting" in the Bourne shell][bfs] considers *only*
593     /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
594     ///
595     /// If you are writing a program that will process an existing
596     /// file format, check what that format's definition of whitespace is
597     /// before using this function.
598     ///
599     /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
600     /// [pct]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
601     /// [bfs]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
602     ///
603     /// # Examples
604     ///
605     /// ```
606     /// let uppercase_a = b'A';
607     /// let uppercase_g = b'G';
608     /// let a = b'a';
609     /// let g = b'g';
610     /// let zero = b'0';
611     /// let percent = b'%';
612     /// let space = b' ';
613     /// let lf = b'\n';
614     /// let esc = 0x1b_u8;
615     ///
616     /// assert!(!uppercase_a.is_ascii_whitespace());
617     /// assert!(!uppercase_g.is_ascii_whitespace());
618     /// assert!(!a.is_ascii_whitespace());
619     /// assert!(!g.is_ascii_whitespace());
620     /// assert!(!zero.is_ascii_whitespace());
621     /// assert!(!percent.is_ascii_whitespace());
622     /// assert!(space.is_ascii_whitespace());
623     /// assert!(lf.is_ascii_whitespace());
624     /// assert!(!esc.is_ascii_whitespace());
625     /// ```
626     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
627     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
628     #[inline]
629     pub const fn is_ascii_whitespace(&self) -> bool {
630         matches!(*self, b'\t' | b'\n' | b'\x0C' | b'\r' | b' ')
631     }
632
633     /// Checks if the value is an ASCII control character:
634     /// U+0000 NUL ..= U+001F UNIT SEPARATOR, or U+007F DELETE.
635     /// Note that most ASCII whitespace characters are control
636     /// characters, but SPACE is not.
637     ///
638     /// # Examples
639     ///
640     /// ```
641     /// let uppercase_a = b'A';
642     /// let uppercase_g = b'G';
643     /// let a = b'a';
644     /// let g = b'g';
645     /// let zero = b'0';
646     /// let percent = b'%';
647     /// let space = b' ';
648     /// let lf = b'\n';
649     /// let esc = 0x1b_u8;
650     ///
651     /// assert!(!uppercase_a.is_ascii_control());
652     /// assert!(!uppercase_g.is_ascii_control());
653     /// assert!(!a.is_ascii_control());
654     /// assert!(!g.is_ascii_control());
655     /// assert!(!zero.is_ascii_control());
656     /// assert!(!percent.is_ascii_control());
657     /// assert!(!space.is_ascii_control());
658     /// assert!(lf.is_ascii_control());
659     /// assert!(esc.is_ascii_control());
660     /// ```
661     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
662     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
663     #[inline]
664     pub const fn is_ascii_control(&self) -> bool {
665         matches!(*self, b'\0'..=b'\x1F' | b'\x7F')
666     }
667
668     /// Returns an iterator that produces an escaped version of a `u8`,
669     /// treating it as an ASCII character.
670     ///
671     /// The behavior is identical to [`ascii::escape_default`].
672     ///
673     /// # Examples
674     ///
675     /// ```
676     /// #![feature(inherent_ascii_escape)]
677     ///
678     /// assert_eq!("0", b'0'.escape_ascii().to_string());
679     /// assert_eq!("\\t", b'\t'.escape_ascii().to_string());
680     /// assert_eq!("\\r", b'\r'.escape_ascii().to_string());
681     /// assert_eq!("\\n", b'\n'.escape_ascii().to_string());
682     /// assert_eq!("\\'", b'\''.escape_ascii().to_string());
683     /// assert_eq!("\\\"", b'"'.escape_ascii().to_string());
684     /// assert_eq!("\\\\", b'\\'.escape_ascii().to_string());
685     /// assert_eq!("\\x9d", b'\x9d'.escape_ascii().to_string());
686     /// ```
687     #[unstable(feature = "inherent_ascii_escape", issue = "77174")]
688     #[inline]
689     pub fn escape_ascii(&self) -> ascii::EscapeDefault {
690         ascii::escape_default(*self)
691     }
692 }
693
694 #[lang = "u16"]
695 impl u16 {
696     uint_impl! { u16, u16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
697     "[0x34, 0x12]", "[0x12, 0x34]", "", "" }
698 }
699
700 #[lang = "u32"]
701 impl u32 {
702     uint_impl! { u32, u32, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
703     "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", "", "" }
704 }
705
706 #[lang = "u64"]
707 impl u64 {
708     uint_impl! { u64, u64, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
709     "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
710     "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
711     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
712     "", ""}
713 }
714
715 #[lang = "u128"]
716 impl u128 {
717     uint_impl! { u128, u128, 128, 340282366920938463463374607431768211455, 16,
718     "0x13f40000000000000000000000004f76", "0x4f7613f4", "0x12345678901234567890123456789012",
719     "0x12907856341290785634129078563412", "0x48091e6a2c48091e6a2c48091e6a2c48",
720     "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
721       0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
722     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \
723       0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]",
724      "", ""}
725 }
726
727 #[cfg(target_pointer_width = "16")]
728 #[lang = "usize"]
729 impl usize {
730     uint_impl! { usize, u16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
731     "[0x34, 0x12]", "[0x12, 0x34]",
732     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
733 }
734 #[cfg(target_pointer_width = "32")]
735 #[lang = "usize"]
736 impl usize {
737     uint_impl! { usize, u32, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
738     "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]",
739     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
740 }
741
742 #[cfg(target_pointer_width = "64")]
743 #[lang = "usize"]
744 impl usize {
745     uint_impl! { usize, u64, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
746     "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
747     "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
748      "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
749     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
750 }
751
752 /// A classification of floating point numbers.
753 ///
754 /// This `enum` is used as the return type for [`f32::classify`] and [`f64::classify`]. See
755 /// their documentation for more.
756 ///
757 /// # Examples
758 ///
759 /// ```
760 /// use std::num::FpCategory;
761 ///
762 /// let num = 12.4_f32;
763 /// let inf = f32::INFINITY;
764 /// let zero = 0f32;
765 /// let sub: f32 = 1.1754942e-38;
766 /// let nan = f32::NAN;
767 ///
768 /// assert_eq!(num.classify(), FpCategory::Normal);
769 /// assert_eq!(inf.classify(), FpCategory::Infinite);
770 /// assert_eq!(zero.classify(), FpCategory::Zero);
771 /// assert_eq!(nan.classify(), FpCategory::Nan);
772 /// assert_eq!(sub.classify(), FpCategory::Subnormal);
773 /// ```
774 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
775 #[stable(feature = "rust1", since = "1.0.0")]
776 pub enum FpCategory {
777     /// "Not a Number", often obtained by dividing by zero.
778     #[stable(feature = "rust1", since = "1.0.0")]
779     Nan,
780
781     /// Positive or negative infinity.
782     #[stable(feature = "rust1", since = "1.0.0")]
783     Infinite,
784
785     /// Positive or negative zero.
786     #[stable(feature = "rust1", since = "1.0.0")]
787     Zero,
788
789     /// De-normalized floating point representation (less precise than `Normal`).
790     #[stable(feature = "rust1", since = "1.0.0")]
791     Subnormal,
792
793     /// A regular floating point number.
794     #[stable(feature = "rust1", since = "1.0.0")]
795     Normal,
796 }
797
798 #[doc(hidden)]
799 trait FromStrRadixHelper: PartialOrd + Copy {
800     fn min_value() -> Self;
801     fn max_value() -> Self;
802     fn from_u32(u: u32) -> Self;
803     fn checked_mul(&self, other: u32) -> Option<Self>;
804     fn checked_sub(&self, other: u32) -> Option<Self>;
805     fn checked_add(&self, other: u32) -> Option<Self>;
806 }
807
808 macro_rules! from_str_radix_int_impl {
809     ($($t:ty)*) => {$(
810         #[stable(feature = "rust1", since = "1.0.0")]
811         impl FromStr for $t {
812             type Err = ParseIntError;
813             fn from_str(src: &str) -> Result<Self, ParseIntError> {
814                 from_str_radix(src, 10)
815             }
816         }
817     )*}
818 }
819 from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }
820
821 macro_rules! doit {
822     ($($t:ty)*) => ($(impl FromStrRadixHelper for $t {
823         #[inline]
824         fn min_value() -> Self { Self::MIN }
825         #[inline]
826         fn max_value() -> Self { Self::MAX }
827         #[inline]
828         fn from_u32(u: u32) -> Self { u as Self }
829         #[inline]
830         fn checked_mul(&self, other: u32) -> Option<Self> {
831             Self::checked_mul(*self, other as Self)
832         }
833         #[inline]
834         fn checked_sub(&self, other: u32) -> Option<Self> {
835             Self::checked_sub(*self, other as Self)
836         }
837         #[inline]
838         fn checked_add(&self, other: u32) -> Option<Self> {
839             Self::checked_add(*self, other as Self)
840         }
841     })*)
842 }
843 doit! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
844
845 fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, ParseIntError> {
846     use self::IntErrorKind::*;
847     use self::ParseIntError as PIE;
848
849     assert!(
850         (2..=36).contains(&radix),
851         "from_str_radix_int: must lie in the range `[2, 36]` - found {}",
852         radix
853     );
854
855     if src.is_empty() {
856         return Err(PIE { kind: Empty });
857     }
858
859     let is_signed_ty = T::from_u32(0) > T::min_value();
860
861     // all valid digits are ascii, so we will just iterate over the utf8 bytes
862     // and cast them to chars. .to_digit() will safely return None for anything
863     // other than a valid ascii digit for the given radix, including the first-byte
864     // of multi-byte sequences
865     let src = src.as_bytes();
866
867     let (is_positive, digits) = match src[0] {
868         b'+' | b'-' if src[1..].is_empty() => {
869             return Err(PIE { kind: InvalidDigit });
870         }
871         b'+' => (true, &src[1..]),
872         b'-' if is_signed_ty => (false, &src[1..]),
873         _ => (true, src),
874     };
875
876     let mut result = T::from_u32(0);
877     if is_positive {
878         // The number is positive
879         for &c in digits {
880             let x = match (c as char).to_digit(radix) {
881                 Some(x) => x,
882                 None => return Err(PIE { kind: InvalidDigit }),
883             };
884             result = match result.checked_mul(radix) {
885                 Some(result) => result,
886                 None => return Err(PIE { kind: PosOverflow }),
887             };
888             result = match result.checked_add(x) {
889                 Some(result) => result,
890                 None => return Err(PIE { kind: PosOverflow }),
891             };
892         }
893     } else {
894         // The number is negative
895         for &c in digits {
896             let x = match (c as char).to_digit(radix) {
897                 Some(x) => x,
898                 None => return Err(PIE { kind: InvalidDigit }),
899             };
900             result = match result.checked_mul(radix) {
901                 Some(result) => result,
902                 None => return Err(PIE { kind: NegOverflow }),
903             };
904             result = match result.checked_sub(x) {
905                 Some(result) => result,
906                 None => return Err(PIE { kind: NegOverflow }),
907             };
908         }
909     }
910     Ok(result)
911 }