#![feature(macro_rules)]
#![crate_name="itertools"]
#![crate_type="dylib"]
pub use adaptors::Clones;
pub use adaptors::Interleave;
pub use adaptors::Product;
pub use adaptors::PutBack;
pub use adaptors::FnMap;
pub use intersperse::Intersperse;
pub use stride::Stride;
pub use stride::StrideMut;
pub use times::Times;
pub use times::times;
pub use linspace::{linspace, Linspace};
mod adaptors;
mod intersperse;
mod linspace;
mod stride;
mod times;
trait AppendTuple<X, Y> {
fn append(self, x: X) -> Y;
}
macro_rules! impl_append_tuple(
() => (
impl<T> AppendTuple<T, (T, )> for () {
fn append(self, x: T) -> (T, ) {
(x, )
}
}
);
($A:ident $(,$B:ident)*) => (
impl_append_tuple!($($B),*)
#[allow(non_snake_case)]
impl<$A, $($B,)* T> AppendTuple<T, ($A, $($B,)* T)> for ($A, $($B),*) {
fn append(self, x: T) -> ($A, $($B,)* T) {
let ($A, $($B),*) = self;
($A, $($B,)* x)
}
}
);
)
impl_append_tuple!(A, B, C, D, E, F, G, H, I, J, K, L)
#[deriving(Clone)]
pub struct FlatTuples<I> {
pub iter: I,
}
impl<X, Y, T: AppendTuple<X, Y>, I: Iterator<(T, X)>>
Iterator<Y> for FlatTuples<I>
{
#[inline]
fn next(&mut self) -> Option<Y>
{
self.iter.next().map(|(t, x)| t.append(x))
}
fn size_hint(&self) -> (uint, Option<uint>) {
self.iter.size_hint()
}
}
impl<X, Y, T: AppendTuple<X, Y>, I: DoubleEndedIterator<(T, X)>>
DoubleEndedIterator<Y> for FlatTuples<I>
{
#[inline]
fn next_back(&mut self) -> Option<Y>
{
self.iter.next_back().map(|(t, x)| t.append(x))
}
}
#[macro_export]
pub macro_rules! iproduct(
($I:expr) => (
($I)
);
($I:expr, $J:expr $(, $K:expr)*) => (
{
let it = ::itertools::Product::new($I, $J);
$(
let it = ::itertools::FlatTuples{iter: ::itertools::Product::new(it, $K)};
)*
it
}
);
)
#[macro_export]
pub macro_rules! izip(
($I:expr) => (
($I)
);
($I:expr, $J:expr $(, $K:expr)*) => (
{
let it = $I.zip($J);
$(
let it = ::itertools::FlatTuples{iter: it.zip($K)};
)*
it
}
);
)
#[macro_export]
pub macro_rules! icompr(
($r:expr for $x:pat in $J:expr if $pred:expr) => (
($J).filter_map(|$x| if $pred { Some($r) } else { None })
);
($r:expr for $x:pat in $J:expr) => (
($J).filter_map(|$x| Some($r))
);
)
pub trait Itertools<A> : Iterator<A> {
fn fn_map<B>(self, map: fn(A) -> B) -> FnMap<A, B, Self> {
FnMap::new(self, map)
}
fn interleave<J: Iterator<A>>(self, other: J) -> Interleave<Self, J> {
Interleave::new(self, other)
}
fn intersperse(self, element: A) -> Intersperse<A, Self> {
Intersperse::new(self, element)
}
fn clones(self) -> Clones<Self> {
Clones::new(self)
}
fn dropn(&mut self, mut n: uint) -> uint {
let start = n;
while n > 0 {
match self.next() {
Some(..) => n -= 1,
None => break
}
}
start - n
}
fn drain(&mut self) {
for _ in *self { }
}
fn apply(&mut self, f: |A|) {
for elt in *self { f(elt) }
}
}
impl<A, T: Iterator<A>> Itertools<A> for T { }
#[inline]
pub fn write<'a, A: 'a, I: Iterator<&'a mut A>, J: Iterator<A>>
(mut to: I, mut from: J) -> uint
{
let mut count = 0u;
for elt in from {
match to.next() {
None => break,
Some(ptr) => *ptr = elt
}
count += 1;
}
count
}