Skip to content

Commit 16e356e

Browse files
committed
Auto merge of #60396 - cuviper:ordered-retain, r=scottmcm
Document the order of {Vec,VecDeque,String}::retain It's natural for `retain` to work in order from beginning to end, but this wasn't actually documented to be the case. If we actually promise this, then the caller can do useful things like track the index of each element being tested, as [discussed in the forum][1]. This is now documented for `Vec`, `VecDeque`, and `String`. [1]: https://users.rust-lang.org/t/vec-retain-by-index/27697 `HashMap` and `HashSet` also have `retain`, and the `hashbrown` implementation does happen to use a plain `iter()` order too, but it's not certain that this should always be the case for these types. r? @scottmcm
2 parents d28e948 + 0545375 commit 16e356e

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

src/liballoc/collections/vec_deque.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -1835,8 +1835,8 @@ impl<T> VecDeque<T> {
18351835
/// Retains only the elements specified by the predicate.
18361836
///
18371837
/// In other words, remove all elements `e` such that `f(&e)` returns false.
1838-
/// This method operates in place and preserves the order of the retained
1839-
/// elements.
1838+
/// This method operates in place, visiting each element exactly once in the
1839+
/// original order, and preserves the order of the retained elements.
18401840
///
18411841
/// # Examples
18421842
///
@@ -1848,6 +1848,20 @@ impl<T> VecDeque<T> {
18481848
/// buf.retain(|&x| x%2 == 0);
18491849
/// assert_eq!(buf, [2, 4]);
18501850
/// ```
1851+
///
1852+
/// The exact order may be useful for tracking external state, like an index.
1853+
///
1854+
/// ```
1855+
/// use std::collections::VecDeque;
1856+
///
1857+
/// let mut buf = VecDeque::new();
1858+
/// buf.extend(1..6);
1859+
///
1860+
/// let keep = [false, true, true, false, true];
1861+
/// let mut i = 0;
1862+
/// buf.retain(|_| (keep[i], i += 1).0);
1863+
/// assert_eq!(buf, [2, 3, 5]);
1864+
/// ```
18511865
#[stable(feature = "vec_deque_retain", since = "1.4.0")]
18521866
pub fn retain<F>(&mut self, mut f: F)
18531867
where F: FnMut(&T) -> bool

src/liballoc/string.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -1200,8 +1200,8 @@ impl String {
12001200
/// Retains only the characters specified by the predicate.
12011201
///
12021202
/// In other words, remove all characters `c` such that `f(c)` returns `false`.
1203-
/// This method operates in place and preserves the order of the retained
1204-
/// characters.
1203+
/// This method operates in place, visiting each character exactly once in the
1204+
/// original order, and preserves the order of the retained characters.
12051205
///
12061206
/// # Examples
12071207
///
@@ -1212,6 +1212,16 @@ impl String {
12121212
///
12131213
/// assert_eq!(s, "foobar");
12141214
/// ```
1215+
///
1216+
/// The exact order may be useful for tracking external state, like an index.
1217+
///
1218+
/// ```
1219+
/// let mut s = String::from("abcde");
1220+
/// let keep = [false, true, true, false, true];
1221+
/// let mut i = 0;
1222+
/// s.retain(|_| (keep[i], i += 1).0);
1223+
/// assert_eq!(s, "bce");
1224+
/// ```
12151225
#[inline]
12161226
#[stable(feature = "string_retain", since = "1.26.0")]
12171227
pub fn retain<F>(&mut self, mut f: F)

src/liballoc/vec.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -937,8 +937,8 @@ impl<T> Vec<T> {
937937
/// Retains only the elements specified by the predicate.
938938
///
939939
/// In other words, remove all elements `e` such that `f(&e)` returns `false`.
940-
/// This method operates in place and preserves the order of the retained
941-
/// elements.
940+
/// This method operates in place, visiting each element exactly once in the
941+
/// original order, and preserves the order of the retained elements.
942942
///
943943
/// # Examples
944944
///
@@ -947,6 +947,16 @@ impl<T> Vec<T> {
947947
/// vec.retain(|&x| x%2 == 0);
948948
/// assert_eq!(vec, [2, 4]);
949949
/// ```
950+
///
951+
/// The exact order may be useful for tracking external state, like an index.
952+
///
953+
/// ```
954+
/// let mut vec = vec![1, 2, 3, 4, 5];
955+
/// let keep = [false, true, true, false, true];
956+
/// let mut i = 0;
957+
/// vec.retain(|_| (keep[i], i += 1).0);
958+
/// assert_eq!(vec, [2, 3, 5]);
959+
/// ```
950960
#[stable(feature = "rust1", since = "1.0.0")]
951961
pub fn retain<F>(&mut self, mut f: F)
952962
where F: FnMut(&T) -> bool

0 commit comments

Comments
 (0)