1- use crate :: mem:: swap;
1+ use crate :: {
2+ iter:: { InPlaceIterable , SourceIter } ,
3+ mem:: swap,
4+ } ;
25
3- /// An iterator that removes all but the first of consecutive elements in a
4- /// given iterator according to the [`PartialEq`] trait implementation.
6+ /// A wrapper type around a key function.
57///
6- /// This `struct` is created by [`Iterator::dedup`].
8+ /// This struct acts like a function which given a key function returns true
9+ /// if and only if both arguments evaluate to the same key.
10+ ///
11+ /// This `struct` is created by [`Iterator::dedup_by_key`].
712/// See its documentation for more.
813///
9- /// [`Iterator::dedup `]: Iterator::dedup
14+ /// [`Iterator::dedup_by_key `]: Iterator::dedup_by_key
1015#[ unstable( feature = "iter_dedup" , reason = "recently added" , issue = "83748" ) ]
1116#[ derive( Debug , Clone , Copy ) ]
12- pub struct Dedup < I , T > {
13- inner : I ,
14- last : Option < T > ,
17+ pub struct ByKey < F > {
18+ key : F ,
19+ }
20+
21+ impl < F > ByKey < F > {
22+ pub ( crate ) fn new ( key : F ) -> Self {
23+ Self { key }
24+ }
1525}
1626
17- impl < I , T > Dedup < I , T >
27+ #[ unstable( feature = "iter_dedup" , reason = "recently added" , issue = "83748" ) ]
28+ impl < F , T , K > FnOnce < ( & T , & T ) > for ByKey < F >
1829where
19- I : Iterator < Item = T > ,
30+ F : FnMut ( & T ) -> K ,
31+ K : PartialEq ,
2032{
21- pub ( crate ) fn new ( inner : I ) -> Self {
22- let mut inner = inner;
23- Self { last : inner. next ( ) , inner }
33+ type Output = bool ;
34+
35+ extern "rust-call" fn call_once ( mut self , args : ( & T , & T ) ) -> Self :: Output {
36+ ( self . key ) ( args. 0 ) == ( self . key ) ( args. 1 )
2437 }
2538}
2639
2740#[ unstable( feature = "iter_dedup" , reason = "recently added" , issue = "83748" ) ]
28- impl < I , T > Iterator for Dedup < I , T >
41+ impl < F , T , K > FnMut < ( & T , & T ) > for ByKey < F >
2942where
30- I : Iterator < Item = T > ,
31- T : PartialEq ,
43+ F : FnMut ( & T ) -> K ,
44+ K : PartialEq ,
3245{
33- type Item = T ;
46+ extern "rust-call" fn call_mut ( & mut self , args : ( & T , & T ) ) -> Self :: Output {
47+ ( self . key ) ( args. 0 ) == ( self . key ) ( args. 1 )
48+ }
49+ }
3450
35- fn next ( & mut self ) -> Option < Self :: Item > {
36- let last_item = self . last . as_ref ( ) ? ;
37- let mut next = loop {
38- let curr = self . inner . next ( ) ;
39- if let Some ( curr_item ) = & curr {
40- if last_item != curr_item {
41- break curr ;
42- }
43- } else {
44- break None ;
45- }
46- } ;
51+ /// A zero-sized type for checking partial equality.
52+ ///
53+ /// This struct acts exactly like the function [`PartialEq::eq`], but its
54+ /// type is always known during compile time.
55+ ///
56+ /// This `struct` is created by [`Iterator::dedup`].
57+ /// See its documentation for more.
58+ ///
59+ /// [`Iterator::dedup`]: Iterator::dedup
60+ # [ unstable ( feature = "iter_dedup" , reason = "recently added" , issue = "83748" ) ]
61+ # [ derive ( Debug , Clone , Copy ) ]
62+ pub struct ByPartialEq ;
4763
48- swap ( & mut self . last , & mut next) ;
49- next
64+ impl ByPartialEq {
65+ pub ( crate ) fn new ( ) -> Self {
66+ Self
5067 }
68+ }
5169
52- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
53- if self . last . is_some ( ) {
54- // If we have a last item stored, the iterator can yield at most
55- // as many items at the inner iterator plus the stored one. Yet we
56- // can only guarantee that the iterator yields at least one more item
57- // since all other items in the inner iterator might be duplicates.
58- let ( _ , max ) = self . inner . size_hint ( ) ;
59- ( 1 , max . and_then ( |k| k . checked_add ( 1 ) ) )
60- } else {
61- // If the last item we got from the inner iterator is `None`,
62- // the iterator is empty.
63- ( 0 , Some ( 0 ) )
64- }
70+ # [ unstable ( feature = "iter_dedup" , reason = "recently added" , issue = "83748" ) ]
71+ impl < T : PartialEq > FnOnce < ( & T , & T ) > for ByPartialEq {
72+ type Output = bool ;
73+
74+ extern "rust-call" fn call_once ( self , args : ( & T , & T ) ) -> Self :: Output {
75+ args . 0 == args . 1
76+ }
77+ }
78+
79+ # [ unstable ( feature = "iter_dedup" , reason = "recently added" , issue = "83748" ) ]
80+ impl < T : PartialEq > FnMut < ( & T , & T ) > for ByPartialEq {
81+ extern "rust-call" fn call_mut ( & mut self , args : ( & T , & T ) ) -> Self :: Output {
82+ args . 0 == args . 1
6583 }
6684}
6785
6886/// An iterator that removes all but the first of consecutive elements in a
6987/// given iterator satisfying a given equality relation.
7088///
71- /// This `struct` is created by [`Iterator::dedup_by`].
72- /// See its documentation for more.
89+ /// This `struct` is created by [`Iterator::dedup`], [`Iterator:: dedup_by`]
90+ /// and [`Iterator::dedup_by_key`]. See its documentation for more.
7391///
92+ /// [`Iterator::dedup`]: Iterator::dedup
7493/// [`Iterator::dedup_by`]: Iterator::dedup_by
94+ /// [`Iterator::dedup_by_key`]: Iterator::dedup_by_key
7595#[ unstable( feature = "iter_dedup" , reason = "recently added" , issue = "83748" ) ]
7696#[ derive( Debug , Clone , Copy ) ]
77- pub struct DedupBy < I , F , T > {
97+ pub struct Dedup < I , F , T > {
7898 inner : I ,
7999 same_bucket : F ,
80100 last : Option < T > ,
81101}
82102
83- impl < I , F , T > DedupBy < I , F , T >
103+ impl < I , F , T > Dedup < I , F , T >
84104where
85105 I : Iterator < Item = T > ,
86106{
87107 pub ( crate ) fn new ( inner : I , same_bucket : F ) -> Self {
88108 let mut inner = inner;
89- Self { last : inner. next ( ) , inner, same_bucket }
109+ Self {
110+ last : inner. next ( ) ,
111+ inner,
112+ same_bucket,
113+ }
90114 }
91115}
92116
93117#[ unstable( feature = "iter_dedup" , reason = "recently added" , issue = "83748" ) ]
94- impl < I , F , T > Iterator for DedupBy < I , F , T >
118+ impl < I , F , T > Iterator for Dedup < I , F , T >
95119where
96120 I : Iterator < Item = T > ,
97121 F : FnMut ( & T , & T ) -> bool ,
@@ -116,84 +140,30 @@ where
116140 }
117141
118142 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
119- if self . last . is_some ( ) {
120- // If we have a last item stored, the iterator can yield at most
121- // as many items at the inner iterator plus the stored one. Yet we
122- // can only guarantee that the iterator yields at least one more item
123- // since all other items in the inner iterator might be duplicates.
124- let ( _, max) = self . inner . size_hint ( ) ;
125- ( 1 , max. and_then ( |k| k. checked_add ( 1 ) ) )
126- } else {
127- // If the last item we got from the inner iterator is `None`,
128- // the iterator is empty.
129- ( 0 , Some ( 0 ) )
130- }
143+ let min = self . last . as_ref ( ) . map ( |_| 1 ) . unwrap_or ( 0 ) ;
144+ let max = self . inner . size_hint ( ) . 1 ;
145+ ( min, max)
131146 }
132147}
133148
134- /// An iterator that removes all but the first of consecutive elements in a
135- /// given iterator that resolve to the same key.
136- ///
137- /// This `struct` is created by [`Iterator::dedup_by_key`].
138- /// See its documentation for more.
139- ///
140- /// [`Iterator::dedup_by_key`]: Iterator::dedup_by_key
141149#[ unstable( feature = "iter_dedup" , reason = "recently added" , issue = "83748" ) ]
142- #[ derive( Debug , Clone , Copy ) ]
143- pub struct DedupByKey < I , F , T > {
144- inner : I ,
145- key : F ,
146- last : Option < T > ,
147- }
148-
149- impl < I , F , T > DedupByKey < I , F , T >
150+ unsafe impl < S , I , F , T > SourceIter for Dedup < I , F , T >
150151where
151- I : Iterator < Item = T > ,
152+ S : Iterator ,
153+ I : Iterator + SourceIter < Source = S > ,
152154{
153- pub ( crate ) fn new ( inner : I , key : F ) -> Self {
154- let mut inner = inner;
155- Self { last : inner. next ( ) , inner, key }
155+ type Source = S ;
156+
157+ unsafe fn as_inner ( & mut self ) -> & mut Self :: Source {
158+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
159+ unsafe { SourceIter :: as_inner ( & mut self . inner ) }
156160 }
157161}
158162
159163#[ unstable( feature = "iter_dedup" , reason = "recently added" , issue = "83748" ) ]
160- impl < I , F , K , T > Iterator for DedupByKey < I , F , T >
164+ unsafe impl < I , F , T > InPlaceIterable for Dedup < I , F , T >
161165where
162- I : Iterator < Item = T > ,
163- F : FnMut ( & T ) -> K ,
164- K : PartialEq ,
166+ I : InPlaceIterable < Item = T > ,
167+ F : FnMut ( & T , & T ) -> bool ,
165168{
166- type Item = T ;
167-
168- fn next ( & mut self ) -> Option < Self :: Item > {
169- let last_item = self . last . as_ref ( ) ?;
170- let mut next = loop {
171- let curr = self . inner . next ( ) ;
172- if let Some ( curr_item) = & curr {
173- if ( self . key ) ( last_item) != ( self . key ) ( curr_item) {
174- break curr;
175- }
176- } else {
177- break None ;
178- }
179- } ;
180-
181- swap ( & mut self . last , & mut next) ;
182- next
183- }
184-
185- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
186- if self . last . is_some ( ) {
187- // If we have a last item stored, the iterator can yield at most
188- // as many items at the inner iterator plus the stored one. Yet we
189- // can only guarantee that the iterator yields at least one more item
190- // since all other items in the inner iterator might be duplicates.
191- let ( _, max) = self . inner . size_hint ( ) ;
192- ( 1 , max. and_then ( |k| k. checked_add ( 1 ) ) )
193- } else {
194- // If the last item we got from the inner iterator is `None`,
195- // the iterator is empty.
196- ( 0 , Some ( 0 ) )
197- }
198- }
199169}
0 commit comments