@@ -255,56 +255,94 @@ impl<'self, C: CharEq> CharEq for &'self [C] {
255
255
Section: Iterators
256
256
*/
257
257
258
- /// External iterator for a string's characters and their byte offsets.
259
- /// Use with the `std::iterator` module.
258
+ /// External iterator for a string's characters.
260
259
#[ deriving( Clone ) ]
261
- pub struct CharOffsetIterator < ' self > {
262
- priv index_front : uint ,
263
- priv index_back : uint ,
260
+ pub struct CharIterator < ' self > {
264
261
priv string : & ' self str ,
265
262
}
266
263
267
- impl < ' self > Iterator < ( uint , char ) > for CharOffsetIterator < ' self > {
264
+ impl < ' self > Iterator < char > for CharIterator < ' self > {
268
265
#[ inline]
269
- fn next ( & mut self ) -> Option < ( uint , char ) > {
270
- if self . index_front < self . index_back {
271
- let CharRange { ch, next} = self . string . char_range_at ( self . index_front ) ;
272
- let index = self . index_front ;
273
- self . index_front = next;
274
- Some ( ( index, ch) )
266
+ fn next ( & mut self ) -> Option < char > {
267
+ if self . string . len ( ) != 0 {
268
+ let CharRange { ch, next} = self . string . char_range_at ( 0 ) ;
269
+ unsafe {
270
+ self . string = raw:: slice_unchecked ( self . string , next, self . string . len ( ) ) ;
271
+ }
272
+ Some ( ch)
275
273
} else {
276
274
None
277
275
}
278
276
}
277
+
278
+ #[ inline]
279
+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
280
+ ( self . string . len ( ) . saturating_add ( 3 ) /4 , Some ( self . string . len ( ) ) )
281
+ }
279
282
}
280
283
281
- impl < ' self > DoubleEndedIterator < ( uint , char ) > for CharOffsetIterator < ' self > {
284
+ impl < ' self > DoubleEndedIterator < char > for CharIterator < ' self > {
282
285
#[ inline]
283
- fn next_back ( & mut self ) -> Option < ( uint , char ) > {
284
- if self . index_front < self . index_back {
285
- let CharRange { ch, next} = self . string . char_range_at_reverse ( self . index_back ) ;
286
- self . index_back = next;
287
- Some ( ( next, ch) )
286
+ fn next_back ( & mut self ) -> Option < char > {
287
+ if self . string . len ( ) != 0 {
288
+ let CharRange { ch, next} = self . string . char_range_at_reverse ( self . string . len ( ) ) ;
289
+ unsafe {
290
+ self . string = raw:: slice_unchecked ( self . string , 0 , next) ;
291
+ }
292
+ Some ( ch)
288
293
} else {
289
294
None
290
295
}
291
296
}
292
297
}
293
298
294
- /// External iterator for a string's characters and their byte offsets in reverse order.
295
- /// Use with the `std::iterator` module.
296
- pub type CharOffsetRevIterator < ' self > =
297
- Invert < CharOffsetIterator < ' self > > ;
298
299
299
- /// External iterator for a string's characters.
300
+ /// External iterator for a string's characters and their byte offsets .
300
301
/// Use with the `std::iterator` module.
301
- pub type CharIterator < ' self > =
302
- Map < ' self , ( uint , char ) , char , CharOffsetIterator < ' self > > ;
302
+ #[ deriving( Clone ) ]
303
+ pub struct CharOffsetIterator < ' self > {
304
+ priv string : & ' self str ,
305
+ priv iter : CharIterator < ' self > ,
306
+ }
307
+
308
+ impl < ' self > Iterator < ( uint , char ) > for CharOffsetIterator < ' self > {
309
+ #[ inline]
310
+ fn next ( & mut self ) -> Option < ( uint , char ) > {
311
+ let offset = do self . string . as_imm_buf |a, _| {
312
+ do self . iter . string . as_imm_buf |b, _| {
313
+ b as uint - a as uint
314
+ }
315
+ } ;
316
+ self . iter . next ( ) . map_move ( |ch| ( offset, ch) )
317
+ }
318
+
319
+ #[ inline]
320
+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
321
+ self . iter . size_hint ( )
322
+ }
323
+ }
324
+
325
+ impl < ' self > DoubleEndedIterator < ( uint , char ) > for CharOffsetIterator < ' self > {
326
+ #[ inline]
327
+ fn next_back ( & mut self ) -> Option < ( uint , char ) > {
328
+ self . iter . next_back ( ) . map_move ( |ch| {
329
+ let offset = do self . string . as_imm_buf |a, _| {
330
+ do self . iter . string . as_imm_buf |b, len| {
331
+ b as uint - a as uint + len
332
+ }
333
+ } ;
334
+ ( offset, ch)
335
+ } )
336
+ }
337
+ }
303
338
304
339
/// External iterator for a string's characters in reverse order.
305
340
/// Use with the `std::iterator` module.
306
- pub type CharRevIterator < ' self > =
307
- Invert < Map < ' self , ( uint , char ) , char , CharOffsetIterator < ' self > > > ;
341
+ pub type CharRevIterator < ' self > = Invert < CharIterator < ' self > > ;
342
+
343
+ /// External iterator for a string's characters and their byte offsets in reverse order.
344
+ /// Use with the `std::iterator` module.
345
+ pub type CharOffsetRevIterator < ' self > = Invert < CharOffsetIterator < ' self > > ;
308
346
309
347
/// External iterator for a string's bytes.
310
348
/// Use with the `std::iterator` module.
@@ -313,8 +351,7 @@ pub type ByteIterator<'self> =
313
351
314
352
/// External iterator for a string's bytes in reverse order.
315
353
/// Use with the `std::iterator` module.
316
- pub type ByteRevIterator < ' self > =
317
- Invert < Map < ' self , & ' self u8 , u8 , vec:: VecIterator < ' self , u8 > > > ;
354
+ pub type ByteRevIterator < ' self > = Invert < ByteIterator < ' self > > ;
318
355
319
356
/// An iterator over the substrings of a string, separated by `sep`.
320
357
#[ deriving( Clone ) ]
@@ -1218,7 +1255,7 @@ impl<'self> StrSlice<'self> for &'self str {
1218
1255
/// ~~~
1219
1256
#[inline]
1220
1257
fn iter(&self) -> CharIterator<'self> {
1221
- self.char_offset_iter().map(|(_, c)| c)
1258
+ CharIterator{string: *self}
1222
1259
}
1223
1260
1224
1261
/// An iterator over the characters of `self`, in reverse order.
@@ -1242,11 +1279,7 @@ impl<'self> StrSlice<'self> for &'self str {
1242
1279
/// An iterator over the characters of `self` and their byte offsets.
1243
1280
#[inline]
1244
1281
fn char_offset_iter(&self) -> CharOffsetIterator<'self> {
1245
- CharOffsetIterator {
1246
- index_front: 0,
1247
- index_back: self.len(),
1248
- string: *self
1249
- }
1282
+ CharOffsetIterator{string: *self, iter: self.iter()}
1250
1283
}
1251
1284
1252
1285
/// An iterator over the characters of `self` and their byte offsets.
0 commit comments