diff options
| author | bors <bors@rust-lang.org> | 2015-05-06 03:33:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-05-06 03:33:42 +0000 |
| commit | 5b04c16bd6954a28e1bcf5fcfc7fb9a784ca2914 (patch) | |
| tree | f39129d59f8e11279f441e267d8983964c028af3 | |
| parent | 7bd71637ca40910dbd310813a19abf76db84f8f6 (diff) | |
| parent | decf395221c986d41947266febf05ae18909b0e4 (diff) | |
| download | rust-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.rs | 36 | ||||
| -rw-r--r-- | src/libcollectionstest/lib.rs | 1 | ||||
| -rw-r--r-- | src/libcollectionstest/vec_deque.rs | 9 |
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]); +} |
