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