@@ -443,6 +443,27 @@ impl<T> RingBuf<T> {
443
443
#[ unstable = "matches collection reform specification, waiting for dust to settle" ]
444
444
pub fn is_empty ( & self ) -> bool { self . len ( ) == 0 }
445
445
446
+ /// Creates a draining iterator that clears the `RingBuf` and iterates over
447
+ /// the removed items from start to end.
448
+ ///
449
+ /// # Examples
450
+ ///
451
+ /// ```
452
+ /// use std::collections::RingBuf;
453
+ ///
454
+ /// let mut v = RingBuf::new();
455
+ /// v.push_back(1i);
456
+ /// assert_eq!(v.drain().next(), Some(1));
457
+ /// assert!(v.is_empty());
458
+ /// ```
459
+ #[ inline]
460
+ #[ unstable = "matches collection reform specification, waiting for dust to settle" ]
461
+ pub fn drain < ' a > ( & ' a mut self ) -> Drain < ' a , T > {
462
+ Drain {
463
+ inner : self ,
464
+ }
465
+ }
466
+
446
467
/// Clears the buffer, removing all values.
447
468
///
448
469
/// # Examples
@@ -456,10 +477,9 @@ impl<T> RingBuf<T> {
456
477
/// assert!(v.is_empty());
457
478
/// ```
458
479
#[ unstable = "matches collection reform specification, waiting for dust to settle" ]
480
+ #[ inline]
459
481
pub fn clear ( & mut self ) {
460
- while self . pop_front ( ) . is_some ( ) { }
461
- self . head = 0 ;
462
- self . tail = 0 ;
482
+ self . drain ( ) ;
463
483
}
464
484
465
485
/// Provides a reference to the front element, or `None` if the sequence is
@@ -1177,9 +1197,44 @@ impl<T> DoubleEndedIterator<T> for MoveItems<T> {
1177
1197
}
1178
1198
}
1179
1199
1180
-
1181
1200
impl < T > ExactSizeIterator < T > for MoveItems < T > { }
1182
1201
1202
+ /// A draining RingBuf iterator
1203
+ pub struct Drain < ' a , T : ' a > {
1204
+ inner : & ' a mut RingBuf < T > ,
1205
+ }
1206
+
1207
+ #[ unsafe_destructor]
1208
+ impl < ' a , T : ' a > Drop for Drain < ' a , T > {
1209
+ fn drop ( & mut self ) {
1210
+ for _ in * self { }
1211
+ self . inner . head = 0 ;
1212
+ self . inner . tail = 0 ;
1213
+ }
1214
+ }
1215
+
1216
+ impl < ' a , T : ' a > Iterator < T > for Drain < ' a , T > {
1217
+ #[ inline]
1218
+ fn next ( & mut self ) -> Option < T > {
1219
+ self . inner . pop_front ( )
1220
+ }
1221
+
1222
+ #[ inline]
1223
+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
1224
+ let len = self . inner . len ( ) ;
1225
+ ( len, Some ( len) )
1226
+ }
1227
+ }
1228
+
1229
+ impl < ' a , T : ' a > DoubleEndedIterator < T > for Drain < ' a , T > {
1230
+ #[ inline]
1231
+ fn next_back ( & mut self ) -> Option < T > {
1232
+ self . inner . pop_back ( )
1233
+ }
1234
+ }
1235
+
1236
+ impl < ' a , T : ' a > ExactSizeIterator < T > for Drain < ' a , T > { }
1237
+
1183
1238
impl < A : PartialEq > PartialEq for RingBuf < A > {
1184
1239
fn eq ( & self , other : & RingBuf < A > ) -> bool {
1185
1240
self . len ( ) == other. len ( ) &&
@@ -1789,6 +1844,73 @@ mod tests {
1789
1844
}
1790
1845
}
1791
1846
1847
+ #[ test]
1848
+ fn test_drain ( ) {
1849
+
1850
+ // Empty iter
1851
+ {
1852
+ let mut d: RingBuf < int > = RingBuf :: new ( ) ;
1853
+
1854
+ {
1855
+ let mut iter = d. drain ( ) ;
1856
+
1857
+ assert_eq ! ( iter. size_hint( ) , ( 0 , Some ( 0 ) ) ) ;
1858
+ assert_eq ! ( iter. next( ) , None ) ;
1859
+ assert_eq ! ( iter. size_hint( ) , ( 0 , Some ( 0 ) ) ) ;
1860
+ }
1861
+
1862
+ assert ! ( d. is_empty( ) ) ;
1863
+ }
1864
+
1865
+ // simple iter
1866
+ {
1867
+ let mut d = RingBuf :: new ( ) ;
1868
+ for i in range ( 0 i, 5 ) {
1869
+ d. push_back ( i) ;
1870
+ }
1871
+
1872
+ assert_eq ! ( d. drain( ) . collect:: <Vec <int>>( ) , [ 0 , 1 , 2 , 3 , 4 ] ) ;
1873
+ assert ! ( d. is_empty( ) ) ;
1874
+ }
1875
+
1876
+ // wrapped iter
1877
+ {
1878
+ let mut d = RingBuf :: new ( ) ;
1879
+ for i in range ( 0 i, 5 ) {
1880
+ d. push_back ( i) ;
1881
+ }
1882
+ for i in range ( 6 , 9 ) {
1883
+ d. push_front ( i) ;
1884
+ }
1885
+
1886
+ assert_eq ! ( d. drain( ) . collect:: <Vec <int>>( ) , [ 8 , 7 , 6 , 0 , 1 , 2 , 3 , 4 ] ) ;
1887
+ assert ! ( d. is_empty( ) ) ;
1888
+ }
1889
+
1890
+ // partially used
1891
+ {
1892
+ let mut d = RingBuf :: new ( ) ;
1893
+ for i in range ( 0 i, 5 ) {
1894
+ d. push_back ( i) ;
1895
+ }
1896
+ for i in range ( 6 , 9 ) {
1897
+ d. push_front ( i) ;
1898
+ }
1899
+
1900
+ {
1901
+ let mut it = d. drain ( ) ;
1902
+ assert_eq ! ( it. size_hint( ) , ( 8 , Some ( 8 ) ) ) ;
1903
+ assert_eq ! ( it. next( ) , Some ( 8 ) ) ;
1904
+ assert_eq ! ( it. size_hint( ) , ( 7 , Some ( 7 ) ) ) ;
1905
+ assert_eq ! ( it. next_back( ) , Some ( 4 ) ) ;
1906
+ assert_eq ! ( it. size_hint( ) , ( 6 , Some ( 6 ) ) ) ;
1907
+ assert_eq ! ( it. next( ) , Some ( 7 ) ) ;
1908
+ assert_eq ! ( it. size_hint( ) , ( 5 , Some ( 5 ) ) ) ;
1909
+ }
1910
+ assert ! ( d. is_empty( ) ) ;
1911
+ }
1912
+ }
1913
+
1792
1914
#[ test]
1793
1915
fn test_from_iter ( ) {
1794
1916
use std:: iter;
0 commit comments