@@ -34,8 +34,6 @@ static MINIMUM_CAPACITY: uint = 2u;
34
34
35
35
// FIXME(conventions): implement shrink_to_fit. Awkward with the current design, but it should
36
36
// be scrapped anyway. Defer to rewrite?
37
- // FIXME(conventions): implement into_iter
38
-
39
37
40
38
/// `RingBuf` is a circular buffer that implements `Deque`.
41
39
pub struct RingBuf < T > {
@@ -394,6 +392,14 @@ impl<T> RingBuf<T> {
394
392
}
395
393
}
396
394
395
+ /// Consumes the list into an iterator yielding elements by value.
396
+ #[ unstable = "matches collection reform specification, waiting for dust to settle" ]
397
+ pub fn into_iter ( self ) -> MoveItems < T > {
398
+ MoveItems {
399
+ inner : self ,
400
+ }
401
+ }
402
+
397
403
/// Returns the number of elements in the `RingBuf`.
398
404
///
399
405
/// # Example
@@ -737,11 +743,9 @@ impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> {
737
743
}
738
744
let tail = self . tail ;
739
745
self . tail = wrap_index ( self . tail + 1 , self . cap ) ;
740
- if mem:: size_of :: < T > ( ) != 0 {
741
- unsafe { Some ( & mut * self . ptr . offset ( tail as int ) ) }
742
- } else {
743
- // use a non-zero pointer
744
- Some ( unsafe { mem:: transmute ( 1 u) } )
746
+
747
+ unsafe {
748
+ Some ( & mut * self . ptr . offset ( tail as int ) )
745
749
}
746
750
}
747
751
@@ -759,12 +763,43 @@ impl<'a, T> DoubleEndedIterator<&'a mut T> for MutItems<'a, T> {
759
763
return None ;
760
764
}
761
765
self . head = wrap_index ( self . head - 1 , self . cap ) ;
762
- unsafe { Some ( & mut * self . ptr . offset ( self . head as int ) ) }
766
+
767
+ unsafe {
768
+ Some ( & mut * self . ptr . offset ( self . head as int ) )
769
+ }
763
770
}
764
771
}
765
772
766
773
impl < ' a , T > ExactSize < & ' a mut T > for MutItems < ' a , T > { }
767
774
775
+ // A by-value RingBuf iterator
776
+ pub struct MoveItems < T > {
777
+ inner : RingBuf < T > ,
778
+ }
779
+
780
+ impl < T > Iterator < T > for MoveItems < T > {
781
+ #[ inline]
782
+ fn next ( & mut self ) -> Option < T > {
783
+ self . inner . pop_front ( )
784
+ }
785
+
786
+ #[ inline]
787
+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
788
+ let len = self . inner . len ( ) ;
789
+ ( len, Some ( len) )
790
+ }
791
+ }
792
+
793
+ impl < T > DoubleEndedIterator < T > for MoveItems < T > {
794
+ #[ inline]
795
+ fn next_back ( & mut self ) -> Option < T > {
796
+ self . inner . pop_back ( )
797
+ }
798
+ }
799
+
800
+
801
+ impl < T > ExactSize < T > for MoveItems < T > { }
802
+
768
803
impl < A : PartialEq > PartialEq for RingBuf < A > {
769
804
fn eq ( & self , other : & RingBuf < A > ) -> bool {
770
805
self . len ( ) == other. len ( ) &&
@@ -1314,6 +1349,65 @@ mod tests {
1314
1349
}
1315
1350
}
1316
1351
1352
+ #[ test]
1353
+ fn test_into_iter ( ) {
1354
+
1355
+ // Empty iter
1356
+ {
1357
+ let d: RingBuf < int > = RingBuf :: new ( ) ;
1358
+ let mut iter = d. into_iter ( ) ;
1359
+
1360
+ assert_eq ! ( iter. size_hint( ) , ( 0 , Some ( 0 ) ) ) ;
1361
+ assert_eq ! ( iter. next( ) , None ) ;
1362
+ assert_eq ! ( iter. size_hint( ) , ( 0 , Some ( 0 ) ) ) ;
1363
+ }
1364
+
1365
+ // simple iter
1366
+ {
1367
+ let mut d = RingBuf :: new ( ) ;
1368
+ for i in range ( 0 i, 5 ) {
1369
+ d. push_back ( i) ;
1370
+ }
1371
+
1372
+ let b = vec ! [ 0 , 1 , 2 , 3 , 4 ] ;
1373
+ assert_eq ! ( d. into_iter( ) . collect:: <Vec <int>>( ) , b) ;
1374
+ }
1375
+
1376
+ // wrapped iter
1377
+ {
1378
+ let mut d = RingBuf :: new ( ) ;
1379
+ for i in range ( 0 i, 5 ) {
1380
+ d. push_back ( i) ;
1381
+ }
1382
+ for i in range ( 6 , 9 ) {
1383
+ d. push_front ( i) ;
1384
+ }
1385
+
1386
+ let b = vec ! [ 8 , 7 , 6 , 0 , 1 , 2 , 3 , 4 ] ;
1387
+ assert_eq ! ( d. into_iter( ) . collect:: <Vec <int>>( ) , b) ;
1388
+ }
1389
+
1390
+ // partially used
1391
+ {
1392
+ let mut d = RingBuf :: new ( ) ;
1393
+ for i in range ( 0 i, 5 ) {
1394
+ d. push_back ( i) ;
1395
+ }
1396
+ for i in range ( 6 , 9 ) {
1397
+ d. push_front ( i) ;
1398
+ }
1399
+
1400
+ let mut it = d. into_iter ( ) ;
1401
+ assert_eq ! ( it. size_hint( ) , ( 8 , Some ( 8 ) ) ) ;
1402
+ assert_eq ! ( it. next( ) , Some ( 8 ) ) ;
1403
+ assert_eq ! ( it. size_hint( ) , ( 7 , Some ( 7 ) ) ) ;
1404
+ assert_eq ! ( it. next_back( ) , Some ( 4 ) ) ;
1405
+ assert_eq ! ( it. size_hint( ) , ( 6 , Some ( 6 ) ) ) ;
1406
+ assert_eq ! ( it. next( ) , Some ( 7 ) ) ;
1407
+ assert_eq ! ( it. size_hint( ) , ( 5 , Some ( 5 ) ) ) ;
1408
+ }
1409
+ }
1410
+
1317
1411
#[ test]
1318
1412
fn test_from_iter ( ) {
1319
1413
use std:: iter;
0 commit comments