@@ -478,14 +478,15 @@ macro_rules! spec_tuple_impl {
478478 $( $remainder, ) *
479479 ) ;
480480 } ;
481- ( [ $( $params_: tt) * ] ) => { } ;
481+ ( [ $( $params_: tt) * ] ) => { } ;
482482 (
483483 $SpecTupleExtendN: ident, $default_extend_tuple_n: ident,
484484 $params: tt
485485 ) => {
486486 spec_tuple_impl!(
487487 $SpecTupleExtendN,
488488 $default_extend_tuple_n,
489+ #special_case_1_tuple
489490 #[ doc( fake_variadic) ]
490491 #[ doc = "This trait is implemented for tuples up to twelve items long. The `impl`s for \
491492 1- and 3- through 12-ary tuples were stabilized after 2-tuples, in \
@@ -500,12 +501,14 @@ macro_rules! spec_tuple_impl {
500501 spec_tuple_impl!(
501502 $SpecTupleExtendN,
502503 $default_extend_tuple_n,
504+ #normal_case
503505 #[ doc( hidden) ]
504506 => $( $params, ) +
505507 ) ;
506508 } ;
507509 (
508- $SpecTupleExtendN: ident, $default_extend_tuple_n: ident, #[ $meta: meta]
510+ $SpecTupleExtendN: ident, $default_extend_tuple_n: ident, #$maybe_special_case: tt
511+ #[ $meta: meta]
509512 $( #[ $doctext: meta] ) ? => $(
510513 (
511514 $Ts: ident, $var_names: ident, $ExtendTs: ident, $cnts: tt
@@ -519,32 +522,15 @@ macro_rules! spec_tuple_impl {
519522 where
520523 $( $ExtendTs: Extend <$Ts>, ) *
521524 {
522- /// Allows to `extend` a tuple of collections that also implement `Extend`.
523- ///
524- /// See also: [`Iterator::unzip`]
525- ///
526- /// # Examples
527- /// ```
528- /// // Example given for a 2-tuple, but 1- through 12-tuples are supported
529- /// let mut tuple = (vec![0], vec![1]);
530- /// tuple.extend([(2, 3), (4, 5), (6, 7)]);
531- /// assert_eq!(tuple.0, [0, 2, 4, 6]);
532- /// assert_eq!(tuple.1, [1, 3, 5, 7]);
533- ///
534- /// // also allows for arbitrarily nested tuples as elements
535- /// let mut nested_tuple = (vec![1], (vec![2], vec![3]));
536- /// nested_tuple.extend([(4, (5, 6)), (7, (8, 9))]);
537- ///
538- /// let (a, (b, c)) = nested_tuple;
539- /// assert_eq!(a, [1, 4, 7]);
540- /// assert_eq!(b, [2, 5, 8]);
541- /// assert_eq!(c, [3, 6, 9]);
542- /// ```
543- fn extend<I : IntoIterator <Item = ( $( $Ts, ) * ) >>( & mut self , into_iter: I ) {
544- let ( $( $var_names, ) * ) = self ;
545- let iter = into_iter. into_iter( ) ;
546- $SpecTupleExtendN:: extend( iter, $( $var_names, ) * ) ;
547- }
525+
526+ spec_tuple_impl!( #$maybe_special_case
527+
528+ fn extend<I : IntoIterator <Item = ( $( $Ts, ) * ) >>( & mut self , into_iter: I ) {
529+ let ( $( $var_names, ) * ) = self ;
530+ let iter = into_iter. into_iter( ) ;
531+ $SpecTupleExtendN:: extend( iter, $( $var_names, ) * ) ;
532+ }
533+ ) ;
548534
549535 fn extend_one( & mut self , item: ( $( $Ts, ) * ) ) {
550536 $( self . $cnts. extend_one( item. $cnts) ; ) *
@@ -562,75 +548,78 @@ macro_rules! spec_tuple_impl {
562548 }
563549 }
564550
565- trait $SpecTupleExtendN<$( $Ts) ,* > {
566- fn extend( self , $( $var_names: & mut $Ts, ) * ) ;
567- }
551+ spec_tuple_impl!( #$maybe_special_case
568552
569- fn $default_extend_tuple_n<$( $Ts, ) * $( $ExtendTs, ) * >(
570- iter: impl Iterator <Item = ( $( $Ts, ) * ) >,
571- $( $var_names: & mut $ExtendTs, ) *
572- ) where
573- $( $ExtendTs: Extend <$Ts>, ) *
574- {
575- fn extend<' a, $( $Ts, ) * >(
576- $( $var_names: & ' a mut impl Extend <$Ts>, ) *
577- ) -> impl FnMut ( ( ) , ( $( $Ts, ) * ) ) + ' a {
578- #[ allow( non_snake_case) ]
579- move |( ) , ( $( $ExtendTs, ) * ) | {
580- $( $var_names. extend_one( $ExtendTs) ; ) *
581- }
553+ trait $SpecTupleExtendN<$( $Ts) ,* > {
554+ fn extend( self , $( $var_names: & mut $Ts, ) * ) ;
582555 }
583556
584- let ( lower_bound, _) = iter. size_hint( ) ;
585- if lower_bound > 0 {
586- $( $var_names. extend_reserve( lower_bound) ; ) *
587- }
588-
589- iter. fold( ( ) , extend( $( $var_names, ) * ) ) ;
590- }
591-
592- impl <$( $Ts, ) * $( $ExtendTs, ) * Iter > $SpecTupleExtendN<$( $ExtendTs) ,* > for Iter
593- where
594- $( $ExtendTs: Extend <$Ts>, ) *
595- Iter : Iterator <Item = ( $( $Ts, ) * ) >,
596- {
597- default fn extend( self , $( $var_names: & mut $ExtendTs) ,* ) {
598- $default_extend_tuple_n( self , $( $var_names) ,* ) ;
599- }
600- }
601-
602- impl <$( $Ts, ) * $( $ExtendTs, ) * Iter > $SpecTupleExtendN<$( $ExtendTs) ,* > for Iter
603- where
604- $( $ExtendTs: Extend <$Ts>, ) *
605- Iter : TrustedLen <Item = ( $( $Ts, ) * ) >,
606- {
607- fn extend( self , $( $var_names: & mut $ExtendTs, ) * ) {
557+ fn $default_extend_tuple_n<$( $Ts, ) * $( $ExtendTs, ) * >(
558+ iter: impl Iterator <Item = ( $( $Ts, ) * ) >,
559+ $( $var_names: & mut $ExtendTs, ) *
560+ ) where
561+ $( $ExtendTs: Extend <$Ts>, ) *
562+ {
608563 fn extend<' a, $( $Ts, ) * >(
609564 $( $var_names: & ' a mut impl Extend <$Ts>, ) *
610565 ) -> impl FnMut ( ( ) , ( $( $Ts, ) * ) ) + ' a {
611566 #[ allow( non_snake_case) ]
612- // SAFETY: We reserve enough space for the `size_hint`, and the iterator is
613- // `TrustedLen` so its `size_hint` is exact.
614- move |( ) , ( $( $ExtendTs, ) * ) | unsafe {
615- $( $var_names. extend_one_unchecked( $ExtendTs) ; ) *
567+ move |( ) , ( $( $ExtendTs, ) * ) | {
568+ $( $var_names. extend_one( $ExtendTs) ; ) *
616569 }
617570 }
618571
619- let ( lower_bound, upper_bound) = self . size_hint( ) ;
620-
621- if upper_bound. is_none( ) {
622- // We cannot reserve more than `usize::MAX` items, and this is likely to go out of memory anyway.
623- $default_extend_tuple_n( self , $( $var_names, ) * ) ;
624- return ;
625- }
626-
572+ let ( lower_bound, _) = iter. size_hint( ) ;
627573 if lower_bound > 0 {
628574 $( $var_names. extend_reserve( lower_bound) ; ) *
629575 }
630576
631- self . fold( ( ) , extend( $( $var_names, ) * ) ) ;
577+ iter . fold( ( ) , extend( $( $var_names, ) * ) ) ;
632578 }
633- }
579+
580+ impl <$( $Ts, ) * $( $ExtendTs, ) * Iter > $SpecTupleExtendN<$( $ExtendTs) ,* > for Iter
581+ where
582+ $( $ExtendTs: Extend <$Ts>, ) *
583+ Iter : Iterator <Item = ( $( $Ts, ) * ) >,
584+ {
585+ default fn extend( self , $( $var_names: & mut $ExtendTs) ,* ) {
586+ $default_extend_tuple_n( self , $( $var_names) ,* ) ;
587+ }
588+ }
589+
590+ impl <$( $Ts, ) * $( $ExtendTs, ) * Iter > $SpecTupleExtendN<$( $ExtendTs) ,* > for Iter
591+ where
592+ $( $ExtendTs: Extend <$Ts>, ) *
593+ Iter : TrustedLen <Item = ( $( $Ts, ) * ) >,
594+ {
595+ fn extend( self , $( $var_names: & mut $ExtendTs, ) * ) {
596+ fn extend<' a, $( $Ts, ) * >(
597+ $( $var_names: & ' a mut impl Extend <$Ts>, ) *
598+ ) -> impl FnMut ( ( ) , ( $( $Ts, ) * ) ) + ' a {
599+ #[ allow( non_snake_case) ]
600+ // SAFETY: We reserve enough space for the `size_hint`, and the iterator is
601+ // `TrustedLen` so its `size_hint` is exact.
602+ move |( ) , ( $( $ExtendTs, ) * ) | unsafe {
603+ $( $var_names. extend_one_unchecked( $ExtendTs) ; ) *
604+ }
605+ }
606+
607+ let ( lower_bound, upper_bound) = self . size_hint( ) ;
608+
609+ if upper_bound. is_none( ) {
610+ // We cannot reserve more than `usize::MAX` items, and this is likely to go out of memory anyway.
611+ $default_extend_tuple_n( self , $( $var_names, ) * ) ;
612+ return ;
613+ }
614+
615+ if lower_bound > 0 {
616+ $( $var_names. extend_reserve( lower_bound) ; ) *
617+ }
618+
619+ self . fold( ( ) , extend( $( $var_names, ) * ) ) ;
620+ }
621+ }
622+ ) ;
634623
635624 /// This implementation turns an iterator of tuples into a tuple of types which implement
636625 /// [`Default`] and [`Extend`].
@@ -666,7 +655,46 @@ macro_rules! spec_tuple_impl {
666655 res
667656 }
668657 }
669-
658+ } ;
659+ (
660+ #special_case_1_tuple fn
661+ $( $t: tt) *
662+ ) => {
663+ /// Allows to `extend` a tuple of collections that also implement `Extend`.
664+ ///
665+ /// See also: [`Iterator::unzip`]
666+ ///
667+ /// # Examples
668+ /// ```
669+ /// // Example given for a 2-tuple, but 1- through 12-tuples are supported
670+ /// let mut tuple = (vec![0], vec![1]);
671+ /// tuple.extend([(2, 3), (4, 5), (6, 7)]);
672+ /// assert_eq!(tuple.0, [0, 2, 4, 6]);
673+ /// assert_eq!(tuple.1, [1, 3, 5, 7]);
674+ ///
675+ /// // also allows for arbitrarily nested tuples as elements
676+ /// let mut nested_tuple = (vec![1], (vec![2], vec![3]));
677+ /// nested_tuple.extend([(4, (5, 6)), (7, (8, 9))]);
678+ ///
679+ /// let (a, (b, c)) = nested_tuple;
680+ /// assert_eq!(a, [1, 4, 7]);
681+ /// assert_eq!(b, [2, 5, 8]);
682+ /// assert_eq!(c, [3, 6, 9]);
683+ /// ```
684+ fn extend<I : IntoIterator <Item = ( T , ) >>( & mut self , into_iter: I ) {
685+ self . 0 . extend( into_iter. into_iter( ) . map( |( a, ) | a) ) ;
686+ }
687+ } ;
688+ (
689+ #special_case_1_tuple $( $t: tt) *
690+ ) => {
691+ // no specialization traits
692+ } ;
693+ (
694+ #normal_case
695+ $( $t: tt) *
696+ ) => {
697+ $( $t) *
670698 } ;
671699}
672700
0 commit comments