Auto merge of #113295 - clarfonthey:ascii-step, r=cuviper
Implement Step for ascii::Char This allows iterating over ranges of `ascii::Char`, similarly to ranges of `char`. Note that `ascii::Char` is still unstable, tracked in #110998.
This commit is contained in:
commit
f9ba43ce14
@ -1,3 +1,4 @@
|
|||||||
|
use crate::ascii::Char as AsciiChar;
|
||||||
use crate::convert::TryFrom;
|
use crate::convert::TryFrom;
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
use crate::num::NonZeroUsize;
|
use crate::num::NonZeroUsize;
|
||||||
@ -14,7 +15,7 @@ macro_rules! unsafe_impl_trusted_step {
|
|||||||
unsafe impl TrustedStep for $type {}
|
unsafe impl TrustedStep for $type {}
|
||||||
)*};
|
)*};
|
||||||
}
|
}
|
||||||
unsafe_impl_trusted_step![char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize];
|
unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize];
|
||||||
|
|
||||||
/// Objects that have a notion of *successor* and *predecessor* operations.
|
/// Objects that have a notion of *successor* and *predecessor* operations.
|
||||||
///
|
///
|
||||||
@ -484,6 +485,48 @@ impl Step for char {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
|
||||||
|
impl Step for AsciiChar {
|
||||||
|
#[inline]
|
||||||
|
fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> Option<usize> {
|
||||||
|
Step::steps_between(&start.to_u8(), &end.to_u8())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn forward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
|
||||||
|
let end = Step::forward_checked(start.to_u8(), count)?;
|
||||||
|
AsciiChar::from_u8(end)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn backward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
|
||||||
|
let end = Step::backward_checked(start.to_u8(), count)?;
|
||||||
|
|
||||||
|
// SAFETY: Values below that of a valid ASCII character are also valid ASCII
|
||||||
|
Some(unsafe { AsciiChar::from_u8_unchecked(end) })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn forward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
|
||||||
|
// SAFETY: Caller asserts that result is a valid ASCII character,
|
||||||
|
// and therefore it is a valid u8.
|
||||||
|
let end = unsafe { Step::forward_unchecked(start.to_u8(), count) };
|
||||||
|
|
||||||
|
// SAFETY: Caller asserts that result is a valid ASCII character.
|
||||||
|
unsafe { AsciiChar::from_u8_unchecked(end) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn backward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
|
||||||
|
// SAFETY: Caller asserts that result is a valid ASCII character,
|
||||||
|
// and therefore it is a valid u8.
|
||||||
|
let end = unsafe { Step::backward_unchecked(start.to_u8(), count) };
|
||||||
|
|
||||||
|
// SAFETY: Caller asserts that result is a valid ASCII character.
|
||||||
|
unsafe { AsciiChar::from_u8_unchecked(end) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! range_exact_iter_impl {
|
macro_rules! range_exact_iter_impl {
|
||||||
($($t:ty)*) => ($(
|
($($t:ty)*) => ($(
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use core::num::NonZeroUsize;
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use core::ascii::Char as AsciiChar;
|
||||||
|
use core::num::NonZeroUsize;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_range() {
|
fn test_range() {
|
||||||
@ -39,6 +40,21 @@ fn test_char_range() {
|
|||||||
assert_eq!(('\u{D7FF}'..'\u{E000}').size_hint(), (1, Some(1)));
|
assert_eq!(('\u{D7FF}'..'\u{E000}').size_hint(), (1, Some(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ascii_char_range() {
|
||||||
|
let from = AsciiChar::Null;
|
||||||
|
let to = AsciiChar::Delete;
|
||||||
|
assert!((from..=to).eq((from as u8..=to as u8).filter_map(AsciiChar::from_u8)));
|
||||||
|
assert!((from..=to).rev().eq((from as u8..=to as u8).filter_map(AsciiChar::from_u8).rev()));
|
||||||
|
|
||||||
|
assert_eq!((AsciiChar::CapitalA..=AsciiChar::CapitalZ).count(), 26);
|
||||||
|
assert_eq!((AsciiChar::CapitalA..=AsciiChar::CapitalZ).size_hint(), (26, Some(26)));
|
||||||
|
assert_eq!((AsciiChar::SmallA..=AsciiChar::SmallZ).count(), 26);
|
||||||
|
assert_eq!((AsciiChar::SmallA..=AsciiChar::SmallZ).size_hint(), (26, Some(26)));
|
||||||
|
assert_eq!((AsciiChar::Digit0..=AsciiChar::Digit9).count(), 10);
|
||||||
|
assert_eq!((AsciiChar::Digit0..=AsciiChar::Digit9).size_hint(), (10, Some(10)));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_range_exhaustion() {
|
fn test_range_exhaustion() {
|
||||||
let mut r = 10..10;
|
let mut r = 10..10;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#![feature(array_chunks)]
|
#![feature(array_chunks)]
|
||||||
#![feature(array_methods)]
|
#![feature(array_methods)]
|
||||||
#![feature(array_windows)]
|
#![feature(array_windows)]
|
||||||
|
#![feature(ascii_char)]
|
||||||
|
#![feature(ascii_char_variants)]
|
||||||
#![feature(bigint_helper_methods)]
|
#![feature(bigint_helper_methods)]
|
||||||
#![feature(cell_update)]
|
#![feature(cell_update)]
|
||||||
#![feature(const_align_offset)]
|
#![feature(const_align_offset)]
|
||||||
|
@ -19,7 +19,7 @@ LL | for i in false..true {}
|
|||||||
i64
|
i64
|
||||||
i128
|
i128
|
||||||
usize
|
usize
|
||||||
and 5 others
|
and 6 others
|
||||||
= note: required for `std::ops::Range<bool>` to implement `Iterator`
|
= note: required for `std::ops::Range<bool>` to implement `Iterator`
|
||||||
= note: required for `std::ops::Range<bool>` to implement `IntoIterator`
|
= note: required for `std::ops::Range<bool>` to implement `IntoIterator`
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user