@@ -491,6 +491,27 @@ impl<T> RingBuf<T> {
491
491
#[ unstable = "matches collection reform specification, waiting for dust to settle" ]
492
492
pub fn is_empty ( & self ) -> bool { self . len ( ) == 0 }
493
493
494
+ /// Creates a draining iterator that clears the `RingBuf` and iterates over
495
+ /// the removed items from start to end.
496
+ ///
497
+ /// # Examples
498
+ ///
499
+ /// ```
500
+ /// use std::collections::RingBuf;
501
+ ///
502
+ /// let mut v = RingBuf::new();
503
+ /// v.push_back(1i);
504
+ /// assert_eq!(v.drain().next(), Some(1));
505
+ /// assert!(v.is_empty());
506
+ /// ```
507
+ #[ inline]
508
+ #[ unstable = "matches collection reform specification, waiting for dust to settle" ]
509
+ pub fn drain < ' a > ( & ' a mut self ) -> Drain < ' a , T > {
510
+ Drain {
511
+ inner : self ,
512
+ }
513
+ }
514
+
494
515
/// Clears the buffer, removing all values.
495
516
///
496
517
/// # Examples
@@ -504,10 +525,9 @@ impl<T> RingBuf<T> {
504
525
/// assert!(v.is_empty());
505
526
/// ```
506
527
#[ unstable = "matches collection reform specification, waiting for dust to settle" ]
528
+ #[ inline]
507
529
pub fn clear ( & mut self ) {
508
- while self . pop_front ( ) . is_some ( ) { }
509
- self . head = 0 ;
510
- self . tail = 0 ;
530
+ self . drain ( ) ;
511
531
}
512
532
513
533
/// Provides a reference to the front element, or `None` if the sequence is
@@ -1230,9 +1250,44 @@ impl<T> DoubleEndedIterator<T> for MoveItems<T> {
1230
1250
}
1231
1251
}
1232
1252
1233
-
1234
1253
impl < T > ExactSizeIterator < T > for MoveItems < T > { }
1235
1254
1255
+ /// A draining RingBuf iterator
1256
+ pub struct Drain < ' a , T : ' a > {
1257
+ inner : & ' a mut RingBuf < T > ,
1258
+ }
1259
+
1260
+ #[ unsafe_destructor]
1261
+ impl < ' a , T : ' a > Drop for Drain < ' a , T > {
1262
+ fn drop ( & mut self ) {
1263
+ for _ in * self { }
1264
+ self . inner . head = 0 ;
1265
+ self . inner . tail = 0 ;
1266
+ }
1267
+ }
1268
+
1269
+ impl < ' a , T : ' a > Iterator < T > for Drain < ' a , T > {
1270
+ #[ inline]
1271
+ fn next ( & mut self ) -> Option < T > {
1272
+ self . inner . pop_front ( )
1273
+ }
1274
+
1275
+ #[ inline]
1276
+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
1277
+ let len = self . inner . len ( ) ;
1278
+ ( len, Some ( len) )
1279
+ }
1280
+ }
1281
+
1282
+ impl < ' a , T : ' a > DoubleEndedIterator < T > for Drain < ' a , T > {
1283
+ #[ inline]
1284
+ fn next_back ( & mut self ) -> Option < T > {
1285
+ self . inner . pop_back ( )
1286
+ }
1287
+ }
1288
+
1289
+ impl < ' a , T : ' a > ExactSizeIterator < T > for Drain < ' a , T > { }
1290
+
1236
1291
impl < A : PartialEq > PartialEq for RingBuf < A > {
1237
1292
fn eq ( & self , other : & RingBuf < A > ) -> bool {
1238
1293
self . len ( ) == other. len ( ) &&
@@ -1841,6 +1896,73 @@ mod tests {
1841
1896
}
1842
1897
}
1843
1898
1899
+ #[ test]
1900
+ fn test_drain ( ) {
1901
+
1902
+ // Empty iter
1903
+ {
1904
+ let mut d: RingBuf < int > = RingBuf :: new ( ) ;
1905
+
1906
+ {
1907
+ let mut iter = d. drain ( ) ;
1908
+
1909
+ assert_eq ! ( iter. size_hint( ) , ( 0 , Some ( 0 ) ) ) ;
1910
+ assert_eq ! ( iter. next( ) , None ) ;
1911
+ assert_eq ! ( iter. size_hint( ) , ( 0 , Some ( 0 ) ) ) ;
1912
+ }
1913
+
1914
+ assert ! ( d. is_empty( ) ) ;
1915
+ }
1916
+
1917
+ // simple iter
1918
+ {
1919
+ let mut d = RingBuf :: new ( ) ;
1920
+ for i in range ( 0 i, 5 ) {
1921
+ d. push_back ( i) ;
1922
+ }
1923
+
1924
+ assert_eq ! ( d. drain( ) . collect:: <Vec <int>>( ) , [ 0 , 1 , 2 , 3 , 4 ] ) ;
1925
+ assert ! ( d. is_empty( ) ) ;
1926
+ }
1927
+
1928
+ // wrapped iter
1929
+ {
1930
+ let mut d = RingBuf :: new ( ) ;
1931
+ for i in range ( 0 i, 5 ) {
1932
+ d. push_back ( i) ;
1933
+ }
1934
+ for i in range ( 6 , 9 ) {
1935
+ d. push_front ( i) ;
1936
+ }
1937
+
1938
+ assert_eq ! ( d. drain( ) . collect:: <Vec <int>>( ) , [ 8 , 7 , 6 , 0 , 1 , 2 , 3 , 4 ] ) ;
1939
+ assert ! ( d. is_empty( ) ) ;
1940
+ }
1941
+
1942
+ // partially used
1943
+ {
1944
+ let mut d = RingBuf :: new ( ) ;
1945
+ for i in range ( 0 i, 5 ) {
1946
+ d. push_back ( i) ;
1947
+ }
1948
+ for i in range ( 6 , 9 ) {
1949
+ d. push_front ( i) ;
1950
+ }
1951
+
1952
+ {
1953
+ let mut it = d. drain ( ) ;
1954
+ assert_eq ! ( it. size_hint( ) , ( 8 , Some ( 8 ) ) ) ;
1955
+ assert_eq ! ( it. next( ) , Some ( 8 ) ) ;
1956
+ assert_eq ! ( it. size_hint( ) , ( 7 , Some ( 7 ) ) ) ;
1957
+ assert_eq ! ( it. next_back( ) , Some ( 4 ) ) ;
1958
+ assert_eq ! ( it. size_hint( ) , ( 6 , Some ( 6 ) ) ) ;
1959
+ assert_eq ! ( it. next( ) , Some ( 7 ) ) ;
1960
+ assert_eq ! ( it. size_hint( ) , ( 5 , Some ( 5 ) ) ) ;
1961
+ }
1962
+ assert ! ( d. is_empty( ) ) ;
1963
+ }
1964
+ }
1965
+
1844
1966
#[ test]
1845
1967
fn test_from_iter ( ) {
1846
1968
use core:: iter;
0 commit comments