@@ -152,7 +152,7 @@ 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
155+ /*/ // This implementation turns an iterator of tuples into a tuple of types which implement
156156/// [`Default`] and [`Extend`].
157157///
158158/// This is similar to [`Iterator::unzip`], but is also composable with other [`FromIterator`]
@@ -183,7 +183,7 @@ where
183183
184184 res
185185 }
186- }
186+ }*/
187187
188188/// Conversion into an [`Iterator`].
189189///
@@ -595,32 +595,67 @@ macro_rules! spec_tuple_impl {
595595 Iter : TrustedLen <Item = ( $( $ty_names, ) * ) >,
596596 {
597597 fn extend( self , $( $var_names: & mut $extend_ty_names, ) * ) {
598- fn extend<' a, $( $ty_names, ) * >(
599- $( $var_names: & ' a mut impl Extend <$ty_names>, ) *
600- ) -> impl FnMut ( ( ) , ( $( $ty_names, ) * ) ) + ' a {
601- #[ allow( non_snake_case) ]
602- // SAFETY: We reserve enough space for the `size_hint`, and the iterator is `TrustedLen`
603- // so its `size_hint` is exact.
604- move |( ) , ( $( $extend_ty_names, ) * ) | unsafe {
605- $( $var_names. extend_one_unchecked( $extend_ty_names) ; ) *
598+ fn extend<' a, $( $ty_names, ) * >(
599+ $( $var_names: & ' a mut impl Extend <$ty_names>, ) *
600+ ) -> impl FnMut ( ( ) , ( $( $ty_names, ) * ) ) + ' a {
601+ #[ allow( non_snake_case) ]
602+ // SAFETY: We reserve enough space for the `size_hint`, and the iterator is `TrustedLen`
603+ // so its `size_hint` is exact.
604+ move |( ) , ( $( $extend_ty_names, ) * ) | unsafe {
605+ $( $var_names. extend_one_unchecked( $extend_ty_names) ; ) *
606+ }
606607 }
607- }
608608
609- let ( lower_bound, upper_bound) = self . size_hint( ) ;
609+ let ( lower_bound, upper_bound) = self . size_hint( ) ;
610610
611- if upper_bound. is_none( ) {
612- // We cannot reserve more than `usize::MAX` items, and this is likely to go out of memory anyway.
613- $default_fn_name( self , $( $var_names, ) * ) ;
614- return ;
615- }
611+ if upper_bound. is_none( ) {
612+ // We cannot reserve more than `usize::MAX` items, and this is likely to go out of memory anyway.
613+ $default_fn_name( self , $( $var_names, ) * ) ;
614+ return ;
615+ }
616616
617- if lower_bound > 0 {
618- $( $var_names. extend_reserve( lower_bound) ; ) *
617+ if lower_bound > 0 {
618+ $( $var_names. extend_reserve( lower_bound) ; ) *
619+ }
620+
621+ self . fold( ( ) , extend( $( $var_names, ) * ) ) ;
619622 }
623+ }
624+
625+ /// This implementation turns an iterator of tuples into a tuple of types which implement
626+ /// [`Default`] and [`Extend`].
627+ ///
628+ /// This is similar to [`Iterator::unzip`], but is also composable with other [`FromIterator`]
629+ /// implementations:
630+ ///
631+ /// ```rust
632+ /// # fn main() -> Result<(), core::num::ParseIntError> {
633+ /// let string = "1,2,123,4";
634+ ///
635+ /// // Example given for a 2-tuple, but 1- through 12-tuples are supported
636+ /// let (numbers, lengths): (Vec<_>, Vec<_>) = string
637+ /// .split(',')
638+ /// .map(|s| s.parse().map(|n: u32| (n, s.len())))
639+ /// .collect::<Result<_, _>>()?;
640+ ///
641+ /// assert_eq!(numbers, [1, 2, 123, 4]);
642+ /// assert_eq!(lengths, [1, 1, 3, 1]);
643+ /// # Ok(()) }
644+ /// ```
645+ #[ $meta]
646+ $( #[ $doctext] ) ?
647+ #[ stable( feature = "from_iterator_for_tuple" , since = "1.79.0" ) ]
648+ impl <$( $ty_names, ) * $( $extend_ty_names, ) * > FromIterator <( $( $extend_ty_names, ) * ) > for ( $( $ty_names, ) * )
649+ where
650+ $( $ty_names: Default + Extend <$extend_ty_names>, ) *
651+ {
652+ fn from_iter<Iter : IntoIterator <Item = ( $( $extend_ty_names, ) * ) >>( iter: Iter ) -> Self {
653+ let mut res = <( $( $ty_names, ) * ) >:: default ( ) ;
654+ res. extend( iter) ;
620655
621- self . fold( ( ) , extend( $( $var_names, ) * ) ) ;
656+ res
657+ }
622658 }
623- }
624659
625660 } ;
626661}
0 commit comments