@@ -9,7 +9,6 @@ mod multi_product;
9
9
pub use self :: multi_product:: * ;
10
10
11
11
use std:: fmt;
12
- use std:: mem:: replace;
13
12
use std:: iter:: { Fuse , Peekable , FromIterator , FusedIterator } ;
14
13
use std:: marker:: PhantomData ;
15
14
use crate :: size_hint;
@@ -606,107 +605,125 @@ impl<I, J, F> Iterator for MergeBy<I, J, F>
606
605
}
607
606
}
608
607
609
- #[ derive( Clone , Debug ) ]
610
- pub struct CoalesceCore < I , T >
608
+ /// An iterator adaptor that may join together adjacent elements.
609
+ ///
610
+ /// See [`.coalesce()`](../trait.Itertools.html#method.coalesce) for more information.
611
+ #[ must_use = "iterator adaptors are lazy and do nothing unless consumed" ]
612
+ pub type Coalesce < I , F > = CoalesceBy < I , F , <I as Iterator >:: Item > ;
613
+
614
+ pub struct CoalesceBy < I , F , T >
611
615
where I : Iterator
612
616
{
613
617
iter : I ,
614
618
last : Option < T > ,
619
+ f : F ,
615
620
}
616
621
617
- impl < I , T > CoalesceCore < I , T >
618
- where I : Iterator
619
- {
620
- fn next_with < F > ( & mut self , mut f : F ) -> Option < T >
621
- where F : FnMut ( T , I :: Item ) -> Result < T , ( T , T ) >
622
- {
623
- // this fuses the iterator
624
- let mut last = match self . last . take ( ) {
625
- None => return None ,
626
- Some ( x) => x,
627
- } ;
628
- for next in & mut self . iter {
629
- match f ( last, next) {
630
- Ok ( joined) => last = joined,
631
- Err ( ( last_, next_) ) => {
632
- self . last = Some ( next_) ;
633
- return Some ( last_) ;
634
- }
635
- }
636
- }
637
-
638
- Some ( last)
639
- }
640
-
641
- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
642
- let ( low, hi) = size_hint:: add_scalar ( self . iter . size_hint ( ) ,
643
- self . last . is_some ( ) as usize ) ;
644
- ( ( low > 0 ) as usize , hi)
645
- }
622
+ pub trait CoalescePredicate < Item , T > {
623
+ fn coalesce_pair ( & mut self , t : T , item : Item ) -> Result < T , ( T , T ) > ;
646
624
}
647
625
648
- /// An iterator adaptor that may join together adjacent elements.
649
- ///
650
- /// See [`.coalesce()`](../trait.Itertools.html#method.coalesce) for more information.
651
- #[ must_use = "iterator adaptors are lazy and do nothing unless consumed" ]
652
- pub struct Coalesce < I , F >
653
- where I : Iterator
626
+ impl < F , Item , T > CoalescePredicate < Item , T > for F
627
+ where F : FnMut ( T , Item ) -> Result < T , ( T , T ) >
654
628
{
655
- iter : CoalesceCore < I , I :: Item > ,
656
- f : F ,
629
+ fn coalesce_pair ( & mut self , t : T , item : Item ) -> Result < T , ( T , T ) > {
630
+ self ( t, item)
631
+ }
657
632
}
658
633
659
- impl < I : Clone , F : Clone > Clone for Coalesce < I , F >
634
+ impl < I : Clone , F : Clone , T : Clone > Clone for CoalesceBy < I , F , T >
660
635
where I : Iterator ,
661
- I :: Item : Clone
662
636
{
663
- clone_fields ! ( iter, f) ;
637
+ clone_fields ! ( last , iter, f) ;
664
638
}
665
639
666
- impl < I , F > fmt:: Debug for Coalesce < I , F >
640
+ impl < I , F , T > fmt:: Debug for CoalesceBy < I , F , T >
667
641
where I : Iterator + fmt:: Debug ,
668
- I :: Item : fmt:: Debug ,
642
+ T : fmt:: Debug ,
669
643
{
670
- debug_fmt_fields ! ( Coalesce , iter) ;
644
+ debug_fmt_fields ! ( CoalesceBy , iter) ;
671
645
}
672
646
673
647
/// Create a new `Coalesce`.
674
648
pub fn coalesce < I , F > ( mut iter : I , f : F ) -> Coalesce < I , F >
675
649
where I : Iterator
676
650
{
677
651
Coalesce {
678
- iter : CoalesceCore {
679
- last : iter. next ( ) ,
680
- iter,
681
- } ,
652
+ last : iter. next ( ) ,
653
+ iter,
682
654
f,
683
655
}
684
656
}
685
657
686
- impl < I , F > Iterator for Coalesce < I , F >
658
+ impl < I , F , T > Iterator for CoalesceBy < I , F , T >
687
659
where I : Iterator ,
688
- F : FnMut ( I :: Item , I :: Item ) -> Result < I :: Item , ( I :: Item , I :: Item ) >
660
+ F : CoalescePredicate < I :: Item , T >
689
661
{
690
- type Item = I :: Item ;
662
+ type Item = T ;
691
663
692
664
fn next ( & mut self ) -> Option < Self :: Item > {
693
- self . iter . next_with ( & mut self . f )
665
+ // this fuses the iterator
666
+ let mut last = match self . last . take ( ) {
667
+ None => return None ,
668
+ Some ( x) => x,
669
+ } ;
670
+ for next in & mut self . iter {
671
+ match self . f . coalesce_pair ( last, next) {
672
+ Ok ( joined) => last = joined,
673
+ Err ( ( last_, next_) ) => {
674
+ self . last = Some ( next_) ;
675
+ return Some ( last_) ;
676
+ }
677
+ }
678
+ }
679
+ Some ( last)
694
680
}
695
681
696
682
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
697
- self . iter . size_hint ( )
683
+ let ( low, hi) = size_hint:: add_scalar ( self . iter . size_hint ( ) ,
684
+ self . last . is_some ( ) as usize ) ;
685
+ ( ( low > 0 ) as usize , hi)
686
+ }
687
+
688
+ fn fold < Acc , FnAcc > ( self , acc : Acc , mut fn_acc : FnAcc ) -> Acc
689
+ where FnAcc : FnMut ( Acc , Self :: Item ) -> Acc ,
690
+ {
691
+ if let Some ( last) = self . last {
692
+ let mut f = self . f ;
693
+ let ( last, acc) = self . iter . fold ( ( last, acc) , |( last, acc) , elt| {
694
+ match f. coalesce_pair ( last, elt) {
695
+ Ok ( joined) => ( joined, acc) ,
696
+ Err ( ( last_, next_) ) => ( next_, fn_acc ( acc, last_) ) ,
697
+ }
698
+ } ) ;
699
+ fn_acc ( acc, last)
700
+ } else {
701
+ acc
702
+ }
698
703
}
699
704
}
700
705
706
+ impl < I : Iterator , F : CoalescePredicate < I :: Item , T > , T > FusedIterator for CoalesceBy < I , F , T > { }
707
+
701
708
/// An iterator adaptor that removes repeated duplicates, determining equality using a comparison function.
702
709
///
703
710
/// See [`.dedup_by()`](../trait.Itertools.html#method.dedup_by) or [`.dedup()`](../trait.Itertools.html#method.dedup) for more information.
704
711
#[ must_use = "iterator adaptors are lazy and do nothing unless consumed" ]
705
- pub struct DedupBy < I , Pred >
706
- where I : Iterator
712
+ pub type DedupBy < I , Pred > = CoalesceBy < I , DedupPred2CoalescePred < Pred > , <I as Iterator >:: Item > ;
713
+
714
+ #[ derive( Clone ) ]
715
+ pub struct DedupPred2CoalescePred < DP > ( DP ) ;
716
+
717
+ impl < DP , T > CoalescePredicate < T , T > for DedupPred2CoalescePred < DP >
718
+ where DP : DedupPredicate < T >
707
719
{
708
- iter : CoalesceCore < I , I :: Item > ,
709
- dedup_pred : Pred ,
720
+ fn coalesce_pair ( & mut self , t : T , item : T ) -> Result < T , ( T , T ) > {
721
+ if self . 0 . dedup_pair ( & t, & item) {
722
+ Ok ( t)
723
+ } else {
724
+ Err ( ( t, item) )
725
+ }
726
+ }
710
727
}
711
728
712
729
pub trait DedupPredicate < T > { // TODO replace by Fn(&T, &T)->bool once Rust supports it
@@ -733,23 +750,14 @@ impl<T, F: FnMut(&T, &T)->bool> DedupPredicate<T> for F {
733
750
/// See [`.dedup()`](../trait.Itertools.html#method.dedup) for more information.
734
751
pub type Dedup < I > =DedupBy < I , DedupEq > ;
735
752
736
- impl < I : Clone , Pred : Clone > Clone for DedupBy < I , Pred >
737
- where I : Iterator ,
738
- I :: Item : Clone ,
739
- {
740
- clone_fields ! ( iter, dedup_pred) ;
741
- }
742
-
743
753
/// Create a new `DedupBy`.
744
754
pub fn dedup_by < I , Pred > ( mut iter : I , dedup_pred : Pred ) -> DedupBy < I , Pred >
745
755
where I : Iterator ,
746
756
{
747
757
DedupBy {
748
- iter : CoalesceCore {
749
- last : iter. next ( ) ,
750
- iter,
751
- } ,
752
- dedup_pred,
758
+ last : iter. next ( ) ,
759
+ iter,
760
+ f : DedupPred2CoalescePred ( dedup_pred) ,
753
761
}
754
762
}
755
763
@@ -760,60 +768,27 @@ pub fn dedup<I>(iter: I) -> Dedup<I>
760
768
dedup_by ( iter, DedupEq )
761
769
}
762
770
763
- impl < I , Pred > fmt:: Debug for DedupBy < I , Pred >
764
- where I : Iterator + fmt:: Debug ,
765
- I :: Item : fmt:: Debug ,
766
- {
767
- debug_fmt_fields ! ( Dedup , iter) ;
768
- }
769
-
770
- impl < I , Pred > Iterator for DedupBy < I , Pred >
771
- where I : Iterator ,
772
- Pred : DedupPredicate < I :: Item > ,
773
- {
774
- type Item = I :: Item ;
775
-
776
- fn next ( & mut self ) -> Option < Self :: Item > {
777
- let ref mut dedup_pred = self . dedup_pred ;
778
- self . iter . next_with ( |x, y| {
779
- if dedup_pred. dedup_pair ( & x, & y) { Ok ( x) } else { Err ( ( x, y) ) }
780
- } )
781
- }
782
-
783
- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
784
- self . iter . size_hint ( )
785
- }
786
-
787
- fn fold < Acc , G > ( self , mut accum : Acc , mut f : G ) -> Acc
788
- where G : FnMut ( Acc , Self :: Item ) -> Acc ,
789
- {
790
- if let Some ( mut last) = self . iter . last {
791
- let mut dedup_pred = self . dedup_pred ;
792
- accum = self . iter . iter . fold ( accum, |acc, elt| {
793
- if dedup_pred. dedup_pair ( & elt, & last) {
794
- acc
795
- } else {
796
- f ( acc, replace ( & mut last, elt) )
797
- }
798
- } ) ;
799
- f ( accum, last)
800
- } else {
801
- accum
802
- }
803
- }
804
- }
805
-
806
771
/// An iterator adaptor that removes repeated duplicates, while keeping a count of how many
807
772
/// repeated elements were present. This will determine equality using a comparison function.
808
773
///
809
774
/// See [`.dedup_by_with_count()`](../trait.Itertools.html#method.dedup_by_with_count) or
810
775
/// [`.dedup_with_count()`](../trait.Itertools.html#method.dedup_with_count) for more information.
811
776
#[ must_use = "iterator adaptors are lazy and do nothing unless consumed" ]
812
- pub struct DedupByWithCount < I , Pred >
813
- where I : Iterator
777
+ pub type DedupByWithCount < I , Pred > = CoalesceBy < I , DedupPredWithCount2CoalescePred < Pred > , ( usize , <I as Iterator >:: Item ) > ;
778
+
779
+ #[ derive( Clone ) ]
780
+ pub struct DedupPredWithCount2CoalescePred < DP > ( DP ) ;
781
+
782
+ impl < DP , T > CoalescePredicate < T , ( usize , T ) > for DedupPredWithCount2CoalescePred < DP >
783
+ where DP : DedupPredicate < T >
814
784
{
815
- iter : CoalesceCore < I , ( usize , I :: Item ) > ,
816
- dedup_pred : Pred ,
785
+ fn coalesce_pair ( & mut self , ( c, t) : ( usize , T ) , item : T ) -> Result < ( usize , T ) , ( ( usize , T ) , ( usize , T ) ) > {
786
+ if self . 0 . dedup_pair ( & t, & item) {
787
+ Ok ( ( c + 1 , t) )
788
+ } else {
789
+ Err ( ( ( c, t) , ( 1 , item) ) )
790
+ }
791
+ }
817
792
}
818
793
819
794
/// An iterator adaptor that removes repeated duplicates, while keeping a count of how many
@@ -827,11 +802,9 @@ pub fn dedup_by_with_count<I, Pred>(mut iter: I, dedup_pred: Pred) -> DedupByWit
827
802
where I : Iterator ,
828
803
{
829
804
DedupByWithCount {
830
- iter : CoalesceCore {
831
- last : iter. next ( ) . map ( |v| ( 1 , v) ) ,
832
- iter,
833
- } ,
834
- dedup_pred,
805
+ last : iter. next ( ) . map ( |v| ( 1 , v) ) ,
806
+ iter,
807
+ f : DedupPredWithCount2CoalescePred ( dedup_pred) ,
835
808
}
836
809
}
837
810
@@ -842,40 +815,6 @@ pub fn dedup_with_count<I>(iter: I) -> DedupWithCount<I>
842
815
dedup_by_with_count ( iter, DedupEq )
843
816
}
844
817
845
- impl < I , Pred > fmt:: Debug for DedupByWithCount < I , Pred >
846
- where I : Iterator + fmt:: Debug ,
847
- I :: Item : fmt:: Debug ,
848
- {
849
- debug_fmt_fields ! ( Dedup , iter) ;
850
- }
851
-
852
- impl < I : Clone , Pred : Clone > Clone for DedupByWithCount < I , Pred >
853
- where I : Iterator ,
854
- I :: Item : Clone ,
855
- {
856
- clone_fields ! ( iter, dedup_pred) ;
857
- }
858
-
859
- impl < I , Pred > Iterator for DedupByWithCount < I , Pred >
860
- where I : Iterator ,
861
- Pred : DedupPredicate < I :: Item > ,
862
- {
863
- type Item = ( usize , I :: Item ) ;
864
-
865
- fn next ( & mut self ) -> Option < ( usize , I :: Item ) > {
866
- let ref mut dedup_pred = self . dedup_pred ;
867
- self . iter . next_with ( |( c, x) , y| {
868
- if dedup_pred. dedup_pair ( & x, & y) { Ok ( ( c + 1 , x) ) } else { Err ( ( ( c, x) , ( 1 , y) ) ) }
869
- } )
870
- }
871
-
872
- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
873
- self . iter . size_hint ( )
874
- }
875
- }
876
-
877
- impl < I : Iterator , Pred : DedupPredicate < I :: Item > > FusedIterator for DedupByWithCount < I , Pred > { }
878
-
879
818
/// An iterator adaptor that borrows from a `Clone`-able iterator
880
819
/// to only pick off elements while the predicate returns `true`.
881
820
///
0 commit comments