|
5 | 5 |
|
6 | 6 | use crate::fmt::{self, Write};
|
7 | 7 | use crate::mem::transmute;
|
| 8 | +use crate::ops::{Add, AddAssign}; |
8 | 9 |
|
9 | 10 | /// One of the 128 Unicode characters from U+0000 through U+007F,
|
10 | 11 | /// often known as the [ASCII] subset.
|
@@ -557,6 +558,14 @@ impl [AsciiChar] {
|
557 | 558 | }
|
558 | 559 | }
|
559 | 560 |
|
| 561 | +#[unstable(feature = "ascii_char", issue = "110998")] |
| 562 | +impl From<AsciiChar> for u8 { |
| 563 | + #[inline] |
| 564 | + fn from(chr: AsciiChar) -> Self { |
| 565 | + chr as u8 |
| 566 | + } |
| 567 | +} |
| 568 | + |
560 | 569 | #[unstable(feature = "ascii_char", issue = "110998")]
|
561 | 570 | impl fmt::Display for AsciiChar {
|
562 | 571 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
@@ -600,3 +609,59 @@ impl fmt::Debug for AsciiChar {
|
600 | 609 | f.write_char('\'')
|
601 | 610 | }
|
602 | 611 | }
|
| 612 | + |
| 613 | +#[unstable(feature = "ascii_char", issue = "110998")] |
| 614 | +impl Add<u8> for AsciiChar { |
| 615 | + type Output = AsciiChar; |
| 616 | + |
| 617 | + /// Calculates sum of the ASCII value and given offset. |
| 618 | + /// |
| 619 | + /// In debug builds, panics if result is greater than largest ASCII value. |
| 620 | + /// |
| 621 | + /// In release builds wraps the value (i.e. masks out the most significant |
| 622 | + /// bit) so the output is a valid ASCII character. |
| 623 | + /// |
| 624 | + /// ``` |
| 625 | + /// #![feature(ascii_char, ascii_char_variants)] |
| 626 | + /// use core::ascii::Char; |
| 627 | + /// |
| 628 | + /// assert_eq!(Char::Digit8, Char::Digit0 + 8); |
| 629 | + /// ``` |
| 630 | + #[inline] |
| 631 | + fn add(self, rhs: u8) -> Self::Output { |
| 632 | + add_impl(self, rhs) |
| 633 | + } |
| 634 | +} |
| 635 | + |
| 636 | +#[unstable(feature = "ascii_char", issue = "110998")] |
| 637 | +impl Add<AsciiChar> for u8 { |
| 638 | + type Output = AsciiChar; |
| 639 | + |
| 640 | + #[inline] |
| 641 | + fn add(self, rhs: AsciiChar) -> Self::Output { |
| 642 | + add_impl(rhs, self) |
| 643 | + } |
| 644 | +} |
| 645 | + |
| 646 | +#[unstable(feature = "ascii_char", issue = "110998")] |
| 647 | +impl AddAssign<u8> for AsciiChar { |
| 648 | + #[inline] |
| 649 | + fn add_assign(&mut self, rhs: u8) { |
| 650 | + *self = add_impl(*self, rhs) |
| 651 | + } |
| 652 | +} |
| 653 | + |
| 654 | +forward_ref_binop! { impl Add, add for AsciiChar, u8 } |
| 655 | +forward_ref_binop! { impl Add, add for u8, AsciiChar } |
| 656 | +forward_ref_op_assign! { impl AddAssign, add_assign for AsciiChar, u8 } |
| 657 | + |
| 658 | +#[inline] |
| 659 | +fn add_impl(chr: AsciiChar, rhs: u8) -> AsciiChar { |
| 660 | + let sum = u16::from(u8::from(chr)) + u16::from(rhs); |
| 661 | + if !cfg!(debug_assertions) || sum < 128 { |
| 662 | + // SAFETY: `& 127` limits the sum to a valid ASCII value. |
| 663 | + unsafe { AsciiChar::from_u8_unchecked((sum as u8) & 127) } |
| 664 | + } else { |
| 665 | + panic!("{} + {} overflows ASCII value", u8::from(chr), rhs) |
| 666 | + } |
| 667 | +} |
0 commit comments