@@ -112,17 +112,25 @@ fn sift_down<T, S>(heap: &mut [T], index: usize, mut less_than: S)
112
112
///
113
113
/// See [`.kmerge()`](../trait.Itertools.html#method.kmerge) for more information.
114
114
#[ must_use = "iterator adaptors are lazy and do nothing unless consumed" ]
115
- pub struct KMerge < I >
116
- where I : Iterator
117
- {
118
- heap : Vec < HeadTail < I > > ,
115
+ pub type KMerge < I > = KMergeBy < I , KMergeByLt > ;
116
+
117
+ pub trait KMergePredicate < T > {
118
+ fn kmerge_pred ( & mut self , a : & T , b : & T ) -> bool ;
119
119
}
120
120
121
- impl < I > fmt:: Debug for KMerge < I >
122
- where I : Iterator + fmt:: Debug ,
123
- I :: Item : fmt:: Debug ,
124
- {
125
- debug_fmt_fields ! ( KMerge , heap) ;
121
+ #[ derive( Clone ) ]
122
+ pub struct KMergeByLt ;
123
+
124
+ impl < T : PartialOrd > KMergePredicate < T > for KMergeByLt {
125
+ fn kmerge_pred ( & mut self , a : & T , b : & T ) -> bool {
126
+ a < b
127
+ }
128
+ }
129
+
130
+ impl < T , F : FnMut ( & T , & T ) ->bool > KMergePredicate < T > for F {
131
+ fn kmerge_pred ( & mut self , a : & T , b : & T ) -> bool {
132
+ self ( a, b)
133
+ }
126
134
}
127
135
128
136
/// Create an iterator that merges elements of the contained iterators using
@@ -142,48 +150,7 @@ pub fn kmerge<I>(iterable: I) -> KMerge<<I::Item as IntoIterator>::IntoIter>
142
150
I :: Item : IntoIterator ,
143
151
<<I as IntoIterator >:: Item as IntoIterator >:: Item : PartialOrd
144
152
{
145
- let iter = iterable. into_iter ( ) ;
146
- let ( lower, _) = iter. size_hint ( ) ;
147
- let mut heap = Vec :: with_capacity ( lower) ;
148
- heap. extend ( iter. filter_map ( |it| HeadTail :: new ( it. into_iter ( ) ) ) ) ;
149
- heapify ( & mut heap, |a, b| a. head < b. head ) ;
150
- KMerge { heap : heap }
151
- }
152
-
153
- impl < I > Clone for KMerge < I >
154
- where I : Iterator + Clone ,
155
- I :: Item : Clone
156
- {
157
- fn clone ( & self ) -> KMerge < I > {
158
- clone_fields ! ( KMerge , self , heap)
159
- }
160
- }
161
-
162
- impl < I > Iterator for KMerge < I >
163
- where I : Iterator ,
164
- I :: Item : PartialOrd
165
- {
166
- type Item = I :: Item ;
167
-
168
- fn next ( & mut self ) -> Option < Self :: Item > {
169
- if self . heap . is_empty ( ) {
170
- return None ;
171
- }
172
- let result = if let Some ( next) = self . heap [ 0 ] . next ( ) {
173
- next
174
- } else {
175
- self . heap . swap_remove ( 0 ) . head
176
- } ;
177
- sift_down ( & mut self . heap , 0 , |a, b| a. head < b. head ) ;
178
- Some ( result)
179
- }
180
-
181
- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
182
- self . heap . iter ( )
183
- . map ( |i| i. size_hint ( ) )
184
- . fold1 ( size_hint:: add)
185
- . unwrap_or ( ( 0 , Some ( 0 ) ) )
186
- }
153
+ kmerge_by ( iterable, KMergeByLt )
187
154
}
188
155
189
156
/// An iterator adaptor that merges an abitrary number of base iterators
@@ -215,21 +182,29 @@ pub fn kmerge_by<I, F>(iterable: I, mut less_than: F)
215
182
-> KMergeBy < <I :: Item as IntoIterator >:: IntoIter , F >
216
183
where I : IntoIterator ,
217
184
I :: Item : IntoIterator ,
218
- F : FnMut ( & <<I as IntoIterator >:: Item as IntoIterator >:: Item ,
219
- & <<I as IntoIterator >:: Item as IntoIterator >:: Item ) -> bool
185
+ F : KMergePredicate < <<I as IntoIterator >:: Item as IntoIterator >:: Item > ,
220
186
{
221
187
let iter = iterable. into_iter ( ) ;
222
188
let ( lower, _) = iter. size_hint ( ) ;
223
189
let mut heap: Vec < _ > = Vec :: with_capacity ( lower) ;
224
190
heap. extend ( iter. filter_map ( |it| HeadTail :: new ( it. into_iter ( ) ) ) ) ;
225
- heapify ( & mut heap, |a, b| less_than ( & a. head , & b. head ) ) ;
191
+ heapify ( & mut heap, |a, b| less_than. kmerge_pred ( & a. head , & b. head ) ) ;
226
192
KMergeBy { heap : heap, less_than : less_than }
227
193
}
228
194
195
+ impl < I , F > Clone for KMergeBy < I , F >
196
+ where I : Iterator + Clone ,
197
+ I :: Item : Clone ,
198
+ F : Clone ,
199
+ {
200
+ fn clone ( & self ) -> KMergeBy < I , F > {
201
+ clone_fields ! ( KMergeBy , self , heap, less_than)
202
+ }
203
+ }
229
204
230
205
impl < I , F > Iterator for KMergeBy < I , F >
231
206
where I : Iterator ,
232
- F : FnMut ( & I :: Item , & I :: Item ) -> bool
207
+ F : KMergePredicate < I :: Item >
233
208
{
234
209
type Item = I :: Item ;
235
210
@@ -243,7 +218,7 @@ impl<I, F> Iterator for KMergeBy<I, F>
243
218
self . heap . swap_remove ( 0 ) . head
244
219
} ;
245
220
let less_than = & mut self . less_than ;
246
- sift_down ( & mut self . heap , 0 , |a, b| less_than ( & a. head , & b. head ) ) ;
221
+ sift_down ( & mut self . heap , 0 , |a, b| less_than. kmerge_pred ( & a. head , & b. head ) ) ;
247
222
Some ( result)
248
223
}
249
224
0 commit comments