2
2
3
3
use crate :: iter:: { InPlaceIterable , SourceIter } ;
4
4
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.
9
7
///
10
- /// This `struct` is created by [`Iterator::dedup_by_key `].
8
+ /// This `struct` is created by [`Iterator::dedup `].
11
9
/// See its documentation for more.
12
10
///
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 > > ,
17
19
}
18
20
19
- impl < F > ByKey < F > {
21
+ impl < I > Dedup < I >
22
+ where
23
+ I : Iterator ,
24
+ {
20
25
#[ 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 }
23
28
}
24
29
}
25
30
26
- impl < F , T , K > FnOnce < ( & T , & T ) > for ByKey < F >
31
+ impl < I > Iterator for Dedup < I >
27
32
where
28
- F : FnMut ( & T ) -> K ,
29
- K : PartialEq ,
33
+ I : Iterator ,
34
+ I :: Item : PartialEq ,
30
35
{
31
- type Output = bool ;
36
+ type Item = I :: Item ;
37
+
32
38
#[ 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)
35
52
}
36
53
}
37
54
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 >
39
57
where
40
- F : FnMut ( & T ) -> K ,
41
- K : PartialEq ,
58
+ I : SourceIter + Iterator ,
42
59
{
60
+ type Source = I :: Source ;
61
+
43
62
#[ 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 ) }
46
66
}
47
67
}
48
68
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.
53
80
///
54
- /// This `struct` is created by [`Iterator::dedup `].
81
+ /// This `struct` is created by [`Iterator::dedup_by `].
55
82
/// See its documentation for more.
56
83
///
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
+ }
61
94
62
- impl ByPartialEq {
95
+ impl < I , F > DedupBy < I , F >
96
+ where
97
+ I : Iterator ,
98
+ {
63
99
#[ 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 }
66
102
}
67
103
}
68
104
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
+
71
121
#[ 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)
74
126
}
75
127
}
76
128
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
+
78
136
#[ 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 ) }
81
140
}
82
141
}
83
142
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
+
84
151
/// 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 .
86
153
///
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.
89
156
///
90
- /// [`Iterator::dedup`]: Iterator::dedup
91
- /// [`Iterator::dedup_by`]: Iterator::dedup_by
92
157
/// [`Iterator::dedup_by_key`]: Iterator::dedup_by_key
93
158
#[ derive( Debug , Clone ) ]
94
- pub struct Dedup < I , F >
159
+ pub struct DedupByKey < I , F , K >
95
160
where
96
161
I : Iterator ,
162
+ F : FnMut ( & I :: Item ) -> K ,
97
163
{
98
164
inner : I ,
99
- same_bucket : F ,
165
+ key : F ,
100
166
last : Option < Option < I :: Item > > ,
101
167
}
102
168
103
- impl < I , F > Dedup < I , F >
169
+ impl < I , F , K > DedupByKey < I , F , K >
104
170
where
105
171
I : Iterator ,
172
+ F : FnMut ( & I :: Item ) -> K ,
106
173
{
107
174
#[ 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 }
110
177
}
111
178
}
112
179
113
- impl < I , F > Iterator for Dedup < I , F >
180
+ impl < I , F , K > Iterator for DedupByKey < I , F , K >
114
181
where
115
182
I : Iterator ,
116
- F : FnMut ( & I :: Item , & I :: Item ) -> bool ,
183
+ F : FnMut ( & I :: Item ) -> K ,
184
+ K : PartialEq ,
117
185
{
118
186
type Item = I :: Item ;
119
187
120
188
#[ inline]
121
189
fn next ( & mut self ) -> Option < Self :: Item > {
122
- let Self { inner, last, same_bucket } = self ;
190
+ let Self { inner, last, key } = self ;
123
191
let last = last. get_or_insert_with ( || inner. next ( ) ) ;
124
192
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) ) ;
126
194
crate :: mem:: replace ( last, next)
127
195
}
128
196
@@ -135,9 +203,10 @@ where
135
203
}
136
204
137
205
#[ 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 >
139
207
where
140
208
I : SourceIter + Iterator ,
209
+ F : FnMut ( & I :: Item ) -> K ,
141
210
{
142
211
type Source = I :: Source ;
143
212
@@ -149,9 +218,10 @@ where
149
218
}
150
219
151
220
#[ 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 >
153
222
where
154
223
I : InPlaceIterable ,
155
- F : FnMut ( & I :: Item , & I :: Item ) -> bool ,
224
+ F : FnMut ( & I :: Item ) -> K ,
225
+ K : PartialEq ,
156
226
{
157
227
}
0 commit comments