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