Skip to content

Commit 5eff3e1

Browse files
author
blake2-ppc
committed
std::str: Use CharOffsetIterator in slice_chars
1 parent 8931ad9 commit 5eff3e1

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

src/libstd/str.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,23 +1438,24 @@ impl<'self> StrSlice<'self> for &'self str {
14381438
/// beyond the last character of the string.
14391439
fn slice_chars(&self, begin: uint, end: uint) -> &'self str {
14401440
assert!(begin <= end);
1441-
// not sure how to use the iterators for this nicely.
1442-
let mut position = 0;
14431441
let mut count = 0;
1444-
let l = self.len();
1445-
while count < begin && position < l {
1446-
position = self.char_range_at(position).next;
1442+
let mut begin_byte = None;
1443+
let mut end_byte = None;
1444+
1445+
// This could be even more efficient by not decoding,
1446+
// only finding the char boundaries
1447+
for (idx, _) in self.char_offset_iter() {
1448+
if count == begin { begin_byte = Some(idx); }
1449+
if count == end { end_byte = Some(idx); break; }
14471450
count += 1;
14481451
}
1449-
if count < begin { fail!("Attempted to begin slice_chars beyond end of string") }
1450-
let start_byte = position;
1451-
while count < end && position < l {
1452-
position = self.char_range_at(position).next;
1453-
count += 1;
1454-
}
1455-
if count < end { fail!("Attempted to end slice_chars beyond end of string") }
1452+
if end_byte.is_none() && count == end { end_byte = Some(self.len()) }
14561453
1457-
self.slice(start_byte, position)
1454+
match (begin_byte, end_byte) {
1455+
(None, _) => fail!("slice_chars: `begin` is beyond end of string"),
1456+
(_, None) => fail!("slice_chars: `end` is beyond end of string"),
1457+
(Some(a), Some(b)) => unsafe { raw::slice_bytes(*self, a, b) }
1458+
}
14581459
}
14591460
14601461
/// Returns true if `needle` is a prefix of the string.

0 commit comments

Comments
 (0)