about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-05-06 03:33:42 +0000
committerbors <bors@rust-lang.org>2015-05-06 03:33:42 +0000
commit5b04c16bd6954a28e1bcf5fcfc7fb9a784ca2914 (patch)
treef39129d59f8e11279f441e267d8983964c028af3
parent7bd71637ca40910dbd310813a19abf76db84f8f6 (diff)
parentdecf395221c986d41947266febf05ae18909b0e4 (diff)
downloadrust-5b04c16bd6954a28e1bcf5fcfc7fb9a784ca2914.tar.gz
rust-5b04c16bd6954a28e1bcf5fcfc7fb9a784ca2914.zip
Auto merge of #24879 - Stebalien:vec_deque, r=alexcrichton
According to rust-lang/rfcs#235, `VecDeque` should have this method (`VecDeque` was called `RingBuf` at the time) but it was never implemented.

I marked this stable since "1.0.0" because it's stable in `Vec`.
-rw-r--r--src/libcollections/vec_deque.rs36
-rw-r--r--src/libcollectionstest/lib.rs1
-rw-r--r--src/libcollectionstest/vec_deque.rs9
3 files changed, 46 insertions, 0 deletions
diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs
index 3032b13855b..f70906f84b8 100644
--- a/src/libcollections/vec_deque.rs
+++ b/src/libcollections/vec_deque.rs
@@ -1395,6 +1395,42 @@ impl<T> VecDeque<T> {
         // naive impl
         self.extend(other.drain());
     }
+
+    /// Retains only the elements specified by the predicate.
+    ///
+    /// In other words, remove all elements `e` such that `f(&e)` returns false.
+    /// This method operates in place and preserves the order of the retained
+    /// elements.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(vec_deque_retain)]
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.extend(1..5);
+    /// buf.retain(|&x| x%2 == 0);
+    ///
+    /// let v: Vec<_> = buf.into_iter().collect();
+    /// assert_eq!(&v[..], &[2, 4]);
+    /// ```
+    #[unstable(feature = "vec_deque_retain",
+               reason = "new API, waiting for dust to settle")]
+    pub fn retain<F>(&mut self, mut f: F) where F: FnMut(&T) -> bool {
+        let len = self.len();
+        let mut del = 0;
+        for i in 0..len {
+            if !f(&self[i]) {
+                del += 1;
+            } else if del > 0 {
+                self.swap(i-del, i);
+            }
+        }
+        if del > 0 {
+            self.truncate(len - del);
+        }
+    }
 }
 
 impl<T: Clone> VecDeque<T> {
diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs
index 57a95633b67..c5edc4e621b 100644
--- a/src/libcollectionstest/lib.rs
+++ b/src/libcollectionstest/lib.rs
@@ -21,6 +21,7 @@
 #![feature(into_cow)]
 #![feature(step_by)]
 #![cfg_attr(test, feature(str_char))]
+#![cfg_attr(test, feature(vec_deque_retain))]
 
 #[macro_use] extern crate log;
 
diff --git a/src/libcollectionstest/vec_deque.rs b/src/libcollectionstest/vec_deque.rs
index 12323286f6b..7870447281b 100644
--- a/src/libcollectionstest/vec_deque.rs
+++ b/src/libcollectionstest/vec_deque.rs
@@ -885,3 +885,12 @@ fn test_append() {
     assert_eq!(b.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
     assert_eq!(a.iter().cloned().collect::<Vec<_>>(), []);
 }
+
+#[test]
+fn test_retain() {
+    let mut buf = VecDeque::new();
+    buf.extend(1..5);
+    buf.retain(|&x| x % 2 == 0);
+    let v: Vec<_> = buf.into_iter().collect();
+    assert_eq!(&v[..], &[2, 4]);
+}