Cartesian product of iterators

[![Latest Version](https://img.shields.io/crates/v/cartprod.svg)][cart_prod] [![Downloads](https://img.shields.io/crates/d/cartprod.svg)][cart_prod] [![Documentation](https://docs.rs/cartprod/badge.svg)][cart_prod/docs] [![License](https://img.shields.io/crates/l/cartprod.svg)][cart_prod/license] [![Dependency Status](https://deps.rs/repo/github/JohnScience/cartprod/status.svg)][cart_prod/depstatus]

At the moment of writing, this crate provides only [Hom2FCartProd] and [Hom3FCartProd] types, which are a two-fold and three-fold Cartesian products of iterators that are "homogenous" in the sense that they produce elements of the same type. Iterators of [Hom2FCartProd] allow to iterate over all distinct pairs [x,y] that can be formed from elements x and y of the original iterators. Similarly, [Hom3FCartProd] allows iteration over triples [x,y,z]. The order of the elements in the pairs is preserved.

Example

```rust use cart_prod::specs::Hom2FCartProd;

let it1 = 0..=2; let it2 = 0..=1;

let mut it = Hom2FCartProd::new(it1, it2); assert!(it.next() == Some([0, 0])); assert!(it.next() == Some([0, 1])); assert!(it.next() == Some([1, 0])); assert!(it.next() == Some([1, 1])); assert!(it.next() == Some([2, 0])); assert!(it.next() == Some([2, 1])); assert!(it.next() == None); ```

Features

Implementation notes

No variadic genericity

Ideally, Hom*FCartProd should be types-aliases for a partial specializations of CartProd (variadic) generic type. However, Rust does not support variadic generics. See https://github.com/rust-lang/rust/issues/10124. For forward compatibility, the [Hom2FCartProd] and [Hom3FCartProd] types are defined in the [cart_prod::specs] module.

Workaround for absence of variadic genericity

It is possible to provide the type definitions as well as implementations (locally) via macros. However, note that at the moment macros cannot evaluate constants, let alone constant expressions. See https://github.com/rust-lang/rfcs/issues/2279. Due to that (and scarcity of time), such macros are currently not provided.

No support for tuple indexing

Unlike in C++ with [std::get], In Rust there's no way to index a tuple by a constant expression. Therefore, it's also impossible to iterate over the tuple of iterators. While its possible to take advantage of trait objects, it's still impossible to generically construct iterators due to absence of variadic genericity.

No top-notch performance guarantees

While the implementations are reasonably efficient, no work was done to benchmark it or to optimize it. While implementation of [core::iter::Iterator::next] is sufficient for implementation of the trait, it is not the most efficient way to implement it. Only the default implementation of [core::iter::Iterator::size_hint] was overridden.

No correctness guarantees

The implementation of [cart_prod] has only a few simple tests. In case of issues, please [report them][cart_prod/issues].

Alternatives

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.