Skip to content

Commit 5df60f4

Browse files
committed
add LinkedList::{retain,retain_mut}
Signed-off-by: TennyZhuang <[email protected]>
1 parent 49a16b6 commit 5df60f4

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

library/alloc/src/collections/linked_list.rs

+93
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,99 @@ impl<T, A: Allocator> LinkedList<T, A> {
10241024
}
10251025
}
10261026

1027+
/// Retains only the elements specified by the predicate.
1028+
///
1029+
/// In other words, remove all elements `e` for which `f(&e)` returns false.
1030+
/// This method operates in place, visiting each element exactly once in the
1031+
/// original order, and preserves the order of the retained elements.
1032+
///
1033+
/// # Examples
1034+
///
1035+
/// ```
1036+
/// #![feature(linked_list_retain)]
1037+
/// use std::collections::LinkedList;
1038+
///
1039+
/// let mut d = LinkedList::new();
1040+
///
1041+
/// d.push_front(1);
1042+
/// d.push_front(2);
1043+
/// d.push_front(3);
1044+
///
1045+
/// d.retain(|&x| x % 2 == 0);
1046+
///
1047+
/// assert_eq!(d.pop_front(), Some(2));
1048+
/// assert_eq!(d.pop_front(), None);
1049+
/// ```
1050+
///
1051+
/// Because the elements are visited exactly once in the original order,
1052+
/// external state may be used to decide which elements to keep.
1053+
///
1054+
/// ```
1055+
/// #![feature(linked_list_retain)]
1056+
/// use std::collections::LinkedList;
1057+
///
1058+
/// let mut d = LinkedList::new();
1059+
///
1060+
/// d.push_front(1);
1061+
/// d.push_front(2);
1062+
/// d.push_front(3);
1063+
///
1064+
/// let keep = [false, true, false];
1065+
/// let mut iter = keep.iter();
1066+
/// d.retain(|_| *iter.next().unwrap());
1067+
/// assert_eq!(d.pop_front(), Some(2));
1068+
/// assert_eq!(d.pop_front(), None);
1069+
/// ```
1070+
#[unstable(feature = "linked_list_retain", issue = "114135")]
1071+
pub fn retain<F>(&mut self, mut f: F)
1072+
where
1073+
F: FnMut(&T) -> bool,
1074+
{
1075+
self.retain_mut(|elem| f(elem));
1076+
}
1077+
1078+
/// Retains only the elements specified by the predicate.
1079+
///
1080+
/// In other words, remove all elements `e` for which `f(&e)` returns false.
1081+
/// This method operates in place, visiting each element exactly once in the
1082+
/// original order, and preserves the order of the retained elements.
1083+
///
1084+
/// # Examples
1085+
///
1086+
/// ```
1087+
/// #![feature(linked_list_retain)]
1088+
/// use std::collections::LinkedList;
1089+
///
1090+
/// let mut d = LinkedList::new();
1091+
///
1092+
/// d.push_front(1);
1093+
/// d.push_front(2);
1094+
/// d.push_front(3);
1095+
///
1096+
/// d.retain_mut(|x| if *x % 2 == 0 {
1097+
/// *x += 1;
1098+
/// true
1099+
/// } else {
1100+
/// false
1101+
/// });
1102+
/// assert_eq!(d.pop_front(), Some(3));
1103+
/// assert_eq!(d.pop_front(), None);
1104+
/// ```
1105+
#[unstable(feature = "linked_list_retain", issue = "114135")]
1106+
pub fn retain_mut<F>(&mut self, mut f: F)
1107+
where
1108+
F: FnMut(&mut T) -> bool,
1109+
{
1110+
let mut cursor = self.cursor_front_mut();
1111+
while let Some(node) = cursor.current() {
1112+
if !f(node) {
1113+
cursor.remove_current().unwrap();
1114+
} else {
1115+
cursor.move_next();
1116+
}
1117+
}
1118+
}
1119+
10271120
/// Creates an iterator which uses a closure to determine if an element should be removed.
10281121
///
10291122
/// If the closure returns true, then the element is removed and yielded.

0 commit comments

Comments
 (0)