Skip to content

Commit 1ff00a9

Browse files
committed
Define KMerge in terms of KMergeBy
1 parent 68bfe1d commit 1ff00a9

1 file changed

Lines changed: 20 additions & 48 deletions

File tree

src/kmerge_impl.rs

Lines changed: 20 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -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

239211
impl<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

Comments
 (0)