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
//! This crate provides an iterator adaptor that yields sliding windows into the elements of the wrapped Iterator.
//!
//! Note that this adaptor does **NEVER** clone any element for huge speed gains.
//!
//! As a consequence it violates the Iterator protocol slightly. It is not possible to have two Windows into the data
//! available at the same time. This is checked during runtime. If this check fails, the Adaptor panicks in ```next()```.
//! More information can be found in the section [Panics](#panics).
//!
//! There are some options regarding the constructor for Storage, which allow reuse of an allocation.
//! Consult the [docs for Storage](struct.Storage.html) for details.
//!
//! Iterator element type is `Window<'a, Self::Item>`.
//!
//! Note: `Window<'a, Self::Item>` implements `iter()` and `iter_mut()`, which return Iterators over the elements of the `Window`.
//!
//! This iterator is *fused*.
//!
//! # Example:
//!
//! ```
//! use sliding_windows::IterExt;
//! use sliding_windows::Storage;
//!
//! let iter = 0..5;
//! let mut storage: Storage<u32> = Storage::new(3);
//! let windowed_iter = iter.sliding_windows(&mut storage);
//! let output: Vec<Vec<u32>> = windowed_iter.map(|x| x.iter().map(|&x| x).collect()).collect();
//! let expected: &[&[u32]] = &[&[0,1,2], &[1,2,3], &[2,3,4]];
//!
//! assert_eq!(output, expected);
//! ```
//!
//! It's also possible to reuse an allocation for `Storage` via the `Into` trait.
//!
//! # Example:
//!
//! ```
//! use sliding_windows::IterExt;
//! use sliding_windows::Storage;
//!
//! let previous_alloca = vec![0u32; 3]; // length doesn't have to be equal to window_size
//! let mut storage: Storage<u32> = Storage::from_vec(previous_alloca, 3);
//! let expected: &[&[u32]] = &[&[0,1,2], &[1,2,3], &[2,3,4]];
//!
//! // extra scope so that windowed_iter doesn't outlive storage.into() call
//! {
//!     let windowed_iter = (0..5).sliding_windows(&mut storage);
//!     let output: Vec<Vec<u32>> = windowed_iter.map(|x| x.iter().map(|&x| x).collect()).collect();
//!     assert_eq!(output, expected);
//! }
//!
//! let reusing_alloca: Vec<u32> = storage.into();
//! // keep using allocation of storage
//!
//! ```
//!
//! ### Panics:
//!
//! As this iterator reuses the allocation for the yielded `Window`, no two instances of `Window`
//! belonging to the same iterator may exist simultaneously. As noted above this is checked at runtime.
//!
//! ```
//! use sliding_windows::IterExt;
//! use sliding_windows::Storage;
//!
//! let mut storage: Storage<u32> = Storage::new(3);
//! let mut windowed_iter = (0..5).sliding_windows(&mut storage);
//!
//! // extra scope so that a doesn't live until the for loop
//! {
//!     let a = windowed_iter.next();
//!     //let b = windowed_iter.next(); => this would PANIC
//! }
//!
//! // looping for example is fine though
//! for _ in windowed_iter {
//!     // blah
//! }
//! ```
//!
//! # Mutable Window:
//!
//! There is an implementation of an Iterator over `&'a mut T` for `Window<'a, T>`. It can be obtained
//! by calling `iter_mut()`. For more information see [`Window<'a, T>`](struct.Window.html).
//!
//! However be aware that changes made to the items in the Window are persistent through calls to `next()`.

mod sliding_windows;
#[cfg(test)]
mod tests;

pub use sliding_windows::{
    Storage, Adaptor, Window, WindowIter, WindowIterMut};

pub trait IterExt: Iterator {
    fn sliding_windows(self, storage: &mut Storage<Self::Item>)
        -> Adaptor<Self>
        where Self: Sized
    {
        Adaptor::new(self, storage)
    }
}

impl<T: ?Sized> IterExt for T where T: Iterator { }