1
- use crate :: mem:: swap;
1
+ use crate :: {
2
+ iter:: { InPlaceIterable , SourceIter } ,
3
+ mem:: swap,
4
+ } ;
2
5
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.
5
7
///
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`].
7
12
/// See its documentation for more.
8
13
///
9
- /// [`Iterator::dedup `]: Iterator::dedup
14
+ /// [`Iterator::dedup_by_key `]: Iterator::dedup_by_key
10
15
#[ unstable( feature = "iter_dedup" , reason = "recently added" , issue = "83748" ) ]
11
16
#[ 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
+ }
15
25
}
16
26
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 >
18
29
where
19
- I : Iterator < Item = T > ,
30
+ F : FnMut ( & T ) -> K ,
31
+ K : PartialEq ,
20
32
{
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 )
24
37
}
25
38
}
26
39
27
40
#[ 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 >
29
42
where
30
- I : Iterator < Item = T > ,
31
- T : PartialEq ,
43
+ F : FnMut ( & T ) -> K ,
44
+ K : PartialEq ,
32
45
{
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
+ }
34
50
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 ;
47
63
48
- swap ( & mut self . last , & mut next) ;
49
- next
64
+ impl ByPartialEq {
65
+ pub ( crate ) fn new ( ) -> Self {
66
+ Self
50
67
}
68
+ }
51
69
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
65
83
}
66
84
}
67
85
68
86
/// An iterator that removes all but the first of consecutive elements in a
69
87
/// given iterator satisfying a given equality relation.
70
88
///
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.
73
91
///
92
+ /// [`Iterator::dedup`]: Iterator::dedup
74
93
/// [`Iterator::dedup_by`]: Iterator::dedup_by
94
+ /// [`Iterator::dedup_by_key`]: Iterator::dedup_by_key
75
95
#[ unstable( feature = "iter_dedup" , reason = "recently added" , issue = "83748" ) ]
76
96
#[ derive( Debug , Clone , Copy ) ]
77
- pub struct DedupBy < I , F , T > {
97
+ pub struct Dedup < I , F , T > {
78
98
inner : I ,
79
99
same_bucket : F ,
80
100
last : Option < T > ,
81
101
}
82
102
83
- impl < I , F , T > DedupBy < I , F , T >
103
+ impl < I , F , T > Dedup < I , F , T >
84
104
where
85
105
I : Iterator < Item = T > ,
86
106
{
87
107
pub ( crate ) fn new ( inner : I , same_bucket : F ) -> Self {
88
108
let mut inner = inner;
89
- Self { last : inner. next ( ) , inner, same_bucket }
109
+ Self {
110
+ last : inner. next ( ) ,
111
+ inner,
112
+ same_bucket,
113
+ }
90
114
}
91
115
}
92
116
93
117
#[ 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 >
95
119
where
96
120
I : Iterator < Item = T > ,
97
121
F : FnMut ( & T , & T ) -> bool ,
@@ -116,84 +140,30 @@ where
116
140
}
117
141
118
142
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)
131
146
}
132
147
}
133
148
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
141
149
#[ 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 >
150
151
where
151
- I : Iterator < Item = T > ,
152
+ S : Iterator ,
153
+ I : Iterator + SourceIter < Source = S > ,
152
154
{
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 ) }
156
160
}
157
161
}
158
162
159
163
#[ 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 >
161
165
where
162
- I : Iterator < Item = T > ,
163
- F : FnMut ( & T ) -> K ,
164
- K : PartialEq ,
166
+ I : InPlaceIterable < Item = T > ,
167
+ F : FnMut ( & T , & T ) -> bool ,
165
168
{
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
- }
199
169
}
0 commit comments