]> git.lizzy.rs Git - rust.git/blob - src/libcore/char/methods.rs
33fd6947c1e4b6471d978a13bd69058695cf33e6
[rust.git] / src / libcore / char / methods.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! impl char {}
12
13 use slice;
14 use str::from_utf8_unchecked_mut;
15 use super::*;
16 use unicode::printable::is_printable;
17 use unicode::tables::{conversions, derived_property, general_category, property};
18
19 #[lang = "char"]
20 impl char {
21     /// Checks if a `char` is a digit in the given radix.
22     ///
23     /// A 'radix' here is sometimes also called a 'base'. A radix of two
24     /// indicates a binary number, a radix of ten, decimal, and a radix of
25     /// sixteen, hexadecimal, to give some common values. Arbitrary
26     /// radices are supported.
27     ///
28     /// Compared to `is_numeric()`, this function only recognizes the characters
29     /// `0-9`, `a-z` and `A-Z`.
30     ///
31     /// 'Digit' is defined to be only the following characters:
32     ///
33     /// * `0-9`
34     /// * `a-z`
35     /// * `A-Z`
36     ///
37     /// For a more comprehensive understanding of 'digit', see [`is_numeric`][is_numeric].
38     ///
39     /// [is_numeric]: #method.is_numeric
40     ///
41     /// # Panics
42     ///
43     /// Panics if given a radix larger than 36.
44     ///
45     /// # Examples
46     ///
47     /// Basic usage:
48     ///
49     /// ```
50     /// assert!('1'.is_digit(10));
51     /// assert!('f'.is_digit(16));
52     /// assert!(!'f'.is_digit(10));
53     /// ```
54     ///
55     /// Passing a large radix, causing a panic:
56     ///
57     /// ```
58     /// use std::thread;
59     ///
60     /// let result = thread::spawn(|| {
61     ///     // this panics
62     ///     '1'.is_digit(37);
63     /// }).join();
64     ///
65     /// assert!(result.is_err());
66     /// ```
67     #[stable(feature = "rust1", since = "1.0.0")]
68     #[inline]
69     pub fn is_digit(self, radix: u32) -> bool {
70         self.to_digit(radix).is_some()
71     }
72
73     /// Converts a `char` to a digit in the given radix.
74     ///
75     /// A 'radix' here is sometimes also called a 'base'. A radix of two
76     /// indicates a binary number, a radix of ten, decimal, and a radix of
77     /// sixteen, hexadecimal, to give some common values. Arbitrary
78     /// radices are supported.
79     ///
80     /// 'Digit' is defined to be only the following characters:
81     ///
82     /// * `0-9`
83     /// * `a-z`
84     /// * `A-Z`
85     ///
86     /// # Errors
87     ///
88     /// Returns `None` if the `char` does not refer to a digit in the given radix.
89     ///
90     /// # Panics
91     ///
92     /// Panics if given a radix larger than 36.
93     ///
94     /// # Examples
95     ///
96     /// Basic usage:
97     ///
98     /// ```
99     /// assert_eq!('1'.to_digit(10), Some(1));
100     /// assert_eq!('f'.to_digit(16), Some(15));
101     /// ```
102     ///
103     /// Passing a non-digit results in failure:
104     ///
105     /// ```
106     /// assert_eq!('f'.to_digit(10), None);
107     /// assert_eq!('z'.to_digit(16), None);
108     /// ```
109     ///
110     /// Passing a large radix, causing a panic:
111     ///
112     /// ```
113     /// use std::thread;
114     ///
115     /// let result = thread::spawn(|| {
116     ///     '1'.to_digit(37);
117     /// }).join();
118     ///
119     /// assert!(result.is_err());
120     /// ```
121     #[stable(feature = "rust1", since = "1.0.0")]
122     #[inline]
123     pub fn to_digit(self, radix: u32) -> Option<u32> {
124         if radix > 36 {
125             panic!("to_digit: radix is too high (maximum 36)");
126         }
127         let val = match self {
128           '0' ..= '9' => self as u32 - '0' as u32,
129           'a' ..= 'z' => self as u32 - 'a' as u32 + 10,
130           'A' ..= 'Z' => self as u32 - 'A' as u32 + 10,
131           _ => return None,
132         };
133         if val < radix { Some(val) }
134         else { None }
135     }
136
137     /// Returns an iterator that yields the hexadecimal Unicode escape of a
138     /// character as `char`s.
139     ///
140     /// This will escape characters with the Rust syntax of the form
141     /// `\u{NNNNNN}` where `NNNNNN` is a hexadecimal representation.
142     ///
143     /// # Examples
144     ///
145     /// As an iterator:
146     ///
147     /// ```
148     /// for c in '❤'.escape_unicode() {
149     ///     print!("{}", c);
150     /// }
151     /// println!();
152     /// ```
153     ///
154     /// Using `println!` directly:
155     ///
156     /// ```
157     /// println!("{}", '❤'.escape_unicode());
158     /// ```
159     ///
160     /// Both are equivalent to:
161     ///
162     /// ```
163     /// println!("\\u{{2764}}");
164     /// ```
165     ///
166     /// Using `to_string`:
167     ///
168     /// ```
169     /// assert_eq!('❤'.escape_unicode().to_string(), "\\u{2764}");
170     /// ```
171     #[stable(feature = "rust1", since = "1.0.0")]
172     #[inline]
173     pub fn escape_unicode(self) -> EscapeUnicode {
174         let c = self as u32;
175
176         // or-ing 1 ensures that for c==0 the code computes that one
177         // digit should be printed and (which is the same) avoids the
178         // (31 - 32) underflow
179         let msb = 31 - (c | 1).leading_zeros();
180
181         // the index of the most significant hex digit
182         let ms_hex_digit = msb / 4;
183         EscapeUnicode {
184             c: self,
185             state: EscapeUnicodeState::Backslash,
186             hex_digit_idx: ms_hex_digit as usize,
187         }
188     }
189
190     /// An extended version of `escape_debug` that optionally permits escaping
191     /// Extended Grapheme codepoints. This allows us to format characters like
192     /// nonspacing marks better when they're at the start of a string.
193     #[doc(hidden)]
194     #[unstable(feature = "str_internals", issue = "0")]
195     #[inline]
196     pub fn escape_debug_ext(self, escape_grapheme_extended: bool) -> EscapeDebug {
197         let init_state = match self {
198             '\t' => EscapeDefaultState::Backslash('t'),
199             '\r' => EscapeDefaultState::Backslash('r'),
200             '\n' => EscapeDefaultState::Backslash('n'),
201             '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
202             _ if escape_grapheme_extended && self.is_grapheme_extended() => {
203                 EscapeDefaultState::Unicode(self.escape_unicode())
204             }
205             _ if is_printable(self) => EscapeDefaultState::Char(self),
206             _ => EscapeDefaultState::Unicode(self.escape_unicode()),
207         };
208         EscapeDebug(EscapeDefault { state: init_state })
209     }
210
211     /// Returns an iterator that yields the literal escape code of a character
212     /// as `char`s.
213     ///
214     /// This will escape the characters similar to the `Debug` implementations
215     /// of `str` or `char`.
216     ///
217     /// # Examples
218     ///
219     /// As an iterator:
220     ///
221     /// ```
222     /// for c in '\n'.escape_debug() {
223     ///     print!("{}", c);
224     /// }
225     /// println!();
226     /// ```
227     ///
228     /// Using `println!` directly:
229     ///
230     /// ```
231     /// println!("{}", '\n'.escape_debug());
232     /// ```
233     ///
234     /// Both are equivalent to:
235     ///
236     /// ```
237     /// println!("\\n");
238     /// ```
239     ///
240     /// Using `to_string`:
241     ///
242     /// ```
243     /// assert_eq!('\n'.escape_debug().to_string(), "\\n");
244     /// ```
245     #[stable(feature = "char_escape_debug", since = "1.20.0")]
246     #[inline]
247     pub fn escape_debug(self) -> EscapeDebug {
248         self.escape_debug_ext(true)
249     }
250
251     /// Returns an iterator that yields the literal escape code of a character
252     /// as `char`s.
253     ///
254     /// The default is chosen with a bias toward producing literals that are
255     /// legal in a variety of languages, including C++11 and similar C-family
256     /// languages. The exact rules are:
257     ///
258     /// * Tab is escaped as `\t`.
259     /// * Carriage return is escaped as `\r`.
260     /// * Line feed is escaped as `\n`.
261     /// * Single quote is escaped as `\'`.
262     /// * Double quote is escaped as `\"`.
263     /// * Backslash is escaped as `\\`.
264     /// * Any character in the 'printable ASCII' range `0x20` .. `0x7e`
265     ///   inclusive is not escaped.
266     /// * All other characters are given hexadecimal Unicode escapes; see
267     ///   [`escape_unicode`][escape_unicode].
268     ///
269     /// [escape_unicode]: #method.escape_unicode
270     ///
271     /// # Examples
272     ///
273     /// As an iterator:
274     ///
275     /// ```
276     /// for c in '"'.escape_default() {
277     ///     print!("{}", c);
278     /// }
279     /// println!();
280     /// ```
281     ///
282     /// Using `println!` directly:
283     ///
284     /// ```
285     /// println!("{}", '"'.escape_default());
286     /// ```
287     ///
288     ///
289     /// Both are equivalent to:
290     ///
291     /// ```
292     /// println!("\\\"");
293     /// ```
294     ///
295     /// Using `to_string`:
296     ///
297     /// ```
298     /// assert_eq!('"'.escape_default().to_string(), "\\\"");
299     /// ```
300     #[stable(feature = "rust1", since = "1.0.0")]
301     #[inline]
302     pub fn escape_default(self) -> EscapeDefault {
303         let init_state = match self {
304             '\t' => EscapeDefaultState::Backslash('t'),
305             '\r' => EscapeDefaultState::Backslash('r'),
306             '\n' => EscapeDefaultState::Backslash('n'),
307             '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
308             '\x20' ..= '\x7e' => EscapeDefaultState::Char(self),
309             _ => EscapeDefaultState::Unicode(self.escape_unicode())
310         };
311         EscapeDefault { state: init_state }
312     }
313
314     /// Returns the number of bytes this `char` would need if encoded in UTF-8.
315     ///
316     /// That number of bytes is always between 1 and 4, inclusive.
317     ///
318     /// # Examples
319     ///
320     /// Basic usage:
321     ///
322     /// ```
323     /// let len = 'A'.len_utf8();
324     /// assert_eq!(len, 1);
325     ///
326     /// let len = 'ß'.len_utf8();
327     /// assert_eq!(len, 2);
328     ///
329     /// let len = 'ℝ'.len_utf8();
330     /// assert_eq!(len, 3);
331     ///
332     /// let len = '💣'.len_utf8();
333     /// assert_eq!(len, 4);
334     /// ```
335     ///
336     /// The `&str` type guarantees that its contents are UTF-8, and so we can compare the length it
337     /// would take if each code point was represented as a `char` vs in the `&str` itself:
338     ///
339     /// ```
340     /// // as chars
341     /// let eastern = '東';
342     /// let capitol = '京';
343     ///
344     /// // both can be represented as three bytes
345     /// assert_eq!(3, eastern.len_utf8());
346     /// assert_eq!(3, capitol.len_utf8());
347     ///
348     /// // as a &str, these two are encoded in UTF-8
349     /// let tokyo = "東京";
350     ///
351     /// let len = eastern.len_utf8() + capitol.len_utf8();
352     ///
353     /// // we can see that they take six bytes total...
354     /// assert_eq!(6, tokyo.len());
355     ///
356     /// // ... just like the &str
357     /// assert_eq!(len, tokyo.len());
358     /// ```
359     #[stable(feature = "rust1", since = "1.0.0")]
360     #[inline]
361     pub fn len_utf8(self) -> usize {
362         let code = self as u32;
363         if code < MAX_ONE_B {
364             1
365         } else if code < MAX_TWO_B {
366             2
367         } else if code < MAX_THREE_B {
368             3
369         } else {
370             4
371         }
372     }
373
374     /// Returns the number of 16-bit code units this `char` would need if
375     /// encoded in UTF-16.
376     ///
377     /// See the documentation for [`len_utf8`] for more explanation of this
378     /// concept. This function is a mirror, but for UTF-16 instead of UTF-8.
379     ///
380     /// [`len_utf8`]: #method.len_utf8
381     ///
382     /// # Examples
383     ///
384     /// Basic usage:
385     ///
386     /// ```
387     /// let n = 'ß'.len_utf16();
388     /// assert_eq!(n, 1);
389     ///
390     /// let len = '💣'.len_utf16();
391     /// assert_eq!(len, 2);
392     /// ```
393     #[stable(feature = "rust1", since = "1.0.0")]
394     #[inline]
395     pub fn len_utf16(self) -> usize {
396         let ch = self as u32;
397         if (ch & 0xFFFF) == ch { 1 } else { 2 }
398     }
399
400     /// Encodes this character as UTF-8 into the provided byte buffer,
401     /// and then returns the subslice of the buffer that contains the encoded character.
402     ///
403     /// # Panics
404     ///
405     /// Panics if the buffer is not large enough.
406     /// A buffer of length four is large enough to encode any `char`.
407     ///
408     /// # Examples
409     ///
410     /// In both of these examples, 'ß' takes two bytes to encode.
411     ///
412     /// ```
413     /// let mut b = [0; 2];
414     ///
415     /// let result = 'ß'.encode_utf8(&mut b);
416     ///
417     /// assert_eq!(result, "ß");
418     ///
419     /// assert_eq!(result.len(), 2);
420     /// ```
421     ///
422     /// A buffer that's too small:
423     ///
424     /// ```
425     /// use std::thread;
426     ///
427     /// let result = thread::spawn(|| {
428     ///     let mut b = [0; 1];
429     ///
430     ///     // this panics
431     ///    'ß'.encode_utf8(&mut b);
432     /// }).join();
433     ///
434     /// assert!(result.is_err());
435     /// ```
436     #[stable(feature = "unicode_encode_char", since = "1.15.0")]
437     #[inline]
438     pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
439         let code = self as u32;
440         unsafe {
441             let len =
442             if code < MAX_ONE_B && !dst.is_empty() {
443                 *dst.get_unchecked_mut(0) = code as u8;
444                 1
445             } else if code < MAX_TWO_B && dst.len() >= 2 {
446                 *dst.get_unchecked_mut(0) = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
447                 *dst.get_unchecked_mut(1) = (code & 0x3F) as u8 | TAG_CONT;
448                 2
449             } else if code < MAX_THREE_B && dst.len() >= 3  {
450                 *dst.get_unchecked_mut(0) = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
451                 *dst.get_unchecked_mut(1) = (code >>  6 & 0x3F) as u8 | TAG_CONT;
452                 *dst.get_unchecked_mut(2) = (code & 0x3F) as u8 | TAG_CONT;
453                 3
454             } else if dst.len() >= 4 {
455                 *dst.get_unchecked_mut(0) = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
456                 *dst.get_unchecked_mut(1) = (code >> 12 & 0x3F) as u8 | TAG_CONT;
457                 *dst.get_unchecked_mut(2) = (code >>  6 & 0x3F) as u8 | TAG_CONT;
458                 *dst.get_unchecked_mut(3) = (code & 0x3F) as u8 | TAG_CONT;
459                 4
460             } else {
461                 panic!("encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}",
462                     from_u32_unchecked(code).len_utf8(),
463                     code,
464                     dst.len())
465             };
466             from_utf8_unchecked_mut(dst.get_unchecked_mut(..len))
467         }
468     }
469
470     /// Encodes this character as UTF-16 into the provided `u16` buffer,
471     /// and then returns the subslice of the buffer that contains the encoded character.
472     ///
473     /// # Panics
474     ///
475     /// Panics if the buffer is not large enough.
476     /// A buffer of length 2 is large enough to encode any `char`.
477     ///
478     /// # Examples
479     ///
480     /// In both of these examples, '𝕊' takes two `u16`s to encode.
481     ///
482     /// ```
483     /// let mut b = [0; 2];
484     ///
485     /// let result = '𝕊'.encode_utf16(&mut b);
486     ///
487     /// assert_eq!(result.len(), 2);
488     /// ```
489     ///
490     /// A buffer that's too small:
491     ///
492     /// ```
493     /// use std::thread;
494     ///
495     /// let result = thread::spawn(|| {
496     ///     let mut b = [0; 1];
497     ///
498     ///     // this panics
499     ///     '𝕊'.encode_utf16(&mut b);
500     /// }).join();
501     ///
502     /// assert!(result.is_err());
503     /// ```
504     #[stable(feature = "unicode_encode_char", since = "1.15.0")]
505     #[inline]
506     pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
507         let mut code = self as u32;
508         unsafe {
509             if (code & 0xFFFF) == code && !dst.is_empty() {
510                 // The BMP falls through (assuming non-surrogate, as it should)
511                 *dst.get_unchecked_mut(0) = code as u16;
512                 slice::from_raw_parts_mut(dst.as_mut_ptr(), 1)
513             } else if dst.len() >= 2 {
514                 // Supplementary planes break into surrogates.
515                 code -= 0x1_0000;
516                 *dst.get_unchecked_mut(0) = 0xD800 | ((code >> 10) as u16);
517                 *dst.get_unchecked_mut(1) = 0xDC00 | ((code as u16) & 0x3FF);
518                 slice::from_raw_parts_mut(dst.as_mut_ptr(), 2)
519             } else {
520                 panic!("encode_utf16: need {} units to encode U+{:X}, but the buffer has {}",
521                     from_u32_unchecked(code).len_utf16(),
522                     code,
523                     dst.len())
524             }
525         }
526     }
527
528     /// Returns true if this `char` is an alphabetic code point, and false if not.
529     ///
530     /// # Examples
531     ///
532     /// Basic usage:
533     ///
534     /// ```
535     /// assert!('a'.is_alphabetic());
536     /// assert!('京'.is_alphabetic());
537     ///
538     /// let c = '💝';
539     /// // love is many things, but it is not alphabetic
540     /// assert!(!c.is_alphabetic());
541     /// ```
542     #[stable(feature = "rust1", since = "1.0.0")]
543     #[inline]
544     pub fn is_alphabetic(self) -> bool {
545         match self {
546             'a'..='z' | 'A'..='Z' => true,
547             c if c > '\x7f' => derived_property::Alphabetic(c),
548             _ => false,
549         }
550     }
551
552     /// Returns true if this `char` satisfies the 'XID_Start' Unicode property, and false
553     /// otherwise.
554     ///
555     /// 'XID_Start' is a Unicode Derived Property specified in
556     /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
557     /// mostly similar to `ID_Start` but modified for closure under `NFKx`.
558     #[unstable(feature = "rustc_private",
559                reason = "mainly needed for compiler internals",
560                issue = "27812")]
561     #[inline]
562     pub fn is_xid_start(self) -> bool {
563         derived_property::XID_Start(self)
564     }
565
566     /// Returns true if this `char` satisfies the 'XID_Continue' Unicode property, and false
567     /// otherwise.
568     ///
569     /// 'XID_Continue' is a Unicode Derived Property specified in
570     /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
571     /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
572     #[unstable(feature = "rustc_private",
573                reason = "mainly needed for compiler internals",
574                issue = "27812")]
575     #[inline]
576     pub fn is_xid_continue(self) -> bool {
577         derived_property::XID_Continue(self)
578     }
579
580     /// Returns true if this `char` is lowercase, and false otherwise.
581     ///
582     /// 'Lowercase' is defined according to the terms of the Unicode Derived Core
583     /// Property `Lowercase`.
584     ///
585     /// # Examples
586     ///
587     /// Basic usage:
588     ///
589     /// ```
590     /// assert!('a'.is_lowercase());
591     /// assert!('δ'.is_lowercase());
592     /// assert!(!'A'.is_lowercase());
593     /// assert!(!'Δ'.is_lowercase());
594     ///
595     /// // The various Chinese scripts do not have case, and so:
596     /// assert!(!'中'.is_lowercase());
597     /// ```
598     #[stable(feature = "rust1", since = "1.0.0")]
599     #[inline]
600     pub fn is_lowercase(self) -> bool {
601         match self {
602             'a'..='z' => true,
603             c if c > '\x7f' => derived_property::Lowercase(c),
604             _ => false,
605         }
606     }
607
608     /// Returns true if this `char` is uppercase, and false otherwise.
609     ///
610     /// 'Uppercase' is defined according to the terms of the Unicode Derived Core
611     /// Property `Uppercase`.
612     ///
613     /// # Examples
614     ///
615     /// Basic usage:
616     ///
617     /// ```
618     /// assert!(!'a'.is_uppercase());
619     /// assert!(!'δ'.is_uppercase());
620     /// assert!('A'.is_uppercase());
621     /// assert!('Δ'.is_uppercase());
622     ///
623     /// // The various Chinese scripts do not have case, and so:
624     /// assert!(!'中'.is_uppercase());
625     /// ```
626     #[stable(feature = "rust1", since = "1.0.0")]
627     #[inline]
628     pub fn is_uppercase(self) -> bool {
629         match self {
630             'A'..='Z' => true,
631             c if c > '\x7f' => derived_property::Uppercase(c),
632             _ => false,
633         }
634     }
635
636     /// Returns true if this `char` is whitespace, and false otherwise.
637     ///
638     /// 'Whitespace' is defined according to the terms of the Unicode Derived Core
639     /// Property `White_Space`.
640     ///
641     /// # Examples
642     ///
643     /// Basic usage:
644     ///
645     /// ```
646     /// assert!(' '.is_whitespace());
647     ///
648     /// // a non-breaking space
649     /// assert!('\u{A0}'.is_whitespace());
650     ///
651     /// assert!(!'越'.is_whitespace());
652     /// ```
653     #[stable(feature = "rust1", since = "1.0.0")]
654     #[inline]
655     pub fn is_whitespace(self) -> bool {
656         match self {
657             ' ' | '\x09'..='\x0d' => true,
658             c if c > '\x7f' => property::White_Space(c),
659             _ => false,
660         }
661     }
662
663     /// Returns true if this `char` is alphanumeric, and false otherwise.
664     ///
665     /// 'Alphanumeric'-ness is defined in terms of the Unicode General Categories
666     /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
667     ///
668     /// # Examples
669     ///
670     /// Basic usage:
671     ///
672     /// ```
673     /// assert!('٣'.is_alphanumeric());
674     /// assert!('7'.is_alphanumeric());
675     /// assert!('৬'.is_alphanumeric());
676     /// assert!('¾'.is_alphanumeric());
677     /// assert!('①'.is_alphanumeric());
678     /// assert!('K'.is_alphanumeric());
679     /// assert!('و'.is_alphanumeric());
680     /// assert!('藏'.is_alphanumeric());
681     /// ```
682     #[stable(feature = "rust1", since = "1.0.0")]
683     #[inline]
684     pub fn is_alphanumeric(self) -> bool {
685         self.is_alphabetic() || self.is_numeric()
686     }
687
688     /// Returns true if this `char` is a control code point, and false otherwise.
689     ///
690     /// 'Control code point' is defined in terms of the Unicode General
691     /// Category `Cc`.
692     ///
693     /// # Examples
694     ///
695     /// Basic usage:
696     ///
697     /// ```
698     /// // U+009C, STRING TERMINATOR
699     /// assert!('\9c'.is_control());
700     /// assert!(!'q'.is_control());
701     /// ```
702     #[stable(feature = "rust1", since = "1.0.0")]
703     #[inline]
704     pub fn is_control(self) -> bool {
705         general_category::Cc(self)
706     }
707
708     /// Returns true if this `char` is an extended grapheme character, and false otherwise.
709     ///
710     /// 'Extended grapheme character' is defined in terms of the Unicode Shaping and Rendering
711     /// Category `Grapheme_Extend`.
712     #[inline]
713     pub(crate) fn is_grapheme_extended(self) -> bool {
714         derived_property::Grapheme_Extend(self)
715     }
716
717     /// Returns true if this `char` is numeric, and false otherwise.
718     ///
719     /// 'Numeric'-ness is defined in terms of the Unicode General Categories
720     /// 'Nd', 'Nl', 'No'.
721     ///
722     /// # Examples
723     ///
724     /// Basic usage:
725     ///
726     /// ```
727     /// assert!('٣'.is_numeric());
728     /// assert!('7'.is_numeric());
729     /// assert!('৬'.is_numeric());
730     /// assert!('¾'.is_numeric());
731     /// assert!('①'.is_numeric());
732     /// assert!(!'K'.is_numeric());
733     /// assert!(!'و'.is_numeric());
734     /// assert!(!'藏'.is_numeric());
735     /// ```
736     #[stable(feature = "rust1", since = "1.0.0")]
737     #[inline]
738     pub fn is_numeric(self) -> bool {
739         match self {
740             '0'..='9' => true,
741             c if c > '\x7f' => general_category::N(c),
742             _ => false,
743         }
744     }
745
746     /// Returns an iterator that yields the lowercase equivalent of a `char`
747     /// as one or more `char`s.
748     ///
749     /// If a character does not have a lowercase equivalent, the same character
750     /// will be returned back by the iterator.
751     ///
752     /// This performs complex unconditional mappings with no tailoring: it maps
753     /// one Unicode character to its lowercase equivalent according to the
754     /// [Unicode database] and the additional complex mappings
755     /// [`SpecialCasing.txt`]. Conditional mappings (based on context or
756     /// language) are not considered here.
757     ///
758     /// For a full reference, see [here][reference].
759     ///
760     /// [Unicode database]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
761     ///
762     /// [`SpecialCasing.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt
763     ///
764     /// [reference]: http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
765     ///
766     /// # Examples
767     ///
768     /// As an iterator:
769     ///
770     /// ```
771     /// for c in 'İ'.to_lowercase() {
772     ///     print!("{}", c);
773     /// }
774     /// println!();
775     /// ```
776     ///
777     /// Using `println!` directly:
778     ///
779     /// ```
780     /// println!("{}", 'İ'.to_lowercase());
781     /// ```
782     ///
783     /// Both are equivalent to:
784     ///
785     /// ```
786     /// println!("i\u{307}");
787     /// ```
788     ///
789     /// Using `to_string`:
790     ///
791     /// ```
792     /// assert_eq!('C'.to_lowercase().to_string(), "c");
793     ///
794     /// // Sometimes the result is more than one character:
795     /// assert_eq!('İ'.to_lowercase().to_string(), "i\u{307}");
796     ///
797     /// // Characters that do not have both uppercase and lowercase
798     /// // convert into themselves.
799     /// assert_eq!('山'.to_lowercase().to_string(), "山");
800     /// ```
801     #[stable(feature = "rust1", since = "1.0.0")]
802     #[inline]
803     pub fn to_lowercase(self) -> ToLowercase {
804         ToLowercase(CaseMappingIter::new(conversions::to_lower(self)))
805     }
806
807     /// Returns an iterator that yields the uppercase equivalent of a `char`
808     /// as one or more `char`s.
809     ///
810     /// If a character does not have an uppercase equivalent, the same character
811     /// will be returned back by the iterator.
812     ///
813     /// This performs complex unconditional mappings with no tailoring: it maps
814     /// one Unicode character to its uppercase equivalent according to the
815     /// [Unicode database] and the additional complex mappings
816     /// [`SpecialCasing.txt`]. Conditional mappings (based on context or
817     /// language) are not considered here.
818     ///
819     /// For a full reference, see [here][reference].
820     ///
821     /// [Unicode database]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
822     ///
823     /// [`SpecialCasing.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt
824     ///
825     /// [reference]: http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
826     ///
827     /// # Examples
828     ///
829     /// As an iterator:
830     ///
831     /// ```
832     /// for c in 'ß'.to_uppercase() {
833     ///     print!("{}", c);
834     /// }
835     /// println!();
836     /// ```
837     ///
838     /// Using `println!` directly:
839     ///
840     /// ```
841     /// println!("{}", 'ß'.to_uppercase());
842     /// ```
843     ///
844     /// Both are equivalent to:
845     ///
846     /// ```
847     /// println!("SS");
848     /// ```
849     ///
850     /// Using `to_string`:
851     ///
852     /// ```
853     /// assert_eq!('c'.to_uppercase().to_string(), "C");
854     ///
855     /// // Sometimes the result is more than one character:
856     /// assert_eq!('ß'.to_uppercase().to_string(), "SS");
857     ///
858     /// // Characters that do not have both uppercase and lowercase
859     /// // convert into themselves.
860     /// assert_eq!('山'.to_uppercase().to_string(), "山");
861     /// ```
862     ///
863     /// # Note on locale
864     ///
865     /// In Turkish, the equivalent of 'i' in Latin has five forms instead of two:
866     ///
867     /// * 'Dotless': I / ı, sometimes written ï
868     /// * 'Dotted': İ / i
869     ///
870     /// Note that the lowercase dotted 'i' is the same as the Latin. Therefore:
871     ///
872     /// ```
873     /// let upper_i = 'i'.to_uppercase().to_string();
874     /// ```
875     ///
876     /// The value of `upper_i` here relies on the language of the text: if we're
877     /// in `en-US`, it should be `"I"`, but if we're in `tr_TR`, it should
878     /// be `"İ"`. `to_uppercase()` does not take this into account, and so:
879     ///
880     /// ```
881     /// let upper_i = 'i'.to_uppercase().to_string();
882     ///
883     /// assert_eq!(upper_i, "I");
884     /// ```
885     ///
886     /// holds across languages.
887     #[stable(feature = "rust1", since = "1.0.0")]
888     #[inline]
889     pub fn to_uppercase(self) -> ToUppercase {
890         ToUppercase(CaseMappingIter::new(conversions::to_upper(self)))
891     }
892
893     /// Checks if the value is within the ASCII range.
894     ///
895     /// # Examples
896     ///
897     /// ```
898     /// let ascii = 'a';
899     /// let non_ascii = '❤';
900     ///
901     /// assert!(ascii.is_ascii());
902     /// assert!(!non_ascii.is_ascii());
903     /// ```
904     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
905     #[inline]
906     pub fn is_ascii(&self) -> bool {
907         *self as u32 <= 0x7F
908     }
909
910     /// Makes a copy of the value in its ASCII upper case equivalent.
911     ///
912     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
913     /// but non-ASCII letters are unchanged.
914     ///
915     /// To uppercase the value in-place, use [`make_ascii_uppercase`].
916     ///
917     /// To uppercase ASCII characters in addition to non-ASCII characters, use
918     /// [`to_uppercase`].
919     ///
920     /// # Examples
921     ///
922     /// ```
923     /// let ascii = 'a';
924     /// let non_ascii = '❤';
925     ///
926     /// assert_eq!('A', ascii.to_ascii_uppercase());
927     /// assert_eq!('❤', non_ascii.to_ascii_uppercase());
928     /// ```
929     ///
930     /// [`make_ascii_uppercase`]: #method.make_ascii_uppercase
931     /// [`to_uppercase`]: #method.to_uppercase
932     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
933     #[inline]
934     pub fn to_ascii_uppercase(&self) -> char {
935         if self.is_ascii() {
936             (*self as u8).to_ascii_uppercase() as char
937         } else {
938             *self
939         }
940     }
941
942     /// Makes a copy of the value in its ASCII lower case equivalent.
943     ///
944     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
945     /// but non-ASCII letters are unchanged.
946     ///
947     /// To lowercase the value in-place, use [`make_ascii_lowercase`].
948     ///
949     /// To lowercase ASCII characters in addition to non-ASCII characters, use
950     /// [`to_lowercase`].
951     ///
952     /// # Examples
953     ///
954     /// ```
955     /// let ascii = 'A';
956     /// let non_ascii = '❤';
957     ///
958     /// assert_eq!('a', ascii.to_ascii_lowercase());
959     /// assert_eq!('❤', non_ascii.to_ascii_lowercase());
960     /// ```
961     ///
962     /// [`make_ascii_lowercase`]: #method.make_ascii_lowercase
963     /// [`to_lowercase`]: #method.to_lowercase
964     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
965     #[inline]
966     pub fn to_ascii_lowercase(&self) -> char {
967         if self.is_ascii() {
968             (*self as u8).to_ascii_lowercase() as char
969         } else {
970             *self
971         }
972     }
973
974     /// Checks that two values are an ASCII case-insensitive match.
975     ///
976     /// Equivalent to `to_ascii_lowercase(a) == to_ascii_lowercase(b)`.
977     ///
978     /// # Examples
979     ///
980     /// ```
981     /// let upper_a = 'A';
982     /// let lower_a = 'a';
983     /// let lower_z = 'z';
984     ///
985     /// assert!(upper_a.eq_ignore_ascii_case(&lower_a));
986     /// assert!(upper_a.eq_ignore_ascii_case(&upper_a));
987     /// assert!(!upper_a.eq_ignore_ascii_case(&lower_z));
988     /// ```
989     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
990     #[inline]
991     pub fn eq_ignore_ascii_case(&self, other: &char) -> bool {
992         self.to_ascii_lowercase() == other.to_ascii_lowercase()
993     }
994
995     /// Converts this type to its ASCII upper case equivalent in-place.
996     ///
997     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
998     /// but non-ASCII letters are unchanged.
999     ///
1000     /// To return a new uppercased value without modifying the existing one, use
1001     /// [`to_ascii_uppercase`].
1002     ///
1003     /// # Examples
1004     ///
1005     /// ```
1006     /// let mut ascii = 'a';
1007     ///
1008     /// ascii.make_ascii_uppercase();
1009     ///
1010     /// assert_eq!('A', ascii);
1011     /// ```
1012     ///
1013     /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
1014     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1015     #[inline]
1016     pub fn make_ascii_uppercase(&mut self) {
1017         *self = self.to_ascii_uppercase();
1018     }
1019
1020     /// Converts this type to its ASCII lower case equivalent in-place.
1021     ///
1022     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
1023     /// but non-ASCII letters are unchanged.
1024     ///
1025     /// To return a new lowercased value without modifying the existing one, use
1026     /// [`to_ascii_lowercase`].
1027     ///
1028     /// # Examples
1029     ///
1030     /// ```
1031     /// let mut ascii = 'A';
1032     ///
1033     /// ascii.make_ascii_lowercase();
1034     ///
1035     /// assert_eq!('a', ascii);
1036     /// ```
1037     ///
1038     /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
1039     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1040     #[inline]
1041     pub fn make_ascii_lowercase(&mut self) {
1042         *self = self.to_ascii_lowercase();
1043     }
1044
1045     /// Checks if the value is an ASCII alphabetic character:
1046     ///
1047     /// - U+0041 'A' ... U+005A 'Z', or
1048     /// - U+0061 'a' ... U+007A 'z'.
1049     ///
1050     /// # Examples
1051     ///
1052     /// ```
1053     /// #![feature(ascii_ctype)]
1054     ///
1055     /// let uppercase_a = 'A';
1056     /// let uppercase_g = 'G';
1057     /// let a = 'a';
1058     /// let g = 'g';
1059     /// let zero = '0';
1060     /// let percent = '%';
1061     /// let space = ' ';
1062     /// let lf = '\n';
1063     /// let esc: char = 0x1b_u8.into();
1064     ///
1065     /// assert!(uppercase_a.is_ascii_alphabetic());
1066     /// assert!(uppercase_g.is_ascii_alphabetic());
1067     /// assert!(a.is_ascii_alphabetic());
1068     /// assert!(g.is_ascii_alphabetic());
1069     /// assert!(!zero.is_ascii_alphabetic());
1070     /// assert!(!percent.is_ascii_alphabetic());
1071     /// assert!(!space.is_ascii_alphabetic());
1072     /// assert!(!lf.is_ascii_alphabetic());
1073     /// assert!(!esc.is_ascii_alphabetic());
1074     /// ```
1075     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1076     #[inline]
1077     pub fn is_ascii_alphabetic(&self) -> bool {
1078         self.is_ascii() && (*self as u8).is_ascii_alphabetic()
1079     }
1080
1081     /// Checks if the value is an ASCII uppercase character:
1082     /// U+0041 'A' ... U+005A 'Z'.
1083     ///
1084     /// # Examples
1085     ///
1086     /// ```
1087     /// #![feature(ascii_ctype)]
1088     ///
1089     /// let uppercase_a = 'A';
1090     /// let uppercase_g = 'G';
1091     /// let a = 'a';
1092     /// let g = 'g';
1093     /// let zero = '0';
1094     /// let percent = '%';
1095     /// let space = ' ';
1096     /// let lf = '\n';
1097     /// let esc: char = 0x1b_u8.into();
1098     ///
1099     /// assert!(uppercase_a.is_ascii_uppercase());
1100     /// assert!(uppercase_g.is_ascii_uppercase());
1101     /// assert!(!a.is_ascii_uppercase());
1102     /// assert!(!g.is_ascii_uppercase());
1103     /// assert!(!zero.is_ascii_uppercase());
1104     /// assert!(!percent.is_ascii_uppercase());
1105     /// assert!(!space.is_ascii_uppercase());
1106     /// assert!(!lf.is_ascii_uppercase());
1107     /// assert!(!esc.is_ascii_uppercase());
1108     /// ```
1109     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1110     #[inline]
1111     pub fn is_ascii_uppercase(&self) -> bool {
1112         self.is_ascii() && (*self as u8).is_ascii_uppercase()
1113     }
1114
1115     /// Checks if the value is an ASCII lowercase character:
1116     /// U+0061 'a' ... U+007A 'z'.
1117     ///
1118     /// # Examples
1119     ///
1120     /// ```
1121     /// #![feature(ascii_ctype)]
1122     ///
1123     /// let uppercase_a = 'A';
1124     /// let uppercase_g = 'G';
1125     /// let a = 'a';
1126     /// let g = 'g';
1127     /// let zero = '0';
1128     /// let percent = '%';
1129     /// let space = ' ';
1130     /// let lf = '\n';
1131     /// let esc: char = 0x1b_u8.into();
1132     ///
1133     /// assert!(!uppercase_a.is_ascii_lowercase());
1134     /// assert!(!uppercase_g.is_ascii_lowercase());
1135     /// assert!(a.is_ascii_lowercase());
1136     /// assert!(g.is_ascii_lowercase());
1137     /// assert!(!zero.is_ascii_lowercase());
1138     /// assert!(!percent.is_ascii_lowercase());
1139     /// assert!(!space.is_ascii_lowercase());
1140     /// assert!(!lf.is_ascii_lowercase());
1141     /// assert!(!esc.is_ascii_lowercase());
1142     /// ```
1143     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1144     #[inline]
1145     pub fn is_ascii_lowercase(&self) -> bool {
1146         self.is_ascii() && (*self as u8).is_ascii_lowercase()
1147     }
1148
1149     /// Checks if the value is an ASCII alphanumeric character:
1150     ///
1151     /// - U+0041 'A' ... U+005A 'Z', or
1152     /// - U+0061 'a' ... U+007A 'z', or
1153     /// - U+0030 '0' ... U+0039 '9'.
1154     ///
1155     /// # Examples
1156     ///
1157     /// ```
1158     /// #![feature(ascii_ctype)]
1159     ///
1160     /// let uppercase_a = 'A';
1161     /// let uppercase_g = 'G';
1162     /// let a = 'a';
1163     /// let g = 'g';
1164     /// let zero = '0';
1165     /// let percent = '%';
1166     /// let space = ' ';
1167     /// let lf = '\n';
1168     /// let esc: char = 0x1b_u8.into();
1169     ///
1170     /// assert!(uppercase_a.is_ascii_alphanumeric());
1171     /// assert!(uppercase_g.is_ascii_alphanumeric());
1172     /// assert!(a.is_ascii_alphanumeric());
1173     /// assert!(g.is_ascii_alphanumeric());
1174     /// assert!(zero.is_ascii_alphanumeric());
1175     /// assert!(!percent.is_ascii_alphanumeric());
1176     /// assert!(!space.is_ascii_alphanumeric());
1177     /// assert!(!lf.is_ascii_alphanumeric());
1178     /// assert!(!esc.is_ascii_alphanumeric());
1179     /// ```
1180     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1181     #[inline]
1182     pub fn is_ascii_alphanumeric(&self) -> bool {
1183         self.is_ascii() && (*self as u8).is_ascii_alphanumeric()
1184     }
1185
1186     /// Checks if the value is an ASCII decimal digit:
1187     /// U+0030 '0' ... U+0039 '9'.
1188     ///
1189     /// # Examples
1190     ///
1191     /// ```
1192     /// #![feature(ascii_ctype)]
1193     ///
1194     /// let uppercase_a = 'A';
1195     /// let uppercase_g = 'G';
1196     /// let a = 'a';
1197     /// let g = 'g';
1198     /// let zero = '0';
1199     /// let percent = '%';
1200     /// let space = ' ';
1201     /// let lf = '\n';
1202     /// let esc: char = 0x1b_u8.into();
1203     ///
1204     /// assert!(!uppercase_a.is_ascii_digit());
1205     /// assert!(!uppercase_g.is_ascii_digit());
1206     /// assert!(!a.is_ascii_digit());
1207     /// assert!(!g.is_ascii_digit());
1208     /// assert!(zero.is_ascii_digit());
1209     /// assert!(!percent.is_ascii_digit());
1210     /// assert!(!space.is_ascii_digit());
1211     /// assert!(!lf.is_ascii_digit());
1212     /// assert!(!esc.is_ascii_digit());
1213     /// ```
1214     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1215     #[inline]
1216     pub fn is_ascii_digit(&self) -> bool {
1217         self.is_ascii() && (*self as u8).is_ascii_digit()
1218     }
1219
1220     /// Checks if the value is an ASCII hexadecimal digit:
1221     ///
1222     /// - U+0030 '0' ... U+0039 '9', or
1223     /// - U+0041 'A' ... U+0046 'F', or
1224     /// - U+0061 'a' ... U+0066 'f'.
1225     ///
1226     /// # Examples
1227     ///
1228     /// ```
1229     /// #![feature(ascii_ctype)]
1230     ///
1231     /// let uppercase_a = 'A';
1232     /// let uppercase_g = 'G';
1233     /// let a = 'a';
1234     /// let g = 'g';
1235     /// let zero = '0';
1236     /// let percent = '%';
1237     /// let space = ' ';
1238     /// let lf = '\n';
1239     /// let esc: char = 0x1b_u8.into();
1240     ///
1241     /// assert!(uppercase_a.is_ascii_hexdigit());
1242     /// assert!(!uppercase_g.is_ascii_hexdigit());
1243     /// assert!(a.is_ascii_hexdigit());
1244     /// assert!(!g.is_ascii_hexdigit());
1245     /// assert!(zero.is_ascii_hexdigit());
1246     /// assert!(!percent.is_ascii_hexdigit());
1247     /// assert!(!space.is_ascii_hexdigit());
1248     /// assert!(!lf.is_ascii_hexdigit());
1249     /// assert!(!esc.is_ascii_hexdigit());
1250     /// ```
1251     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1252     #[inline]
1253     pub fn is_ascii_hexdigit(&self) -> bool {
1254         self.is_ascii() && (*self as u8).is_ascii_hexdigit()
1255     }
1256
1257     /// Checks if the value is an ASCII punctuation character:
1258     ///
1259     /// - U+0021 ... U+002F `! " # $ % & ' ( ) * + , - . /`, or
1260     /// - U+003A ... U+0040 `: ; < = > ? @`, or
1261     /// - U+005B ... U+0060 ``[ \ ] ^ _ ` ``, or
1262     /// - U+007B ... U+007E `{ | } ~`
1263     ///
1264     /// # Examples
1265     ///
1266     /// ```
1267     /// #![feature(ascii_ctype)]
1268     ///
1269     /// let uppercase_a = 'A';
1270     /// let uppercase_g = 'G';
1271     /// let a = 'a';
1272     /// let g = 'g';
1273     /// let zero = '0';
1274     /// let percent = '%';
1275     /// let space = ' ';
1276     /// let lf = '\n';
1277     /// let esc: char = 0x1b_u8.into();
1278     ///
1279     /// assert!(!uppercase_a.is_ascii_punctuation());
1280     /// assert!(!uppercase_g.is_ascii_punctuation());
1281     /// assert!(!a.is_ascii_punctuation());
1282     /// assert!(!g.is_ascii_punctuation());
1283     /// assert!(!zero.is_ascii_punctuation());
1284     /// assert!(percent.is_ascii_punctuation());
1285     /// assert!(!space.is_ascii_punctuation());
1286     /// assert!(!lf.is_ascii_punctuation());
1287     /// assert!(!esc.is_ascii_punctuation());
1288     /// ```
1289     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1290     #[inline]
1291     pub fn is_ascii_punctuation(&self) -> bool {
1292         self.is_ascii() && (*self as u8).is_ascii_punctuation()
1293     }
1294
1295     /// Checks if the value is an ASCII graphic character:
1296     /// U+0021 '!' ... U+007E '~'.
1297     ///
1298     /// # Examples
1299     ///
1300     /// ```
1301     /// #![feature(ascii_ctype)]
1302     ///
1303     /// let uppercase_a = 'A';
1304     /// let uppercase_g = 'G';
1305     /// let a = 'a';
1306     /// let g = 'g';
1307     /// let zero = '0';
1308     /// let percent = '%';
1309     /// let space = ' ';
1310     /// let lf = '\n';
1311     /// let esc: char = 0x1b_u8.into();
1312     ///
1313     /// assert!(uppercase_a.is_ascii_graphic());
1314     /// assert!(uppercase_g.is_ascii_graphic());
1315     /// assert!(a.is_ascii_graphic());
1316     /// assert!(g.is_ascii_graphic());
1317     /// assert!(zero.is_ascii_graphic());
1318     /// assert!(percent.is_ascii_graphic());
1319     /// assert!(!space.is_ascii_graphic());
1320     /// assert!(!lf.is_ascii_graphic());
1321     /// assert!(!esc.is_ascii_graphic());
1322     /// ```
1323     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1324     #[inline]
1325     pub fn is_ascii_graphic(&self) -> bool {
1326         self.is_ascii() && (*self as u8).is_ascii_graphic()
1327     }
1328
1329     /// Checks if the value is an ASCII whitespace character:
1330     /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED,
1331     /// U+000C FORM FEED, or U+000D CARRIAGE RETURN.
1332     ///
1333     /// Rust uses the WhatWG Infra Standard's [definition of ASCII
1334     /// whitespace][infra-aw]. There are several other definitions in
1335     /// wide use. For instance, [the POSIX locale][pct] includes
1336     /// U+000B VERTICAL TAB as well as all the above characters,
1337     /// but—from the very same specification—[the default rule for
1338     /// "field splitting" in the Bourne shell][bfs] considers *only*
1339     /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
1340     ///
1341     /// If you are writing a program that will process an existing
1342     /// file format, check what that format's definition of whitespace is
1343     /// before using this function.
1344     ///
1345     /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
1346     /// [pct]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
1347     /// [bfs]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
1348     ///
1349     /// # Examples
1350     ///
1351     /// ```
1352     /// #![feature(ascii_ctype)]
1353     ///
1354     /// let uppercase_a = 'A';
1355     /// let uppercase_g = 'G';
1356     /// let a = 'a';
1357     /// let g = 'g';
1358     /// let zero = '0';
1359     /// let percent = '%';
1360     /// let space = ' ';
1361     /// let lf = '\n';
1362     /// let esc: char = 0x1b_u8.into();
1363     ///
1364     /// assert!(!uppercase_a.is_ascii_whitespace());
1365     /// assert!(!uppercase_g.is_ascii_whitespace());
1366     /// assert!(!a.is_ascii_whitespace());
1367     /// assert!(!g.is_ascii_whitespace());
1368     /// assert!(!zero.is_ascii_whitespace());
1369     /// assert!(!percent.is_ascii_whitespace());
1370     /// assert!(space.is_ascii_whitespace());
1371     /// assert!(lf.is_ascii_whitespace());
1372     /// assert!(!esc.is_ascii_whitespace());
1373     /// ```
1374     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1375     #[inline]
1376     pub fn is_ascii_whitespace(&self) -> bool {
1377         self.is_ascii() && (*self as u8).is_ascii_whitespace()
1378     }
1379
1380     /// Checks if the value is an ASCII control character:
1381     /// U+0000 NUL ... U+001F UNIT SEPARATOR, or U+007F DELETE.
1382     /// Note that most ASCII whitespace characters are control
1383     /// characters, but SPACE is not.
1384     ///
1385     /// # Examples
1386     ///
1387     /// ```
1388     /// #![feature(ascii_ctype)]
1389     ///
1390     /// let uppercase_a = 'A';
1391     /// let uppercase_g = 'G';
1392     /// let a = 'a';
1393     /// let g = 'g';
1394     /// let zero = '0';
1395     /// let percent = '%';
1396     /// let space = ' ';
1397     /// let lf = '\n';
1398     /// let esc: char = 0x1b_u8.into();
1399     ///
1400     /// assert!(!uppercase_a.is_ascii_control());
1401     /// assert!(!uppercase_g.is_ascii_control());
1402     /// assert!(!a.is_ascii_control());
1403     /// assert!(!g.is_ascii_control());
1404     /// assert!(!zero.is_ascii_control());
1405     /// assert!(!percent.is_ascii_control());
1406     /// assert!(!space.is_ascii_control());
1407     /// assert!(lf.is_ascii_control());
1408     /// assert!(esc.is_ascii_control());
1409     /// ```
1410     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1411     #[inline]
1412     pub fn is_ascii_control(&self) -> bool {
1413         self.is_ascii() && (*self as u8).is_ascii_control()
1414     }
1415 }