Skip to content

Commit 10b2351

Browse files
committed
Impl FromIterator for tuples with arity 1-12
1 parent 87e641a commit 10b2351

File tree

2 files changed

+47
-33
lines changed

2 files changed

+47
-33
lines changed

Diff for: library/core/src/iter/traits/collect.rs

+35-33
Original file line numberDiff line numberDiff line change
@@ -152,39 +152,6 @@ pub trait FromIterator<A>: Sized {
152152
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
153153
}
154154

155-
/// This implementation turns an iterator of tuples into a tuple of types which implement
156-
/// [`Default`] and [`Extend`].
157-
///
158-
/// This is similar to [`Iterator::unzip`], but is also composable with other [`FromIterator`]
159-
/// implementations:
160-
///
161-
/// ```rust
162-
/// # fn main() -> Result<(), core::num::ParseIntError> {
163-
/// let string = "1,2,123,4";
164-
///
165-
/// let (numbers, lengths): (Vec<_>, Vec<_>) = string
166-
/// .split(',')
167-
/// .map(|s| s.parse().map(|n: u32| (n, s.len())))
168-
/// .collect::<Result<_, _>>()?;
169-
///
170-
/// assert_eq!(numbers, [1, 2, 123, 4]);
171-
/// assert_eq!(lengths, [1, 1, 3, 1]);
172-
/// # Ok(()) }
173-
/// ```
174-
#[stable(feature = "from_iterator_for_tuple", since = "1.79.0")]
175-
impl<A, B, AE, BE> FromIterator<(AE, BE)> for (A, B)
176-
where
177-
A: Default + Extend<AE>,
178-
B: Default + Extend<BE>,
179-
{
180-
fn from_iter<I: IntoIterator<Item = (AE, BE)>>(iter: I) -> Self {
181-
let mut res = <(A, B)>::default();
182-
res.extend(iter);
183-
184-
res
185-
}
186-
}
187-
188155
/// Conversion into an [`Iterator`].
189156
///
190157
/// By implementing `IntoIterator` for a type, you define how it will be
@@ -671,6 +638,41 @@ macro_rules! spec_tuple_impl {
671638
}
672639
}
673640

641+
/// This implementation turns an iterator of tuples into a tuple of types which implement
642+
/// [`Default`] and [`Extend`].
643+
///
644+
/// This is similar to [`Iterator::unzip`], but is also composable with other [`FromIterator`]
645+
/// implementations:
646+
///
647+
/// ```rust
648+
/// # fn main() -> Result<(), core::num::ParseIntError> {
649+
/// let string = "1,2,123,4";
650+
///
651+
/// // Example given for a 2-tuple, but 1- through 12-tuples are supported
652+
/// let (numbers, lengths): (Vec<_>, Vec<_>) = string
653+
/// .split(',')
654+
/// .map(|s| s.parse().map(|n: u32| (n, s.len())))
655+
/// .collect::<Result<_, _>>()?;
656+
///
657+
/// assert_eq!(numbers, [1, 2, 123, 4]);
658+
/// assert_eq!(lengths, [1, 1, 3, 1]);
659+
/// # Ok(()) }
660+
/// ```
661+
#[$meta]
662+
$(#[$doctext])?
663+
#[stable(feature = "from_iterator_for_tuple", since = "1.79.0")]
664+
impl<$($ty_names,)* $($extend_ty_names,)*> FromIterator<($($extend_ty_names,)*)> for ($($ty_names,)*)
665+
where
666+
$($ty_names: Default + Extend<$extend_ty_names>,)*
667+
{
668+
fn from_iter<Iter: IntoIterator<Item = ($($extend_ty_names,)*)>>(iter: Iter) -> Self {
669+
let mut res = <($($ty_names,)*)>::default();
670+
res.extend(iter);
671+
672+
res
673+
}
674+
}
675+
674676
};
675677
}
676678

Diff for: library/core/tests/iter/traits/iterator.rs

+12
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,18 @@ fn test_collect_into_tuples() {
630630
assert!(e.2 == d);
631631
}
632632

633+
#[test]
634+
fn test_collect_for_tuples() {
635+
let a = vec![(1, 2, 3), (4, 5, 6), (7, 8, 9)];
636+
let b = vec![1, 4, 7];
637+
let c = vec![2, 5, 8];
638+
let d = vec![3, 6, 9];
639+
let e: (Vec<_>, Vec<_>, Vec<_>) = a.into_iter().collect();
640+
assert!(e.0 == b);
641+
assert!(e.1 == c);
642+
assert!(e.2 == d);
643+
}
644+
633645
// just tests by whether or not this compiles
634646
fn _empty_impl_all_auto_traits<T>() {
635647
use std::panic::{RefUnwindSafe, UnwindSafe};

0 commit comments

Comments
 (0)