diff --git a/src/combinations.rs b/src/combinations.rs index c75f6e6e1..6df9b4e40 100644 --- a/src/combinations.rs +++ b/src/combinations.rs @@ -1,6 +1,7 @@ use std::ops::Index; use std::fmt; +use std::iter::{self, Empty}; /// An iterator to iterate through all the `n`-length combinations in an iterator. /// @@ -20,31 +21,37 @@ impl fmt::Debug for Combinations debug_fmt_fields!(Combinations, n, indices, pool, first); } -/// Create a new `Combinations` from a clonable iterator. +/// Create a new `Combinations` from a cloneable iterator. pub fn combinations(iter: I, n: usize) -> Combinations where I: Iterator { - let mut indices: Vec = Vec::with_capacity(n); - for i in 0..n { - indices.push(i); - } let mut pool: LazyBuffer = LazyBuffer::new(iter); - for _ in 0..n { if !pool.get_next() { break; } } + Combinations::new(n, pool) +} - Combinations { - n: n, - indices: indices, - pool: pool, - first: true, +impl Combinations + where I: Iterator +{ + fn new(n: usize, pool: LazyBuffer) -> Combinations { + Combinations { + n: n, + indices: (0..n).collect(), + pool: pool, + first: true, + } + } + + /// Fast construction from a slice. + pub(crate) fn from_slice(src: &[T], n: usize) -> Combinations> { + let pool = LazyBuffer::>::from_slice(src); + Combinations::new(n, pool) } -} -impl Combinations { #[inline] /// Returns the length of a combination produced by this iterator. pub fn n(&self) -> usize { self.n } @@ -132,6 +139,14 @@ impl LazyBuffer } } + fn from_slice(src: &[T]) -> LazyBuffer> { + LazyBuffer { + it: iter::empty::(), + done: true, + buffer: src.to_owned(), + } + } + pub fn len(&self) -> usize { self.buffer.len() } diff --git a/src/powerset.rs b/src/powerset.rs index 8d603096a..fed602c2e 100644 --- a/src/powerset.rs +++ b/src/powerset.rs @@ -1,7 +1,7 @@ -use std::vec::IntoIter; use std::fmt; use std::usize; -use super::combinations::{self, Combinations}; +use std::iter::{self, Empty}; +use super::combinations::Combinations; use super::size_hint; /// An iterator over the powerset of all elements from its source iterator. @@ -17,7 +17,7 @@ pub struct Powerset { pos: usize, } -type SetCombinations = Combinations::Item>>; +type SetCombinations = Combinations::Item>>; impl fmt::Debug for Powerset where I: Iterator + fmt::Debug, @@ -28,8 +28,7 @@ impl fmt::Debug for Powerset /// Create a new `Powerset` from a cloneable iterator. pub fn powerset(src: I) -> Powerset - where I: Iterator, - I::Item: Clone + where I: Iterator { let (src_low, _) = src.size_hint(); @@ -57,8 +56,7 @@ impl Powerset None => 2 }; - let iter = self.buf.clone().into_iter(); - let mut combs = combinations::combinations(iter, new_len); + let mut combs = Combinations::>::from_slice(&self.buf[..], new_len); let result = combs.next(); self.combs = Some(combs);