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