diff options
| author | blake2-ppc <blake2-ppc> | 2013-08-18 13:57:34 +0200 |
|---|---|---|
| committer | blake2-ppc <blake2-ppc> | 2013-08-19 11:19:59 +0200 |
| commit | 3cb5b8dc1849c5958c62caf990faf75fcec6b2ea (patch) | |
| tree | f0c5a6ecd0943f73f44a692c7b7f5bb308a65cb6 /src/libstd/str.rs | |
| parent | 4043c70f23bbc883088634e9cf0c3224524a2c5c (diff) | |
std::str: Special case char_range_at_reverse so it is faster
Implement char_range_at_reverse similarly to char_range_at, instead of re-using that method.
Diffstat (limited to 'src/libstd/str.rs')
| -rw-r--r-- | src/libstd/str.rs | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 07006ba8c15..c5c2150617c 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -27,7 +27,7 @@ use iterator::{Iterator, FromIterator, Extendable}; use iterator::{Filter, AdditiveIterator, Map}; use iterator::{Invert, DoubleEndedIterator}; use libc; -use num::Zero; +use num::{Saturating, Zero}; use option::{None, Option, Some}; use ptr; use ptr::RawPtr; @@ -1698,21 +1698,29 @@ impl<'self> StrSlice<'self> for &'self str { fn char_range_at_reverse(&self, start: uint) -> CharRange { let mut prev = start; - // while there is a previous byte == 10...... - while prev > 0u && self[prev - 1u] & 192u8 == TAG_CONT_U8 { - prev -= 1u; - } + prev = prev.saturating_sub(1); + if self[prev] < 128 { return CharRange{ch: self[prev] as char, next: prev} } - // now refer to the initial byte of previous char - if prev > 0u { - prev -= 1u; - } else { - prev = 0u; - } + // Multibyte case is a fn to allow char_range_at_reverse to inline cleanly + fn multibyte_char_range_at_rev(s: &str, mut i: uint) -> CharRange { + // while there is a previous byte == 10...... + while i > 0 && s[i] & 192u8 == TAG_CONT_U8 { + i -= 1u; + } + + let mut val = s[i] as uint; + let w = UTF8_CHAR_WIDTH[val] as uint; + assert!((w != 0)); + val = utf8_first_byte!(val, w); + val = utf8_acc_cont_byte!(val, s[i + 1]); + if w > 2 { val = utf8_acc_cont_byte!(val, s[i + 2]); } + if w > 3 { val = utf8_acc_cont_byte!(val, s[i + 3]); } + + return CharRange {ch: val as char, next: i}; + } - let ch = self.char_at(prev); - return CharRange {ch:ch, next:prev}; + return multibyte_char_range_at_rev(*self, prev); } /// Plucks the character ending at the `i`th byte of a string |
