@@ -112,17 +112,25 @@ fn sift_down<T, S>(heap: &mut [T], index: usize, mut less_than: S)
112112///
113113/// See [`.kmerge()`](../trait.Itertools.html#method.kmerge) for more information.
114114#[ 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 ;
119119}
120120
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+ }
126134}
127135
128136/// Create an iterator that merges elements of the contained iterators using
@@ -147,43 +155,7 @@ pub fn kmerge<I>(iterable: I) -> KMerge<<I::Item as IntoIterator>::IntoIter>
147155 let mut heap = Vec :: with_capacity ( lower) ;
148156 heap. extend ( iter. filter_map ( |it| HeadTail :: new ( it. into_iter ( ) ) ) ) ;
149157 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- }
158+ KMerge { heap : heap , less_than : KMergeByLt }
187159}
188160
189161/// An iterator adaptor that merges an abitrary number of base iterators
@@ -238,7 +210,7 @@ impl<I, F> Clone for KMergeBy<I, F>
238210
239211impl < I , F > Iterator for KMergeBy < I , F >
240212 where I : Iterator ,
241- F : FnMut ( & I :: Item , & I :: Item ) -> bool
213+ F : KMergePredicate < I :: Item >
242214{
243215 type Item = I :: Item ;
244216
@@ -252,7 +224,7 @@ impl<I, F> Iterator for KMergeBy<I, F>
252224 self . heap . swap_remove ( 0 ) . head
253225 } ;
254226 let less_than = & mut self . less_than ;
255- sift_down ( & mut self . heap , 0 , |a, b| less_than ( & a. head , & b. head ) ) ;
227+ sift_down ( & mut self . heap , 0 , |a, b| less_than. kmerge_pred ( & a. head , & b. head ) ) ;
256228 Some ( result)
257229 }
258230
0 commit comments