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