22
33use crate :: iter:: { InPlaceIterable , SourceIter } ;
44
5- /// A wrapper type around a key function.
6- ///
7- /// This struct acts like a function which given a key function returns true
8- /// if and only if both arguments evaluate to the same key.
5+ /// An iterator that removes all but the first of consecutive elements in a
6+ /// given iterator according to the [`PartialEq`] trait implementation.
97///
10- /// This `struct` is created by [`Iterator::dedup_by_key `].
8+ /// This `struct` is created by [`Iterator::dedup `].
119/// See its documentation for more.
1210///
13- /// [`Iterator::dedup_by_key`]: Iterator::dedup_by_key
14- #[ derive( Debug , Clone , Copy ) ]
15- pub struct ByKey < F > {
16- key : F ,
11+ /// [`Iterator::dedup`]: Iterator::dedup
12+ #[ derive( Debug , Clone ) ]
13+ pub struct Dedup < I >
14+ where
15+ I : Iterator ,
16+ {
17+ inner : I ,
18+ last : Option < Option < I :: Item > > ,
1719}
1820
19- impl < F > ByKey < F > {
21+ impl < I > Dedup < I >
22+ where
23+ I : Iterator ,
24+ {
2025 #[ inline]
21- pub ( crate ) fn new ( key : F ) -> Self {
22- Self { key }
26+ pub ( crate ) fn new ( inner : I ) -> Self {
27+ Self { inner , last : None }
2328 }
2429}
2530
26- impl < F , T , K > FnOnce < ( & T , & T ) > for ByKey < F >
31+ impl < I > Iterator for Dedup < I >
2732where
28- F : FnMut ( & T ) -> K ,
29- K : PartialEq ,
33+ I : Iterator ,
34+ I :: Item : PartialEq ,
3035{
31- type Output = bool ;
36+ type Item = I :: Item ;
37+
3238 #[ inline]
33- extern "rust-call" fn call_once ( mut self , args : ( & T , & T ) ) -> Self :: Output {
34- ( self . key ) ( args. 0 ) == ( self . key ) ( args. 1 )
39+ fn next ( & mut self ) -> Option < Self :: Item > {
40+ let Self { inner, last } = self ;
41+ let last = last. get_or_insert_with ( || inner. next ( ) ) ;
42+ let last_item = last. as_ref ( ) ?;
43+ let next = inner. find ( |next_item| next_item != last_item) ;
44+ crate :: mem:: replace ( last, next)
45+ }
46+
47+ #[ inline]
48+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
49+ let min = matches ! ( self . last, Some ( Some ( _) ) ) . into ( ) ;
50+ let max = self . inner . size_hint ( ) . 1 . map ( |max| max + min) ;
51+ ( min, max)
3552 }
3653}
3754
38- impl < F , T , K > FnMut < ( & T , & T ) > for ByKey < F >
55+ #[ unstable( issue = "none" , feature = "inplace_iteration" ) ]
56+ unsafe impl < I > SourceIter for Dedup < I >
3957where
40- F : FnMut ( & T ) -> K ,
41- K : PartialEq ,
58+ I : SourceIter + Iterator ,
4259{
60+ type Source = I :: Source ;
61+
4362 #[ inline]
44- extern "rust-call" fn call_mut ( & mut self , args : ( & T , & T ) ) -> Self :: Output {
45- ( self . key ) ( args. 0 ) == ( self . key ) ( args. 1 )
63+ unsafe fn as_inner ( & mut self ) -> & mut I :: Source {
64+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
65+ unsafe { SourceIter :: as_inner ( & mut self . inner ) }
4666 }
4767}
4868
49- /// A zero-sized type for checking partial equality.
50- ///
51- /// This struct acts exactly like the function [`PartialEq::eq`], but its
52- /// type is always known during compile time.
69+ #[ unstable( issue = "none" , feature = "inplace_iteration" ) ]
70+ unsafe impl < I > InPlaceIterable for Dedup < I >
71+ where
72+ I : Iterator ,
73+ I : InPlaceIterable ,
74+ I :: Item : PartialEq ,
75+ {
76+ }
77+
78+ /// An iterator that removes all but the first of consecutive elements in a
79+ /// given iterator satisfying a given equality relation.
5380///
54- /// This `struct` is created by [`Iterator::dedup `].
81+ /// This `struct` is created by [`Iterator::dedup_by `].
5582/// See its documentation for more.
5683///
57- /// [`Iterator::dedup`]: Iterator::dedup
58- #[ derive( Debug , Clone , Copy ) ]
59- #[ non_exhaustive]
60- pub struct ByPartialEq ;
84+ /// [`Iterator::dedup_by`]: Iterator::dedup_by
85+ #[ derive( Debug , Clone ) ]
86+ pub struct DedupBy < I , F >
87+ where
88+ I : Iterator ,
89+ {
90+ inner : I ,
91+ same_bucket : F ,
92+ last : Option < Option < I :: Item > > ,
93+ }
6194
62- impl ByPartialEq {
95+ impl < I , F > DedupBy < I , F >
96+ where
97+ I : Iterator ,
98+ {
6399 #[ inline]
64- pub ( crate ) fn new ( ) -> Self {
65- Self
100+ pub ( crate ) fn new ( inner : I , same_bucket : F ) -> Self {
101+ Self { inner , same_bucket , last : None }
66102 }
67103}
68104
69- impl < T : PartialEq > FnOnce < ( & T , & T ) > for ByPartialEq {
70- type Output = bool ;
105+ impl < I , F > Iterator for DedupBy < I , F >
106+ where
107+ I : Iterator ,
108+ F : FnMut ( & I :: Item , & I :: Item ) -> bool ,
109+ {
110+ type Item = I :: Item ;
111+
112+ #[ inline]
113+ fn next ( & mut self ) -> Option < Self :: Item > {
114+ let Self { inner, last, same_bucket } = self ;
115+ let last = last. get_or_insert_with ( || inner. next ( ) ) ;
116+ let last_item = last. as_ref ( ) ?;
117+ let next = inner. find ( |next_item| !( same_bucket) ( next_item, last_item) ) ;
118+ crate :: mem:: replace ( last, next)
119+ }
120+
71121 #[ inline]
72- extern "rust-call" fn call_once ( self , args : ( & T , & T ) ) -> Self :: Output {
73- args. 0 == args. 1
122+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
123+ let min = matches ! ( self . last, Some ( Some ( _) ) ) . into ( ) ;
124+ let max = self . inner . size_hint ( ) . 1 . map ( |max| max + min) ;
125+ ( min, max)
74126 }
75127}
76128
77- impl < T : PartialEq > FnMut < ( & T , & T ) > for ByPartialEq {
129+ #[ unstable( issue = "none" , feature = "inplace_iteration" ) ]
130+ unsafe impl < I , F > SourceIter for DedupBy < I , F >
131+ where
132+ I : SourceIter + Iterator ,
133+ {
134+ type Source = I :: Source ;
135+
78136 #[ inline]
79- extern "rust-call" fn call_mut ( & mut self , args : ( & T , & T ) ) -> Self :: Output {
80- args. 0 == args. 1
137+ unsafe fn as_inner ( & mut self ) -> & mut I :: Source {
138+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
139+ unsafe { SourceIter :: as_inner ( & mut self . inner ) }
81140 }
82141}
83142
143+ #[ unstable( issue = "none" , feature = "inplace_iteration" ) ]
144+ unsafe impl < I , F > InPlaceIterable for DedupBy < I , F >
145+ where
146+ I : InPlaceIterable ,
147+ F : FnMut ( & I :: Item , & I :: Item ) -> bool ,
148+ {
149+ }
150+
84151/// An iterator that removes all but the first of consecutive elements in a
85- /// given iterator satisfying a given equality relation .
152+ /// given iterator that resolve to the same key .
86153///
87- /// This `struct` is created by [`Iterator::dedup`], [`Iterator::dedup_by`]
88- /// and [`Iterator::dedup_by_key`]. See its documentation for more.
154+ /// This `struct` is created by [`Iterator::dedup_by_key`].
155+ /// See its documentation for more.
89156///
90- /// [`Iterator::dedup`]: Iterator::dedup
91- /// [`Iterator::dedup_by`]: Iterator::dedup_by
92157/// [`Iterator::dedup_by_key`]: Iterator::dedup_by_key
93158#[ derive( Debug , Clone ) ]
94- pub struct Dedup < I , F >
159+ pub struct DedupByKey < I , F , K >
95160where
96161 I : Iterator ,
162+ F : FnMut ( & I :: Item ) -> K ,
97163{
98164 inner : I ,
99- same_bucket : F ,
165+ key : F ,
100166 last : Option < Option < I :: Item > > ,
101167}
102168
103- impl < I , F > Dedup < I , F >
169+ impl < I , F , K > DedupByKey < I , F , K >
104170where
105171 I : Iterator ,
172+ F : FnMut ( & I :: Item ) -> K ,
106173{
107174 #[ inline]
108- pub ( crate ) fn new ( inner : I , same_bucket : F ) -> Self {
109- Self { inner, same_bucket , last : None }
175+ pub ( crate ) fn new ( inner : I , key : F ) -> Self {
176+ Self { inner, key , last : None }
110177 }
111178}
112179
113- impl < I , F > Iterator for Dedup < I , F >
180+ impl < I , F , K > Iterator for DedupByKey < I , F , K >
114181where
115182 I : Iterator ,
116- F : FnMut ( & I :: Item , & I :: Item ) -> bool ,
183+ F : FnMut ( & I :: Item ) -> K ,
184+ K : PartialEq ,
117185{
118186 type Item = I :: Item ;
119187
120188 #[ inline]
121189 fn next ( & mut self ) -> Option < Self :: Item > {
122- let Self { inner, last, same_bucket } = self ;
190+ let Self { inner, last, key } = self ;
123191 let last = last. get_or_insert_with ( || inner. next ( ) ) ;
124192 let last_item = last. as_ref ( ) ?;
125- let next = inner. find ( |next_item| ! ( same_bucket ) ( next_item, last_item) ) ;
193+ let next = inner. find ( |next_item| key ( next_item) != key ( last_item) ) ;
126194 crate :: mem:: replace ( last, next)
127195 }
128196
@@ -135,9 +203,10 @@ where
135203}
136204
137205#[ unstable( issue = "none" , feature = "inplace_iteration" ) ]
138- unsafe impl < I , F > SourceIter for Dedup < I , F >
206+ unsafe impl < I , F , K > SourceIter for DedupByKey < I , F , K >
139207where
140208 I : SourceIter + Iterator ,
209+ F : FnMut ( & I :: Item ) -> K ,
141210{
142211 type Source = I :: Source ;
143212
@@ -149,9 +218,10 @@ where
149218}
150219
151220#[ unstable( issue = "none" , feature = "inplace_iteration" ) ]
152- unsafe impl < I , F > InPlaceIterable for Dedup < I , F >
221+ unsafe impl < I , F , K > InPlaceIterable for DedupByKey < I , F , K >
153222where
154223 I : InPlaceIterable ,
155- F : FnMut ( & I :: Item , & I :: Item ) -> bool ,
224+ F : FnMut ( & I :: Item ) -> K ,
225+ K : PartialEq ,
156226{
157227}
0 commit comments