From b19dd145ea9d5ecd1f0af3d12a5a0dc5e7555dd1 Mon Sep 17 00:00:00 2001 From: Ross MacArthur Date: Tue, 4 Jun 2024 10:51:05 +0200 Subject: [PATCH] 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. ``` for (x, y) in chain(xs, ys) {} // vs. for (x, y) in xs.into_iter().chain(ys) {} ``` --- core/src/iter/adapters/chain.rs | 37 +++++++++++++++++++++++++++++-- core/src/iter/adapters/mod.rs | 3 +++ core/src/iter/mod.rs | 2 ++ core/tests/iter/adapters/chain.rs | 8 +++++++ core/tests/lib.rs | 1 + 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/core/src/iter/adapters/chain.rs b/core/src/iter/adapters/chain.rs index bcaac2f42cf04..dad3d79acb183 100644 --- a/core/src/iter/adapters/chain.rs +++ b/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 Chain { } } +/// 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: A, b: B) -> Chain +where + A: IntoIterator, + B: IntoIterator, +{ + Chain::new(a.into_iter(), b.into_iter()) +} + #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Chain where diff --git a/core/src/iter/adapters/mod.rs b/core/src/iter/adapters/mod.rs index cc514bd914f14..05a5f2689056b 100644 --- a/core/src/iter/adapters/mod.rs +++ b/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/core/src/iter/mod.rs b/core/src/iter/mod.rs index 44fef3e145b78..921c75c85f161 100644 --- a/core/src/iter/mod.rs +++ b/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/core/tests/iter/adapters/chain.rs b/core/tests/iter/adapters/chain.rs index b2429588de12b..c93510df524cf 100644 --- a/core/tests/iter/adapters/chain.rs +++ b/core/tests/iter/adapters/chain.rs @@ -2,6 +2,14 @@ use super::*; 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]; diff --git a/core/tests/lib.rs b/core/tests/lib.rs index e0f82c916635e..20ff6fd7687fe 100644 --- a/core/tests/lib.rs +++ b/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)]