1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
//! Some convenient traits and functions for process grid based iterators

use crate::combine::Combine;
use itertools::Product;
mod tuple;
mod transpose;

/// Create a grid over a tuple of iterators
pub fn grid<G: IntoGrid>(g: G) -> G::Grid {
    g.into_grid()
}

/// Trait used by [grid]
pub trait IntoGrid {
    type Grid;
    fn into_grid(self) -> Self::Grid;
}

/// 2D Grid Iterator
pub type Grid2<I1, I2> = Product<I1, I2>;
/// 3D Grid Iterator
pub type Grid3<I1, I2, I3> = Combine<Product<Grid2<I1, I2>, I3>>;
/// 4D Grid Iterator
pub type Grid4<I1, I2, I3, I4> = Combine<Product<Grid3<I1, I2, I3>, I4>>;

/// Trait for Transpose
/// Used by [Range](std::ops::Range) to convert `Range<(A, B)>` into `(Range<A>, Range<B>)` for example
pub trait Transpose {
    type Output;
    fn transpose(self) -> Self::Output;
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_grid2() {
        let it = grid((
            vec![0, 1].into_iter(),
            vec![2, 3].into_iter(),
        ));

        assert!(it.eq(vec![
            (0, 2),
            (0, 3),
            (1, 2),
            (1, 3),
        ]));
    }

    #[test]
    fn test_grid3() {
        let it = grid((
            vec![0, 1].into_iter(),
            vec![2, 3].into_iter(),
            vec![4, 5].into_iter(),
        ));

        assert!(it.eq(vec![
            (0, 2, 4),
            (0, 2, 5),
            (0, 3, 4),
            (0, 3, 5),
            (1, 2, 4),
            (1, 2, 5),
            (1, 3, 4),
            (1, 3, 5),
        ]));
    }

    #[test]
    fn test_grid4() {
        let it = grid((
            vec![0, 1].into_iter(),
            vec![2, 3].into_iter(),
            vec![4, 5].into_iter(),
            vec![6, 7].into_iter(),
        ));

        assert!(it.eq(vec![
            (0, 2, 4, 6),
            (0, 2, 4, 7),
            (0, 2, 5, 6),
            (0, 2, 5, 7),
            (0, 3, 4, 6),
            (0, 3, 4, 7),
            (0, 3, 5, 6),
            (0, 3, 5, 7),
            (1, 2, 4, 6),
            (1, 2, 4, 7),
            (1, 2, 5, 6),
            (1, 2, 5, 7),
            (1, 3, 4, 6),
            (1, 3, 4, 7),
            (1, 3, 5, 6),
            (1, 3, 5, 7),
        ]));
    }
}