]> git.lizzy.rs Git - rust.git/blob - src/libcore/char/methods.rs
FIX - Char documentation for unexperienced users
[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::{self, conversions};
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         let len = self.len_utf8();
438         match (len, &mut dst[..]) {
439             (1, [a, ..]) => {
440                 *a = code as u8;
441             }
442             (2, [a, b, ..]) => {
443                 *a = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
444                 *b = (code & 0x3F) as u8 | TAG_CONT;
445             }
446             (3, [a, b, c, ..]) => {
447                 *a = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
448                 *b = (code >> 6 & 0x3F) as u8 | TAG_CONT;
449                 *c = (code & 0x3F) as u8 | TAG_CONT;
450             }
451             (4, [a, b, c, d, ..]) => {
452                 *a = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
453                 *b = (code >> 12 & 0x3F) as u8 | TAG_CONT;
454                 *c = (code >> 6 & 0x3F) as u8 | TAG_CONT;
455                 *d = (code & 0x3F) as u8 | TAG_CONT;
456             }
457             _ => panic!(
458                 "encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}",
459                 len,
460                 code,
461                 dst.len(),
462             ),
463         };
464         // SAFETY: We just wrote UTF-8 content in, so converting to str is fine.
465         unsafe { from_utf8_unchecked_mut(&mut dst[..len]) }
466     }
467
468     /// Encodes this character as UTF-16 into the provided `u16` buffer,
469     /// and then returns the subslice of the buffer that contains the encoded character.
470     ///
471     /// # Panics
472     ///
473     /// Panics if the buffer is not large enough.
474     /// A buffer of length 2 is large enough to encode any `char`.
475     ///
476     /// # Examples
477     ///
478     /// In both of these examples, '𝕊' takes two `u16`s to encode.
479     ///
480     /// ```
481     /// let mut b = [0; 2];
482     ///
483     /// let result = '𝕊'.encode_utf16(&mut b);
484     ///
485     /// assert_eq!(result.len(), 2);
486     /// ```
487     ///
488     /// A buffer that's too small:
489     ///
490     /// ```
491     /// use std::thread;
492     ///
493     /// let result = thread::spawn(|| {
494     ///     let mut b = [0; 1];
495     ///
496     ///     // this panics
497     ///     '𝕊'.encode_utf16(&mut b);
498     /// }).join();
499     ///
500     /// assert!(result.is_err());
501     /// ```
502     #[stable(feature = "unicode_encode_char", since = "1.15.0")]
503     #[inline]
504     pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
505         let mut code = self as u32;
506         // SAFETY: each arm checks whether there are enough bits to write into
507         unsafe {
508             if (code & 0xFFFF) == code && !dst.is_empty() {
509                 // The BMP falls through (assuming non-surrogate, as it should)
510                 *dst.get_unchecked_mut(0) = code as u16;
511                 slice::from_raw_parts_mut(dst.as_mut_ptr(), 1)
512             } else if dst.len() >= 2 {
513                 // Supplementary planes break into surrogates.
514                 code -= 0x1_0000;
515                 *dst.get_unchecked_mut(0) = 0xD800 | ((code >> 10) as u16);
516                 *dst.get_unchecked_mut(1) = 0xDC00 | ((code as u16) & 0x3FF);
517                 slice::from_raw_parts_mut(dst.as_mut_ptr(), 2)
518             } else {
519                 panic!(
520                     "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
529     /// Returns `true` if this `char` has the `Alphabetic` property.
530     ///
531     /// `Alphabetic` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and
532     /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`].
533     ///
534     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
535     /// [ucd]: https://www.unicode.org/reports/tr44/
536     /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
537     ///
538     /// # Examples
539     ///
540     /// Basic usage:
541     ///
542     /// ```
543     /// assert!('a'.is_alphabetic());
544     /// assert!('京'.is_alphabetic());
545     ///
546     /// let c = '💝';
547     /// // love is many things, but it is not alphabetic
548     /// assert!(!c.is_alphabetic());
549     /// ```
550     #[stable(feature = "rust1", since = "1.0.0")]
551     #[inline]
552     pub fn is_alphabetic(self) -> bool {
553         match self {
554             'a'..='z' | 'A'..='Z' => true,
555             c => c > '\x7f' && unicode::Alphabetic(c),
556         }
557     }
558
559     /// Returns `true` if this `char` has the `Lowercase` property.
560     ///
561     /// `Lowercase` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and
562     /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`].
563     ///
564     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
565     /// [ucd]: https://www.unicode.org/reports/tr44/
566     /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
567     ///
568     /// # Examples
569     ///
570     /// Basic usage:
571     ///
572     /// ```
573     /// assert!('a'.is_lowercase());
574     /// assert!('δ'.is_lowercase());
575     /// assert!(!'A'.is_lowercase());
576     /// assert!(!'Δ'.is_lowercase());
577     ///
578     /// // The various Chinese scripts and punctuation do not have case, and so:
579     /// assert!(!'中'.is_lowercase());
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' && unicode::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 and punctuation do not have case, and so:
611     /// assert!(!'中'.is_uppercase());
612     /// assert!(!' '.is_uppercase());
613     /// ```
614     #[stable(feature = "rust1", since = "1.0.0")]
615     #[inline]
616     pub fn is_uppercase(self) -> bool {
617         match self {
618             'A'..='Z' => true,
619             c => c > '\x7f' && unicode::Uppercase(c),
620         }
621     }
622
623     /// Returns `true` if this `char` has the `White_Space` property.
624     ///
625     /// `White_Space` is specified in the [Unicode Character Database][ucd] [`PropList.txt`].
626     ///
627     /// [ucd]: https://www.unicode.org/reports/tr44/
628     /// [`PropList.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt
629     ///
630     /// # Examples
631     ///
632     /// Basic usage:
633     ///
634     /// ```
635     /// assert!(' '.is_whitespace());
636     ///
637     /// // a non-breaking space
638     /// assert!('\u{A0}'.is_whitespace());
639     ///
640     /// assert!(!'越'.is_whitespace());
641     /// ```
642     #[stable(feature = "rust1", since = "1.0.0")]
643     #[inline]
644     pub fn is_whitespace(self) -> bool {
645         match self {
646             ' ' | '\x09'..='\x0d' => true,
647             c => c > '\x7f' && unicode::White_Space(c),
648         }
649     }
650
651     /// Returns `true` if this `char` satisfies either [`is_alphabetic()`] or [`is_numeric()`].
652     ///
653     /// [`is_alphabetic()`]: #method.is_alphabetic
654     /// [`is_numeric()`]: #method.is_numeric
655     ///
656     /// # Examples
657     ///
658     /// Basic usage:
659     ///
660     /// ```
661     /// assert!('٣'.is_alphanumeric());
662     /// assert!('7'.is_alphanumeric());
663     /// assert!('৬'.is_alphanumeric());
664     /// assert!('¾'.is_alphanumeric());
665     /// assert!('①'.is_alphanumeric());
666     /// assert!('K'.is_alphanumeric());
667     /// assert!('و'.is_alphanumeric());
668     /// assert!('藏'.is_alphanumeric());
669     /// ```
670     #[stable(feature = "rust1", since = "1.0.0")]
671     #[inline]
672     pub fn is_alphanumeric(self) -> bool {
673         self.is_alphabetic() || self.is_numeric()
674     }
675
676     /// Returns `true` if this `char` has the general category for control codes.
677     ///
678     /// Control codes (code points with the general category of `Cc`) are described in Chapter 4
679     /// (Character Properties) of the [Unicode Standard] and specified in the [Unicode Character
680     /// Database][ucd] [`UnicodeData.txt`].
681     ///
682     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
683     /// [ucd]: https://www.unicode.org/reports/tr44/
684     /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
685     ///
686     /// # Examples
687     ///
688     /// Basic usage:
689     ///
690     /// ```
691     /// // U+009C, STRING TERMINATOR
692     /// assert!('\9c'.is_control());
693     /// assert!(!'q'.is_control());
694     /// ```
695     #[stable(feature = "rust1", since = "1.0.0")]
696     #[inline]
697     pub fn is_control(self) -> bool {
698         unicode::Cc(self)
699     }
700
701     /// Returns `true` if this `char` has the `Grapheme_Extend` property.
702     ///
703     /// `Grapheme_Extend` is described in [Unicode Standard Annex #29 (Unicode Text
704     /// Segmentation)][uax29] and specified in the [Unicode Character Database][ucd]
705     /// [`DerivedCoreProperties.txt`].
706     ///
707     /// [uax29]: https://www.unicode.org/reports/tr29/
708     /// [ucd]: https://www.unicode.org/reports/tr44/
709     /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
710     #[inline]
711     pub(crate) fn is_grapheme_extended(self) -> bool {
712         unicode::Grapheme_Extend(self)
713     }
714
715     /// Returns `true` if this `char` has one of the general categories for numbers.
716     ///
717     /// The general categories for numbers (`Nd` for decimal digits, `Nl` for letter-like numeric
718     /// characters, and `No` for other numeric characters) are specified in the [Unicode Character
719     /// Database][ucd] [`UnicodeData.txt`].
720     ///
721     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
722     /// [ucd]: https://www.unicode.org/reports/tr44/
723     /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
724     ///
725     /// # Examples
726     ///
727     /// Basic usage:
728     ///
729     /// ```
730     /// assert!('٣'.is_numeric());
731     /// assert!('7'.is_numeric());
732     /// assert!('৬'.is_numeric());
733     /// assert!('¾'.is_numeric());
734     /// assert!('①'.is_numeric());
735     /// assert!(!'K'.is_numeric());
736     /// assert!(!'و'.is_numeric());
737     /// assert!(!'藏'.is_numeric());
738     /// ```
739     #[stable(feature = "rust1", since = "1.0.0")]
740     #[inline]
741     pub fn is_numeric(self) -> bool {
742         match self {
743             '0'..='9' => true,
744             c => c > '\x7f' && unicode::N(c),
745         }
746     }
747
748     /// Returns an iterator that yields the lowercase mapping of this `char` as one or more
749     /// `char`s.
750     ///
751     /// If this `char` does not have a lowercase mapping, the iterator yields the same `char`.
752     ///
753     /// If this `char` has a one-to-one lowercase mapping given by the [Unicode Character
754     /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`.
755     ///
756     /// [ucd]: https://www.unicode.org/reports/tr44/
757     /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
758     ///
759     /// If this `char` requires special considerations (e.g. multiple `char`s) the iterator yields
760     /// the `char`(s) given by [`SpecialCasing.txt`].
761     ///
762     /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
763     ///
764     /// This operation performs an unconditional mapping without tailoring. That is, the conversion
765     /// is independent of context and language.
766     ///
767     /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in
768     /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion.
769     ///
770     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
771     ///
772     /// # Examples
773     ///
774     /// As an iterator:
775     ///
776     /// ```
777     /// for c in 'İ'.to_lowercase() {
778     ///     print!("{}", c);
779     /// }
780     /// println!();
781     /// ```
782     ///
783     /// Using `println!` directly:
784     ///
785     /// ```
786     /// println!("{}", 'İ'.to_lowercase());
787     /// ```
788     ///
789     /// Both are equivalent to:
790     ///
791     /// ```
792     /// println!("i\u{307}");
793     /// ```
794     ///
795     /// Using `to_string`:
796     ///
797     /// ```
798     /// assert_eq!('C'.to_lowercase().to_string(), "c");
799     ///
800     /// // Sometimes the result is more than one character:
801     /// assert_eq!('İ'.to_lowercase().to_string(), "i\u{307}");
802     ///
803     /// // Characters that do not have both uppercase and lowercase
804     /// // convert into themselves.
805     /// assert_eq!('山'.to_lowercase().to_string(), "山");
806     /// ```
807     #[stable(feature = "rust1", since = "1.0.0")]
808     #[inline]
809     pub fn to_lowercase(self) -> ToLowercase {
810         ToLowercase(CaseMappingIter::new(conversions::to_lower(self)))
811     }
812
813     /// Returns an iterator that yields the uppercase mapping of this `char` as one or more
814     /// `char`s.
815     ///
816     /// If this `char` does not have a uppercase mapping, the iterator yields the same `char`.
817     ///
818     /// If this `char` has a one-to-one uppercase mapping given by the [Unicode Character
819     /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`.
820     ///
821     /// [ucd]: https://www.unicode.org/reports/tr44/
822     /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
823     ///
824     /// If this `char` requires special considerations (e.g. multiple `char`s) the iterator yields
825     /// the `char`(s) given by [`SpecialCasing.txt`].
826     ///
827     /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
828     ///
829     /// This operation performs an unconditional mapping without tailoring. That is, the conversion
830     /// is independent of context and language.
831     ///
832     /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in
833     /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion.
834     ///
835     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
836     ///
837     /// # Examples
838     ///
839     /// As an iterator:
840     ///
841     /// ```
842     /// for c in 'ß'.to_uppercase() {
843     ///     print!("{}", c);
844     /// }
845     /// println!();
846     /// ```
847     ///
848     /// Using `println!` directly:
849     ///
850     /// ```
851     /// println!("{}", 'ß'.to_uppercase());
852     /// ```
853     ///
854     /// Both are equivalent to:
855     ///
856     /// ```
857     /// println!("SS");
858     /// ```
859     ///
860     /// Using `to_string`:
861     ///
862     /// ```
863     /// assert_eq!('c'.to_uppercase().to_string(), "C");
864     ///
865     /// // Sometimes the result is more than one character:
866     /// assert_eq!('ß'.to_uppercase().to_string(), "SS");
867     ///
868     /// // Characters that do not have both uppercase and lowercase
869     /// // convert into themselves.
870     /// assert_eq!('山'.to_uppercase().to_string(), "山");
871     /// ```
872     ///
873     /// # Note on locale
874     ///
875     /// In Turkish, the equivalent of 'i' in Latin has five forms instead of two:
876     ///
877     /// * 'Dotless': I / ı, sometimes written ï
878     /// * 'Dotted': İ / i
879     ///
880     /// Note that the lowercase dotted 'i' is the same as the Latin. Therefore:
881     ///
882     /// ```
883     /// let upper_i = 'i'.to_uppercase().to_string();
884     /// ```
885     ///
886     /// The value of `upper_i` here relies on the language of the text: if we're
887     /// in `en-US`, it should be `"I"`, but if we're in `tr_TR`, it should
888     /// be `"İ"`. `to_uppercase()` does not take this into account, and so:
889     ///
890     /// ```
891     /// let upper_i = 'i'.to_uppercase().to_string();
892     ///
893     /// assert_eq!(upper_i, "I");
894     /// ```
895     ///
896     /// holds across languages.
897     #[stable(feature = "rust1", since = "1.0.0")]
898     #[inline]
899     pub fn to_uppercase(self) -> ToUppercase {
900         ToUppercase(CaseMappingIter::new(conversions::to_upper(self)))
901     }
902
903     /// Checks if the value is within the ASCII range.
904     ///
905     /// # Examples
906     ///
907     /// ```
908     /// let ascii = 'a';
909     /// let non_ascii = '❤';
910     ///
911     /// assert!(ascii.is_ascii());
912     /// assert!(!non_ascii.is_ascii());
913     /// ```
914     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
915     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.32.0")]
916     #[inline]
917     pub const fn is_ascii(&self) -> bool {
918         *self as u32 <= 0x7F
919     }
920
921     /// Makes a copy of the value in its ASCII upper case equivalent.
922     ///
923     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
924     /// but non-ASCII letters are unchanged.
925     ///
926     /// To uppercase the value in-place, use [`make_ascii_uppercase`].
927     ///
928     /// To uppercase ASCII characters in addition to non-ASCII characters, use
929     /// [`to_uppercase`].
930     ///
931     /// # Examples
932     ///
933     /// ```
934     /// let ascii = 'a';
935     /// let non_ascii = '❤';
936     ///
937     /// assert_eq!('A', ascii.to_ascii_uppercase());
938     /// assert_eq!('❤', non_ascii.to_ascii_uppercase());
939     /// ```
940     ///
941     /// [`make_ascii_uppercase`]: #method.make_ascii_uppercase
942     /// [`to_uppercase`]: #method.to_uppercase
943     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
944     #[inline]
945     pub fn to_ascii_uppercase(&self) -> char {
946         if self.is_ascii() { (*self as u8).to_ascii_uppercase() as char } else { *self }
947     }
948
949     /// Makes a copy of the value in its ASCII lower case equivalent.
950     ///
951     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
952     /// but non-ASCII letters are unchanged.
953     ///
954     /// To lowercase the value in-place, use [`make_ascii_lowercase`].
955     ///
956     /// To lowercase ASCII characters in addition to non-ASCII characters, use
957     /// [`to_lowercase`].
958     ///
959     /// # Examples
960     ///
961     /// ```
962     /// let ascii = 'A';
963     /// let non_ascii = '❤';
964     ///
965     /// assert_eq!('a', ascii.to_ascii_lowercase());
966     /// assert_eq!('❤', non_ascii.to_ascii_lowercase());
967     /// ```
968     ///
969     /// [`make_ascii_lowercase`]: #method.make_ascii_lowercase
970     /// [`to_lowercase`]: #method.to_lowercase
971     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
972     #[inline]
973     pub fn to_ascii_lowercase(&self) -> char {
974         if self.is_ascii() { (*self as u8).to_ascii_lowercase() as char } else { *self }
975     }
976
977     /// Checks that two values are an ASCII case-insensitive match.
978     ///
979     /// Equivalent to `to_ascii_lowercase(a) == to_ascii_lowercase(b)`.
980     ///
981     /// # Examples
982     ///
983     /// ```
984     /// let upper_a = 'A';
985     /// let lower_a = 'a';
986     /// let lower_z = 'z';
987     ///
988     /// assert!(upper_a.eq_ignore_ascii_case(&lower_a));
989     /// assert!(upper_a.eq_ignore_ascii_case(&upper_a));
990     /// assert!(!upper_a.eq_ignore_ascii_case(&lower_z));
991     /// ```
992     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
993     #[inline]
994     pub fn eq_ignore_ascii_case(&self, other: &char) -> bool {
995         self.to_ascii_lowercase() == other.to_ascii_lowercase()
996     }
997
998     /// Converts this type to its ASCII upper case equivalent in-place.
999     ///
1000     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
1001     /// but non-ASCII letters are unchanged.
1002     ///
1003     /// To return a new uppercased value without modifying the existing one, use
1004     /// [`to_ascii_uppercase`].
1005     ///
1006     /// # Examples
1007     ///
1008     /// ```
1009     /// let mut ascii = 'a';
1010     ///
1011     /// ascii.make_ascii_uppercase();
1012     ///
1013     /// assert_eq!('A', ascii);
1014     /// ```
1015     ///
1016     /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
1017     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1018     #[inline]
1019     pub fn make_ascii_uppercase(&mut self) {
1020         *self = self.to_ascii_uppercase();
1021     }
1022
1023     /// Converts this type to its ASCII lower case equivalent in-place.
1024     ///
1025     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
1026     /// but non-ASCII letters are unchanged.
1027     ///
1028     /// To return a new lowercased value without modifying the existing one, use
1029     /// [`to_ascii_lowercase`].
1030     ///
1031     /// # Examples
1032     ///
1033     /// ```
1034     /// let mut ascii = 'A';
1035     ///
1036     /// ascii.make_ascii_lowercase();
1037     ///
1038     /// assert_eq!('a', ascii);
1039     /// ```
1040     ///
1041     /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
1042     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1043     #[inline]
1044     pub fn make_ascii_lowercase(&mut self) {
1045         *self = self.to_ascii_lowercase();
1046     }
1047
1048     /// Checks if the value is an ASCII alphabetic character:
1049     ///
1050     /// - U+0041 'A' ..= U+005A 'Z', or
1051     /// - U+0061 'a' ..= U+007A 'z'.
1052     ///
1053     /// # Examples
1054     ///
1055     /// ```
1056     /// let uppercase_a = 'A';
1057     /// let uppercase_g = 'G';
1058     /// let a = 'a';
1059     /// let g = 'g';
1060     /// let zero = '0';
1061     /// let percent = '%';
1062     /// let space = ' ';
1063     /// let lf = '\n';
1064     /// let esc: char = 0x1b_u8.into();
1065     ///
1066     /// assert!(uppercase_a.is_ascii_alphabetic());
1067     /// assert!(uppercase_g.is_ascii_alphabetic());
1068     /// assert!(a.is_ascii_alphabetic());
1069     /// assert!(g.is_ascii_alphabetic());
1070     /// assert!(!zero.is_ascii_alphabetic());
1071     /// assert!(!percent.is_ascii_alphabetic());
1072     /// assert!(!space.is_ascii_alphabetic());
1073     /// assert!(!lf.is_ascii_alphabetic());
1074     /// assert!(!esc.is_ascii_alphabetic());
1075     /// ```
1076     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1077     #[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
1078     #[inline]
1079     pub const fn is_ascii_alphabetic(&self) -> bool {
1080         match *self {
1081             'A'..='Z' | 'a'..='z' => true,
1082             _ => false,
1083         }
1084     }
1085
1086     /// Checks if the value is an ASCII uppercase character:
1087     /// U+0041 'A' ..= U+005A 'Z'.
1088     ///
1089     /// # Examples
1090     ///
1091     /// ```
1092     /// let uppercase_a = 'A';
1093     /// let uppercase_g = 'G';
1094     /// let a = 'a';
1095     /// let g = 'g';
1096     /// let zero = '0';
1097     /// let percent = '%';
1098     /// let space = ' ';
1099     /// let lf = '\n';
1100     /// let esc: char = 0x1b_u8.into();
1101     ///
1102     /// assert!(uppercase_a.is_ascii_uppercase());
1103     /// assert!(uppercase_g.is_ascii_uppercase());
1104     /// assert!(!a.is_ascii_uppercase());
1105     /// assert!(!g.is_ascii_uppercase());
1106     /// assert!(!zero.is_ascii_uppercase());
1107     /// assert!(!percent.is_ascii_uppercase());
1108     /// assert!(!space.is_ascii_uppercase());
1109     /// assert!(!lf.is_ascii_uppercase());
1110     /// assert!(!esc.is_ascii_uppercase());
1111     /// ```
1112     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1113     #[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
1114     #[inline]
1115     pub const fn is_ascii_uppercase(&self) -> bool {
1116         match *self {
1117             'A'..='Z' => true,
1118             _ => false,
1119         }
1120     }
1121
1122     /// Checks if the value is an ASCII lowercase character:
1123     /// U+0061 'a' ..= U+007A 'z'.
1124     ///
1125     /// # Examples
1126     ///
1127     /// ```
1128     /// let uppercase_a = 'A';
1129     /// let uppercase_g = 'G';
1130     /// let a = 'a';
1131     /// let g = 'g';
1132     /// let zero = '0';
1133     /// let percent = '%';
1134     /// let space = ' ';
1135     /// let lf = '\n';
1136     /// let esc: char = 0x1b_u8.into();
1137     ///
1138     /// assert!(!uppercase_a.is_ascii_lowercase());
1139     /// assert!(!uppercase_g.is_ascii_lowercase());
1140     /// assert!(a.is_ascii_lowercase());
1141     /// assert!(g.is_ascii_lowercase());
1142     /// assert!(!zero.is_ascii_lowercase());
1143     /// assert!(!percent.is_ascii_lowercase());
1144     /// assert!(!space.is_ascii_lowercase());
1145     /// assert!(!lf.is_ascii_lowercase());
1146     /// assert!(!esc.is_ascii_lowercase());
1147     /// ```
1148     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1149     #[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
1150     #[inline]
1151     pub const fn is_ascii_lowercase(&self) -> bool {
1152         match *self {
1153             'a'..='z' => true,
1154             _ => false,
1155         }
1156     }
1157
1158     /// Checks if the value is an ASCII alphanumeric character:
1159     ///
1160     /// - U+0041 'A' ..= U+005A 'Z', or
1161     /// - U+0061 'a' ..= U+007A 'z', or
1162     /// - U+0030 '0' ..= U+0039 '9'.
1163     ///
1164     /// # Examples
1165     ///
1166     /// ```
1167     /// let uppercase_a = 'A';
1168     /// let uppercase_g = 'G';
1169     /// let a = 'a';
1170     /// let g = 'g';
1171     /// let zero = '0';
1172     /// let percent = '%';
1173     /// let space = ' ';
1174     /// let lf = '\n';
1175     /// let esc: char = 0x1b_u8.into();
1176     ///
1177     /// assert!(uppercase_a.is_ascii_alphanumeric());
1178     /// assert!(uppercase_g.is_ascii_alphanumeric());
1179     /// assert!(a.is_ascii_alphanumeric());
1180     /// assert!(g.is_ascii_alphanumeric());
1181     /// assert!(zero.is_ascii_alphanumeric());
1182     /// assert!(!percent.is_ascii_alphanumeric());
1183     /// assert!(!space.is_ascii_alphanumeric());
1184     /// assert!(!lf.is_ascii_alphanumeric());
1185     /// assert!(!esc.is_ascii_alphanumeric());
1186     /// ```
1187     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1188     #[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
1189     #[inline]
1190     pub const fn is_ascii_alphanumeric(&self) -> bool {
1191         match *self {
1192             '0'..='9' | 'A'..='Z' | 'a'..='z' => true,
1193             _ => false,
1194         }
1195     }
1196
1197     /// Checks if the value is an ASCII decimal digit:
1198     /// U+0030 '0' ..= U+0039 '9'.
1199     ///
1200     /// # Examples
1201     ///
1202     /// ```
1203     /// let uppercase_a = 'A';
1204     /// let uppercase_g = 'G';
1205     /// let a = 'a';
1206     /// let g = 'g';
1207     /// let zero = '0';
1208     /// let percent = '%';
1209     /// let space = ' ';
1210     /// let lf = '\n';
1211     /// let esc: char = 0x1b_u8.into();
1212     ///
1213     /// assert!(!uppercase_a.is_ascii_digit());
1214     /// assert!(!uppercase_g.is_ascii_digit());
1215     /// assert!(!a.is_ascii_digit());
1216     /// assert!(!g.is_ascii_digit());
1217     /// assert!(zero.is_ascii_digit());
1218     /// assert!(!percent.is_ascii_digit());
1219     /// assert!(!space.is_ascii_digit());
1220     /// assert!(!lf.is_ascii_digit());
1221     /// assert!(!esc.is_ascii_digit());
1222     /// ```
1223     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1224     #[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
1225     #[inline]
1226     pub const fn is_ascii_digit(&self) -> bool {
1227         match *self {
1228             '0'..='9' => true,
1229             _ => false,
1230         }
1231     }
1232
1233     /// Checks if the value is an ASCII hexadecimal digit:
1234     ///
1235     /// - U+0030 '0' ..= U+0039 '9', or
1236     /// - U+0041 'A' ..= U+0046 'F', or
1237     /// - U+0061 'a' ..= U+0066 'f'.
1238     ///
1239     /// # Examples
1240     ///
1241     /// ```
1242     /// let uppercase_a = 'A';
1243     /// let uppercase_g = 'G';
1244     /// let a = 'a';
1245     /// let g = 'g';
1246     /// let zero = '0';
1247     /// let percent = '%';
1248     /// let space = ' ';
1249     /// let lf = '\n';
1250     /// let esc: char = 0x1b_u8.into();
1251     ///
1252     /// assert!(uppercase_a.is_ascii_hexdigit());
1253     /// assert!(!uppercase_g.is_ascii_hexdigit());
1254     /// assert!(a.is_ascii_hexdigit());
1255     /// assert!(!g.is_ascii_hexdigit());
1256     /// assert!(zero.is_ascii_hexdigit());
1257     /// assert!(!percent.is_ascii_hexdigit());
1258     /// assert!(!space.is_ascii_hexdigit());
1259     /// assert!(!lf.is_ascii_hexdigit());
1260     /// assert!(!esc.is_ascii_hexdigit());
1261     /// ```
1262     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1263     #[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
1264     #[inline]
1265     pub const fn is_ascii_hexdigit(&self) -> bool {
1266         match *self {
1267             '0'..='9' | 'A'..='F' | 'a'..='f' => true,
1268             _ => false,
1269         }
1270     }
1271
1272     /// Checks if the value is an ASCII punctuation character:
1273     ///
1274     /// - U+0021 ..= U+002F `! " # $ % & ' ( ) * + , - . /`, or
1275     /// - U+003A ..= U+0040 `: ; < = > ? @`, or
1276     /// - U+005B ..= U+0060 ``[ \ ] ^ _ ` ``, or
1277     /// - U+007B ..= U+007E `{ | } ~`
1278     ///
1279     /// # Examples
1280     ///
1281     /// ```
1282     /// let uppercase_a = 'A';
1283     /// let uppercase_g = 'G';
1284     /// let a = 'a';
1285     /// let g = 'g';
1286     /// let zero = '0';
1287     /// let percent = '%';
1288     /// let space = ' ';
1289     /// let lf = '\n';
1290     /// let esc: char = 0x1b_u8.into();
1291     ///
1292     /// assert!(!uppercase_a.is_ascii_punctuation());
1293     /// assert!(!uppercase_g.is_ascii_punctuation());
1294     /// assert!(!a.is_ascii_punctuation());
1295     /// assert!(!g.is_ascii_punctuation());
1296     /// assert!(!zero.is_ascii_punctuation());
1297     /// assert!(percent.is_ascii_punctuation());
1298     /// assert!(!space.is_ascii_punctuation());
1299     /// assert!(!lf.is_ascii_punctuation());
1300     /// assert!(!esc.is_ascii_punctuation());
1301     /// ```
1302     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1303     #[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
1304     #[inline]
1305     pub const fn is_ascii_punctuation(&self) -> bool {
1306         match *self {
1307             '!'..='/' | ':'..='@' | '['..='`' | '{'..='~' => true,
1308             _ => false,
1309         }
1310     }
1311
1312     /// Checks if the value is an ASCII graphic character:
1313     /// U+0021 '!' ..= U+007E '~'.
1314     ///
1315     /// # Examples
1316     ///
1317     /// ```
1318     /// let uppercase_a = 'A';
1319     /// let uppercase_g = 'G';
1320     /// let a = 'a';
1321     /// let g = 'g';
1322     /// let zero = '0';
1323     /// let percent = '%';
1324     /// let space = ' ';
1325     /// let lf = '\n';
1326     /// let esc: char = 0x1b_u8.into();
1327     ///
1328     /// assert!(uppercase_a.is_ascii_graphic());
1329     /// assert!(uppercase_g.is_ascii_graphic());
1330     /// assert!(a.is_ascii_graphic());
1331     /// assert!(g.is_ascii_graphic());
1332     /// assert!(zero.is_ascii_graphic());
1333     /// assert!(percent.is_ascii_graphic());
1334     /// assert!(!space.is_ascii_graphic());
1335     /// assert!(!lf.is_ascii_graphic());
1336     /// assert!(!esc.is_ascii_graphic());
1337     /// ```
1338     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1339     #[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
1340     #[inline]
1341     pub const fn is_ascii_graphic(&self) -> bool {
1342         match *self {
1343             '!'..='~' => true,
1344             _ => false,
1345         }
1346     }
1347
1348     /// Checks if the value is an ASCII whitespace character:
1349     /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED,
1350     /// U+000C FORM FEED, or U+000D CARRIAGE RETURN.
1351     ///
1352     /// Rust uses the WhatWG Infra Standard's [definition of ASCII
1353     /// whitespace][infra-aw]. There are several other definitions in
1354     /// wide use. For instance, [the POSIX locale][pct] includes
1355     /// U+000B VERTICAL TAB as well as all the above characters,
1356     /// but—from the very same specification—[the default rule for
1357     /// "field splitting" in the Bourne shell][bfs] considers *only*
1358     /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
1359     ///
1360     /// If you are writing a program that will process an existing
1361     /// file format, check what that format's definition of whitespace is
1362     /// before using this function.
1363     ///
1364     /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
1365     /// [pct]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
1366     /// [bfs]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
1367     ///
1368     /// # Examples
1369     ///
1370     /// ```
1371     /// let uppercase_a = 'A';
1372     /// let uppercase_g = 'G';
1373     /// let a = 'a';
1374     /// let g = 'g';
1375     /// let zero = '0';
1376     /// let percent = '%';
1377     /// let space = ' ';
1378     /// let lf = '\n';
1379     /// let esc: char = 0x1b_u8.into();
1380     ///
1381     /// assert!(!uppercase_a.is_ascii_whitespace());
1382     /// assert!(!uppercase_g.is_ascii_whitespace());
1383     /// assert!(!a.is_ascii_whitespace());
1384     /// assert!(!g.is_ascii_whitespace());
1385     /// assert!(!zero.is_ascii_whitespace());
1386     /// assert!(!percent.is_ascii_whitespace());
1387     /// assert!(space.is_ascii_whitespace());
1388     /// assert!(lf.is_ascii_whitespace());
1389     /// assert!(!esc.is_ascii_whitespace());
1390     /// ```
1391     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1392     #[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
1393     #[inline]
1394     pub const fn is_ascii_whitespace(&self) -> bool {
1395         match *self {
1396             '\t' | '\n' | '\x0C' | '\r' | ' ' => true,
1397             _ => false,
1398         }
1399     }
1400
1401     /// Checks if the value is an ASCII control character:
1402     /// U+0000 NUL ..= U+001F UNIT SEPARATOR, or U+007F DELETE.
1403     /// Note that most ASCII whitespace characters are control
1404     /// characters, but SPACE is not.
1405     ///
1406     /// # Examples
1407     ///
1408     /// ```
1409     /// let uppercase_a = 'A';
1410     /// let uppercase_g = 'G';
1411     /// let a = 'a';
1412     /// let g = 'g';
1413     /// let zero = '0';
1414     /// let percent = '%';
1415     /// let space = ' ';
1416     /// let lf = '\n';
1417     /// let esc: char = 0x1b_u8.into();
1418     ///
1419     /// assert!(!uppercase_a.is_ascii_control());
1420     /// assert!(!uppercase_g.is_ascii_control());
1421     /// assert!(!a.is_ascii_control());
1422     /// assert!(!g.is_ascii_control());
1423     /// assert!(!zero.is_ascii_control());
1424     /// assert!(!percent.is_ascii_control());
1425     /// assert!(!space.is_ascii_control());
1426     /// assert!(lf.is_ascii_control());
1427     /// assert!(esc.is_ascii_control());
1428     /// ```
1429     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1430     #[rustc_const_unstable(feature = "const_ascii_ctype_on_intrinsics", issue = "68983")]
1431     #[inline]
1432     pub const fn is_ascii_control(&self) -> bool {
1433         match *self {
1434             '\0'..='\x1F' | '\x7F' => true,
1435             _ => false,
1436         }
1437     }
1438 }