|
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.
|
@@ -616,3 +617,71 @@ impl fmt::Debug for AsciiChar {
|
616 | 617 | f.write_char('\'')
|
617 | 618 | }
|
618 | 619 | }
|
| 620 | + |
| 621 | +#[unstable(feature = "ascii_char", issue = "110998")] |
| 622 | +impl Add<u8> for AsciiChar { |
| 623 | + type Output = AsciiChar; |
| 624 | + |
| 625 | + /// Calculates sum of the ASCII value and given offset. |
| 626 | + /// |
| 627 | + /// In debug builds, panics if result is greater than largest ASCII value. |
| 628 | + /// In release builds wraps the value (i.e. masks out the most significant |
| 629 | + /// bit) so the output is a valid ASCII character. |
| 630 | + /// |
| 631 | + /// # Examples |
| 632 | + /// |
| 633 | + /// ``` |
| 634 | + /// #![feature(ascii_char, ascii_char_variants)] |
| 635 | + /// use core::ascii::Char; |
| 636 | + /// |
| 637 | + /// assert_eq!(Char::Digit8, Char::Digit0 + 8); |
| 638 | + /// ``` |
| 639 | + /// |
| 640 | + /// ```should_panic |
| 641 | + /// #![feature(ascii_char, ascii_char_variants)] |
| 642 | + /// use core::ascii::Char; |
| 643 | + /// |
| 644 | + /// // This produces value which is not a valid ASCII character and thus |
| 645 | + /// // panics in debug builds. |
| 646 | + /// let _ = Char::Digit0 + 100; |
| 647 | + /// ``` |
| 648 | + #[inline] |
| 649 | + #[rustc_inherit_overflow_checks] |
| 650 | + fn add(self, rhs: u8) -> Self::Output { |
| 651 | + add_impl(self, rhs) |
| 652 | + } |
| 653 | +} |
| 654 | + |
| 655 | +#[unstable(feature = "ascii_char", issue = "110998")] |
| 656 | +impl Add<AsciiChar> for u8 { |
| 657 | + type Output = AsciiChar; |
| 658 | + |
| 659 | + #[inline] |
| 660 | + #[rustc_inherit_overflow_checks] |
| 661 | + fn add(self, rhs: AsciiChar) -> Self::Output { |
| 662 | + add_impl(rhs, self) |
| 663 | + } |
| 664 | +} |
| 665 | + |
| 666 | +#[unstable(feature = "ascii_char", issue = "110998")] |
| 667 | +impl AddAssign<u8> for AsciiChar { |
| 668 | + #[inline] |
| 669 | + #[rustc_inherit_overflow_checks] |
| 670 | + fn add_assign(&mut self, rhs: u8) { |
| 671 | + *self = add_impl(*self, rhs) |
| 672 | + } |
| 673 | +} |
| 674 | + |
| 675 | +forward_ref_binop! { impl Add, add for AsciiChar, u8 } |
| 676 | +forward_ref_binop! { impl Add, add for u8, AsciiChar } |
| 677 | +forward_ref_op_assign! { impl AddAssign, add_assign for AsciiChar, u8 } |
| 678 | + |
| 679 | +#[inline] |
| 680 | +#[rustc_inherit_overflow_checks] |
| 681 | +fn add_impl(chr: AsciiChar, rhs: u8) -> AsciiChar { |
| 682 | + // Make sure we overflow if chr + rhs ≥ 128. Since we inherit overflow |
| 683 | + // checks, we’re wrap in release and panic in debug builds. |
| 684 | + let sum = u8::from(chr) + 128 + rhs; |
| 685 | + // SAFETY: `sum & 127` limits the sum to a valid ASCII value. |
| 686 | + unsafe { AsciiChar::from_u8_unchecked(sum & 127) } |
| 687 | +} |
0 commit comments