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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! This crate aims to provide various tools for slices.
//!
//! This crate use its own streaming iterator
//! due to the lack of generic associated type in the language:
//! you therefore cannot use those iterators with the `for` control flow.
//! Use the `while let` control flow, or the macro helper, as you can see below.
//!
//! # Example
//!
//! ```
//! extern crate slicetools;
//! use slicetools::*;
//!
//! let mut v = vec![1, 2, 3, 4];
//! {
//!     let mut it = v.pairs_mut();
//!     
//!     while let Some((a, b)) = it.next() {
//!         if *b > *a {
//!             *a += 1;
//!         }
//!     }
//! }
//! assert_eq!(v, &[4, 4, 4, 4]);
//! ```
//! 
//! Or, with the helper macro:
//!
//! ```
//! #[macro_use] extern crate slicetools;
//! use slicetools::*;
//! 
//! let mut v = vec![1, 2, 3, 4];
//! 
//! stream!( v.pairs_mut() => (a, b) in {
//!     if *b > *a {
//!         *a += 1;
//!     }
//! });
//! assert_eq!(v, &[4, 4, 4, 4]);
//! ```


mod streamer;
pub use streamer::StreamerMut;


mod cartesian_product_mut;
use cartesian_product_mut::CartesianProductMut;
mod pairs_mut;
use pairs_mut::PairsMut;


/// Convenient helper to use easily the custom streaming iterator.
#[macro_export]
macro_rules! stream {
    { $iter:expr => $item:pat in $b:block } => {{
        let mut it = $iter;

        while let Some($item) = it.next() {
            $b
        }
    }}
}


/// A trait to extend slices and `Vec`s with streaming iterators.
pub trait SliceTools {

    /// Iterate on all the pairs (a, b) from slices A and B such as a ∈ A and b ∈ B,
    /// yielding mutables references on items.
    ///
    /// # Example
    ///
    /// ```
    /// use slicetools::*;
    /// let mut v1 = vec![100; 3];
    /// let mut v2 = vec![1, 2, 3, 4];
    /// {
    ///     let mut it = v1.cartesian_product_mut(&mut v2);
    ///     
    ///     while let Some((a, b)) = it.next() {
    ///         *a += *b;
    ///     }
    /// }
    /// assert_eq!(v1, &[110; 3]);
    /// ```
    fn cartesian_product_mut<'a, S, T: 'a, U: 'a>(&'a mut self, slice: &'a mut S) -> CartesianProductMut<'a, T, U>
        where Self: AsMut<[T]>, S: AsMut<[U]>
    {
        CartesianProductMut::new(self.as_mut(), slice.as_mut())
    }

    /// Iterate on all the possible pairs of the slice,
    /// yielding mutables references on items.
    ///
    /// # Example
    ///
    /// ```
    /// use slicetools::*;
    /// let mut v = vec![1, 2, 3, 4];
    /// {
    ///     let mut it = v.pairs_mut();
    ///     
    ///     while let Some((a, b)) = it.next() {
    ///         if *b > *a {
    ///             *a += 1;
    ///         }
    ///     }
    /// }
    /// assert_eq!(v, &[4, 4, 4, 4]);
    /// ```
    fn pairs_mut<'a, T: 'a>(&'a mut self) -> PairsMut<'a, T>
        where Self: AsMut<[T]>
    {
        PairsMut::new(self.as_mut())
    }
}

impl<T> SliceTools for T {}