|
| 1 | +use crate::char; |
1 | 2 | use crate::convert::TryFrom;
|
2 | 3 | use crate::mem;
|
3 | 4 | use crate::ops::{self, Add, Sub, Try};
|
@@ -400,6 +401,69 @@ step_integer_impls! {
|
400 | 401 | wider than usize: [u32 i32], [u64 i64], [u128 i128];
|
401 | 402 | }
|
402 | 403 |
|
| 404 | +#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] |
| 405 | +unsafe impl Step for char { |
| 406 | + #[inline] |
| 407 | + fn steps_between(&start: &char, &end: &char) -> Option<usize> { |
| 408 | + let start = start as u32; |
| 409 | + let end = end as u32; |
| 410 | + if start <= end { |
| 411 | + let count = end - start + 1; |
| 412 | + if start < 0xD800 && 0xE000 <= end { |
| 413 | + usize::try_from(count - 0x800).ok() |
| 414 | + } else { |
| 415 | + usize::try_from(count).ok() |
| 416 | + } |
| 417 | + } else { |
| 418 | + None |
| 419 | + } |
| 420 | + } |
| 421 | + |
| 422 | + #[inline] |
| 423 | + fn forward_checked(start: char, count: usize) -> Option<char> { |
| 424 | + let start = start as u32; |
| 425 | + let mut res = Step::forward_checked(start, count)?; |
| 426 | + if start < 0xD800 && 0xD800 <= res { |
| 427 | + res = Step::forward_checked(res, 0x800)?; |
| 428 | + } |
| 429 | + if res <= char::MAX as u32 { |
| 430 | + Some(unsafe { char::from_u32_unchecked(res) }) |
| 431 | + } else { |
| 432 | + None |
| 433 | + } |
| 434 | + } |
| 435 | + |
| 436 | + #[inline] |
| 437 | + fn backward_checked(start: char, count: usize) -> Option<char> { |
| 438 | + let start = start as u32; |
| 439 | + let mut res = Step::backward_checked(start, count)?; |
| 440 | + if start >= 0xE000 && 0xE000 > res { |
| 441 | + res = Step::backward_checked(res, 0x800)?; |
| 442 | + } |
| 443 | + Some(unsafe { char::from_u32_unchecked(res) }) |
| 444 | + } |
| 445 | + |
| 446 | + #[inline] |
| 447 | + unsafe fn forward_unchecked(start: char, count: usize) -> char { |
| 448 | + let start = start as u32; |
| 449 | + let mut res = Step::forward_unchecked(start, count); |
| 450 | + if start < 0xD800 && 0xD800 <= res { |
| 451 | + res = Step::forward_unchecked(res, 0x800); |
| 452 | + } |
| 453 | + char::from_u32_unchecked(res) |
| 454 | + } |
| 455 | + |
| 456 | + #[inline] |
| 457 | + unsafe fn backward_unchecked(start: char, count: usize) -> char { |
| 458 | + let start = start as u32; |
| 459 | + let mut res = Step::backward_unchecked(start, count); |
| 460 | + if start >= 0xE000 && 0xE000 > res { |
| 461 | + res = Step::backward_unchecked(res, 0x800); |
| 462 | + } |
| 463 | + char::from_u32_unchecked(res) |
| 464 | + } |
| 465 | +} |
| 466 | + |
403 | 467 | macro_rules! range_exact_iter_impl {
|
404 | 468 | ($($t:ty)*) => ($(
|
405 | 469 | #[stable(feature = "rust1", since = "1.0.0")]
|
|
0 commit comments