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