Skip to content

Commit addb1c8

Browse files
committed
add Iterator::contains
1 parent 59aa1e8 commit addb1c8

File tree

5 files changed

+58
-0
lines changed

5 files changed

+58
-0
lines changed

library/core/src/iter/traits/iterator.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2826,6 +2826,43 @@ pub trait Iterator {
28262826
self.try_fold((), check(f)) == ControlFlow::Break(())
28272827
}
28282828

2829+
/// Tests whether a value is contained in the iterator.
2830+
///
2831+
/// `contains()` is short-circuiting; in other words, it will stop processing
2832+
/// as soon as the function finds the item in the `Iterator`.
2833+
///
2834+
/// This method checks the whole iterator, which is O(n). If the iterator is a sorted
2835+
/// slice, [`binary_search`](slice::binary_search) may be faster. If this is an iterator
2836+
/// on collections that have a `.contains()` or `.contains_key()` method (such as
2837+
/// `HashMap` or `BtreeSet`), using those methods directly will be faster.
2838+
///
2839+
/// # Examples
2840+
///
2841+
/// Basic usage:
2842+
///
2843+
/// ```
2844+
/// #![feature(iter_contains)]
2845+
/// assert!([1, 2, 3].iter().contains(2));
2846+
/// assert!(![1, 2, 3].iter().contains(5));
2847+
/// ```
2848+
///
2849+
/// [`Iterator::contains`] can be used where [`slice::contains`] cannot be used:
2850+
///
2851+
/// ```
2852+
/// #![feature(iter_contains)]
2853+
/// let s = [String::from("a"), String::from("b"), String::from("c")];
2854+
/// assert!(s.iter().contains("b"));
2855+
/// ```
2856+
#[inline]
2857+
#[unstable(feature = "iter_contains", issue = "127494")]
2858+
fn contains<Q>(&mut self, item: Q) -> bool
2859+
where
2860+
Q: PartialEq<Self::Item> + ?Sized,
2861+
Self: Sized,
2862+
{
2863+
self.any(|elem| item == elem)
2864+
}
2865+
28292866
/// Searches for an element of an iterator that satisfies a predicate.
28302867
///
28312868
/// `find()` takes a closure that returns `true` or `false`. It applies

library/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
#![feature(internal_impls_macro)]
111111
#![feature(ip)]
112112
#![feature(is_ascii_octdigit)]
113+
#![feature(iter_contains)]
113114
#![feature(lazy_get)]
114115
#![feature(link_cfg)]
115116
#![feature(offset_of_enum)]

library/core/src/str/iter.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,14 @@ impl Iterator for Bytes<'_> {
331331
self.0.any(f)
332332
}
333333

334+
#[inline]
335+
fn contains<Q>(&mut self, item: Q) -> bool
336+
where
337+
Q: PartialEq<Self::Item> + ?Sized,
338+
{
339+
self.0.contains(item)
340+
}
341+
334342
#[inline]
335343
fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
336344
where

library/coretests/tests/iter/traits/iterator.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,17 @@ fn test_any() {
272272
assert!(!v[..0].iter().any(|_| panic!()));
273273
}
274274

275+
#[test]
276+
fn test_iterator_contains() {
277+
let v: Box<[isize]> = Box::new([1, 2, 3, 4, 5]);
278+
assert_eq!(true, v.iter().contains(&3));
279+
assert_eq!(v.iter().contains(&3), v.iter().any(|&x| x == 3));
280+
assert_eq!(false, v.iter().contains(&10));
281+
assert_eq!(v.iter().contains(&10), v.iter().any(|&x| x == 10));
282+
assert_eq!(true, Iterator::contains(&mut (1isize..=5), 3));
283+
assert_eq!(false, Iterator::contains(&mut (1isize..=5), 10));
284+
}
285+
275286
#[test]
276287
fn test_find() {
277288
let v: &[isize] = &[1, 3, 9, 27, 103, 14, 11];

library/coretests/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#![feature(iter_array_chunks)]
5656
#![feature(iter_chain)]
5757
#![feature(iter_collect_into)]
58+
#![feature(iter_contains)]
5859
#![feature(iter_intersperse)]
5960
#![feature(iter_is_partitioned)]
6061
#![feature(iter_map_windows)]

0 commit comments

Comments
 (0)