about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2024-06-04 21:41:33 +0200
committerGitHub <noreply@github.com>2024-06-04 21:41:33 +0200
commit190f221dba5d9d89707d4a75974ab7a231bdae1d (patch)
tree22cd22720dd50f7599a69254727baf7fe7060bfb
parent44701e070c8453df10df1984944258018ac21610 (diff)
parent6a84995fae01eb0ae18ef6bfc41b2979ca760447 (diff)
downloadrust-190f221dba5d9d89707d4a75974ab7a231bdae1d.tar.gz
rust-190f221dba5d9d89707d4a75974ab7a231bdae1d.zip
Rollup merge of #106186 - rossmacarthur:ft/iter-chain, r=Amanieu
Add function `core::iter::chain`

The addition of `core::iter::zip` (#82917) set a precedent for adding plain functions for iterator adaptors. Adding `chain` makes it a little easier to `chain` two iterators.

```rust
for (x, y) in chain(xs, ys) {}
// vs.
for (x, y) in xs.into_iter().chain(ys) {}
```

There is prior art for the utility of this in [`itertools::chain`](https://docs.rs/itertools/latest/itertools/fn.chain.html).

Approved ACP https://github.com/rust-lang/libs-team/issues/154
-rw-r--r--library/core/src/iter/adapters/chain.rs37
-rw-r--r--library/core/src/iter/adapters/mod.rs3
-rw-r--r--library/core/src/iter/mod.rs2
-rw-r--r--library/core/tests/iter/adapters/chain.rs8
-rw-r--r--library/core/tests/lib.rs1
5 files changed, 49 insertions, 2 deletions
diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs
index bcaac2f42cf..dad3d79acb1 100644
--- a/library/core/src/iter/adapters/chain.rs
+++ b/library/core/src/iter/adapters/chain.rs
@@ -4,8 +4,8 @@ use crate::ops::Try;
 
 /// An iterator that links two iterators together, in a chain.
 ///
-/// This `struct` is created by [`Iterator::chain`]. See its documentation
-/// for more.
+/// This `struct` is created by [`chain`] or [`Iterator::chain`]. See their
+/// documentation for more.
 ///
 /// # Examples
 ///
@@ -38,6 +38,39 @@ impl<A, B> Chain<A, B> {
     }
 }
 
+/// Converts the arguments to iterators and links them together, in a chain.
+///
+/// See the documentation of [`Iterator::chain`] for more.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(iter_chain)]
+///
+/// use std::iter::chain;
+///
+/// let a = [1, 2, 3];
+/// let b = [4, 5, 6];
+///
+/// let mut iter = chain(a, b);
+///
+/// assert_eq!(iter.next(), Some(1));
+/// assert_eq!(iter.next(), Some(2));
+/// assert_eq!(iter.next(), Some(3));
+/// assert_eq!(iter.next(), Some(4));
+/// assert_eq!(iter.next(), Some(5));
+/// assert_eq!(iter.next(), Some(6));
+/// assert_eq!(iter.next(), None);
+/// ```
+#[unstable(feature = "iter_chain", reason = "recently added", issue = "125964")]
+pub fn chain<A, B>(a: A, b: B) -> Chain<A::IntoIter, B::IntoIter>
+where
+    A: IntoIterator,
+    B: IntoIterator<Item = A::Item>,
+{
+    Chain::new(a.into_iter(), b.into_iter())
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A, B> Iterator for Chain<A, B>
 where
diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs
index cc514bd914f..05a5f268905 100644
--- a/library/core/src/iter/adapters/mod.rs
+++ b/library/core/src/iter/adapters/mod.rs
@@ -41,6 +41,9 @@ pub use self::array_chunks::ArrayChunks;
 #[unstable(feature = "std_internals", issue = "none")]
 pub use self::by_ref_sized::ByRefSized;
 
+#[unstable(feature = "iter_chain", reason = "recently added", issue = "125964")]
+pub use self::chain::chain;
+
 #[stable(feature = "iter_cloned", since = "1.1.0")]
 pub use self::cloned::Cloned;
 
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index 44fef3e145b..921c75c85f1 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -428,6 +428,8 @@ pub use self::traits::{
     DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum,
 };
 
+#[unstable(feature = "iter_chain", reason = "recently added", issue = "125964")]
+pub use self::adapters::chain;
 #[stable(feature = "iter_zip", since = "1.59.0")]
 pub use self::adapters::zip;
 #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
diff --git a/library/core/tests/iter/adapters/chain.rs b/library/core/tests/iter/adapters/chain.rs
index b2429588de1..c93510df524 100644
--- a/library/core/tests/iter/adapters/chain.rs
+++ b/library/core/tests/iter/adapters/chain.rs
@@ -3,6 +3,14 @@ use core::iter::*;
 use core::num::NonZero;
 
 #[test]
+fn test_chain() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let ys = [30, 40, 50, 60];
+    let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
+    assert_eq!(Vec::from_iter(chain(xs, ys)), expected);
+}
+
+#[test]
 fn test_iterator_chain() {
     let xs = [0, 1, 2, 3, 4, 5];
     let ys = [30, 40, 50, 60];
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index e0f82c91663..20ff6fd7687 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -75,6 +75,7 @@
 #![feature(ip)]
 #![feature(iter_advance_by)]
 #![feature(iter_array_chunks)]
+#![feature(iter_chain)]
 #![feature(iter_collect_into)]
 #![feature(iter_partition_in_place)]
 #![feature(iter_intersperse)]