Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit dc17002

Browse files
committed
add Iterator::dedup and friends
1 parent 6ba0ce4 commit dc17002

File tree

5 files changed

+219
-8
lines changed

5 files changed

+219
-8
lines changed

‎compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,10 +1457,8 @@ fn print_native_static_libs(
14571457
all_native_libs: &[NativeLib],
14581458
all_rust_dylibs: &[&Path],
14591459
) {
1460-
let mut lib_args: Vec<_> = all_native_libs
1461-
.iter()
1462-
.filter(|l| relevant_lib(sess, l))
1463-
.filter_map(|lib| {
1460+
let mut lib_args: Vec<_> = Itertools::dedup(
1461+
all_native_libs.iter().filter(|l| relevant_lib(sess, l)).filter_map(|lib| {
14641462
let name = lib.name;
14651463
match lib.kind {
14661464
NativeLibKind::Static { bundle: Some(false), .. }
@@ -1486,10 +1484,9 @@ fn print_native_static_libs(
14861484
| NativeLibKind::WasmImportModule
14871485
| NativeLibKind::RawDylib => None,
14881486
}
1489-
})
1490-
// deduplication of consecutive repeated libraries, see rust-lang/rust#113209
1491-
.dedup()
1492-
.collect();
1487+
}), // deduplication of consecutive repeated libraries, see rust-lang/rust#113209
1488+
)
1489+
.collect();
14931490
for path in all_rust_dylibs {
14941491
// FIXME deduplicate with add_dynamic_crate
14951492

‎library/core/src/iter/adapters/dedup.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
trait DedupPredicate<T> {
2+
fn eq(&mut self, a: &T, b: &T) -> bool;
3+
}
4+
5+
impl<T, F: FnMut(&T, &T) -> bool> DedupPredicate<T> for F {
6+
fn eq(&mut self, a: &T, b: &T) -> bool {
7+
self(a, b)
8+
}
9+
}
10+
11+
#[unstable(feature = "iter_dedup", issue = "83747")]
12+
#[doc(hidden)]
13+
#[derive(Debug)]
14+
pub struct DedupEq;
15+
16+
impl<T: PartialEq> DedupPredicate<T> for DedupEq {
17+
fn eq(&mut self, a: &T, b: &T) -> bool {
18+
a == b
19+
}
20+
}
21+
22+
#[unstable(feature = "iter_dedup", issue = "83747")]
23+
#[doc(hidden)]
24+
#[derive(Debug)]
25+
pub struct DedupKey<F>(pub F);
26+
27+
impl<T, K: PartialEq, F: Fn(&T) -> K> DedupPredicate<T> for DedupKey<F> {
28+
fn eq(&mut self, a: &T, b: &T) -> bool {
29+
(self.0)(a) == (self.0)(b)
30+
}
31+
}
32+
33+
/// An iterator to deduplicate adjacent items in another iterator.
34+
///
35+
/// This `struct` is created by the [`dedup`], [`dedup_by`], and
36+
/// [`dedup_by_key`] methods on [`Iterator`]. See their documentation for more.
37+
///
38+
/// [`dedup`]: Iterator::dedup
39+
/// [`dedup_by`]: Iterator::dedup_by
40+
/// [`dedup_by_key`]: Iterator::dedup_by_key
41+
#[unstable(feature = "iter_dedup", issue = "83747")]
42+
#[derive(Debug)]
43+
pub struct Dedup<I: Iterator, F> {
44+
inner: I,
45+
f: F,
46+
last: Option<I::Item>,
47+
}
48+
49+
impl<I: Iterator, F> Dedup<I, F> {
50+
pub(in crate::iter) fn new(mut it: I, f: F) -> Self {
51+
let first = it.next();
52+
Self { inner: it, f, last: first }
53+
}
54+
}
55+
56+
#[unstable(feature = "iter_dedup", issue = "83747")]
57+
impl<I, F> Iterator for Dedup<I, F>
58+
where
59+
I: Iterator,
60+
I::Item: Clone,
61+
F: DedupPredicate<I::Item>,
62+
{
63+
type Item = I::Item;
64+
65+
fn next(&mut self) -> Option<Self::Item> {
66+
let last = self.last.as_ref()?;
67+
self.last = self.inner.find(|e| self.f.eq(e, last));
68+
return self.last.clone();
69+
}
70+
}

‎library/core/src/iter/adapters/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod chain;
88
mod cloned;
99
mod copied;
1010
mod cycle;
11+
mod dedup;
1112
mod enumerate;
1213
mod filter;
1314
mod filter_map;
@@ -38,6 +39,10 @@ pub use self::chain::chain;
3839
pub use self::cloned::Cloned;
3940
#[stable(feature = "iter_copied", since = "1.36.0")]
4041
pub use self::copied::Copied;
42+
#[unstable(feature = "iter_dedup", issue = "83747")]
43+
pub use self::dedup::Dedup;
44+
#[unstable(feature = "iter_dedup", issue = "83747")]
45+
pub use self::dedup::{DedupEq, DedupKey};
4146
#[stable(feature = "iterator_flatten", since = "1.29.0")]
4247
pub use self::flatten::Flatten;
4348
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]

‎library/core/src/iter/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ pub use self::adapters::{
414414
Chain, Cycle, Enumerate, Filter, FilterMap, FlatMap, Fuse, Inspect, Map, Peekable, Rev, Scan,
415415
Skip, SkipWhile, Take, TakeWhile, Zip,
416416
};
417+
#[unstable(feature = "iter_dedup", issue = "83747")]
418+
pub use self::adapters::{Dedup, DedupEq, DedupKey};
417419
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
418420
pub use self::adapters::{Intersperse, IntersperseWith};
419421
#[unstable(

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

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use super::super::{
66
};
77
use crate::array;
88
use crate::cmp::{self, Ordering};
9+
use crate::iter::adapters::{Dedup, DedupEq, DedupKey};
910
use crate::num::NonZero;
1011
use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try};
1112

@@ -1863,6 +1864,142 @@ pub trait Iterator {
18631864
Inspect::new(self, f)
18641865
}
18651866

1867+
/// Removes all but the first of consecutive repeated elements in the iterator
1868+
/// according to the [`PartialEq`] trait implementation.
1869+
///
1870+
/// For an iterator yielding infinitely many consecutive duplicates,
1871+
/// calling [`next`][Iterator::next] on this iterator may never halt.
1872+
///
1873+
/// If the iterator is sorted, this removes all duplicates.
1874+
///
1875+
/// # Examples
1876+
///
1877+
/// Basic usage:
1878+
///
1879+
/// ```
1880+
/// #![feature(iter_dedup)]
1881+
///
1882+
/// let vec = vec![1, 2, 2, 3, 2];
1883+
///
1884+
/// let mut iter = vec.into_iter().dedup();
1885+
///
1886+
/// assert_eq!(iter.next(), Some(1));
1887+
/// assert_eq!(iter.next(), Some(2));
1888+
/// assert_eq!(iter.next(), Some(3));
1889+
/// assert_eq!(iter.next(), Some(2));
1890+
/// assert_eq!(iter.next(), None);
1891+
/// ```
1892+
///
1893+
/// Example of an infinite loop:
1894+
///
1895+
/// ```no_run
1896+
/// #![feature(iter_dedup)]
1897+
///
1898+
/// // this will never terminate
1899+
/// let _ = std::iter::repeat(2).dedup().next();
1900+
/// ```
1901+
#[unstable(feature = "iter_dedup", issue = "83747")]
1902+
#[inline]
1903+
fn dedup<F>(self) -> Dedup<Self, DedupEq>
1904+
where
1905+
Self: Sized,
1906+
Self::Item: PartialEq,
1907+
{
1908+
Dedup::new(self, DedupEq)
1909+
}
1910+
1911+
/// Removes all but the first of consecutive elements in the iterator
1912+
/// satisfying a given equality relation.
1913+
///
1914+
/// The `same_bucket` function is passed a references to two elements from
1915+
/// the iterator and must determine if the elements compare equal.
1916+
///
1917+
/// For an iterator yielding infinitely many consecutive duplicates,
1918+
/// calling [`next`][Iterator::next] on this iterator may never halt.
1919+
///
1920+
/// If the iterator is sorted, this removes all duplicates.
1921+
///
1922+
/// # Examples
1923+
///
1924+
/// Basic usage:
1925+
///
1926+
/// ```
1927+
/// #![feature(iter_dedup)]
1928+
///
1929+
/// let vec = vec!["foo", "bar", "Bar", "baz", "bar"];
1930+
///
1931+
/// let mut iter = vec.into_iter().dedup_by(|a, b| a.eq_ignore_ascii_case(b));
1932+
///
1933+
/// assert_eq!(iter.next(), Some("foo"));
1934+
/// assert_eq!(iter.next(), Some("bar"));
1935+
/// assert_eq!(iter.next(), Some("baz"));
1936+
/// assert_eq!(iter.next(), Some("bar"));
1937+
/// assert_eq!(iter.next(), None);
1938+
/// ```
1939+
///
1940+
/// Example of an infinite loop:
1941+
///
1942+
/// ```no_run
1943+
/// #![feature(iter_dedup)]
1944+
///
1945+
/// // this will never terminate
1946+
/// let _ = std::iter::repeat(2).dedup_by(|a, b| a == b).next();
1947+
/// ```
1948+
#[unstable(feature = "iter_dedup", issue = "83747")]
1949+
#[inline]
1950+
fn dedup_by<F>(self, f: F) -> Dedup<Self, F>
1951+
where
1952+
Self: Sized,
1953+
F: FnMut(&Self::Item, &Self::Item) -> bool,
1954+
{
1955+
Dedup::new(self, f)
1956+
}
1957+
1958+
/// Removes all but the first of consecutive elements in the iterator
1959+
/// that resolve to the same key.
1960+
///
1961+
/// For an iterator yielding infinitely many consecutive duplicates,
1962+
/// calling [`next`][Iterator::next] on this iterator may never halt.
1963+
///
1964+
/// If the iterator is sorted, this removes all duplicates.
1965+
///
1966+
/// # Examples
1967+
///
1968+
/// Basic usage:
1969+
///
1970+
/// ```
1971+
/// #![feature(iter_dedup)]
1972+
///
1973+
/// let vec = vec![10, 20, 21, 30, 20];
1974+
///
1975+
/// let mut iter = vec.into_iter().dedup_by_key(|&i| i / 10);
1976+
///
1977+
/// assert_eq!(iter.next(), Some(10));
1978+
/// assert_eq!(iter.next(), Some(20));
1979+
/// assert_eq!(iter.next(), Some(30));
1980+
/// assert_eq!(iter.next(), Some(20));
1981+
/// assert_eq!(iter.next(), None);
1982+
/// ```
1983+
///
1984+
/// Example of an infinite loop:
1985+
///
1986+
/// ```no_run
1987+
/// #![feature(iter_dedup)]
1988+
///
1989+
/// // this will never terminate
1990+
/// let _ = std::iter::repeat(2).dedup_by_key(|&n| n).next();
1991+
/// ```
1992+
#[unstable(feature = "iter_dedup", issue = "83747")]
1993+
#[inline]
1994+
fn dedup_by_key<F, K>(self, f: F) -> Dedup<Self, DedupKey<F>>
1995+
where
1996+
Self: Sized,
1997+
F: FnMut(&Self::Item) -> K,
1998+
K: PartialEq,
1999+
{
2000+
Dedup::new(self, DedupKey(f))
2001+
}
2002+
18662003
/// Creates a "by reference" adapter for this instance of `Iterator`.
18672004
///
18682005
/// Consuming method calls (direct or indirect calls to `next`)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /