slicetools 0.3.0

Add extra iterators to slices.
Documentation
#[cfg(test)] mod tests;

use ::StreamerMut;

pub struct PairsMut<'a, T: 'a> {
    slice: &'a mut [T],
    first: usize,
    second: usize,
}

impl<'a, 'it, T> StreamerMut<'it, (&'it mut T, &'it mut T)> for PairsMut<'a, T> {
    fn next(&'it mut self) -> Option<(&'it mut T, &'it mut T)> {
        match self.slice.len() - self.first {
            0 | 1 => None,
            _ => self.get_next(),
        }
    }
}

impl<'a, T> PairsMut<'a, T> {
    pub fn new(slice: &'a mut [T]) -> PairsMut<'a, T> {
        PairsMut{ slice, first: 0, second: 1 }
    }

    fn get_next(&mut self) -> Option<(&'a mut T, &'a mut T)> {
        let ptr = self.slice.as_mut_ptr();

        if self.second >= self.slice.len() {
            self.first += 1;
            self.second = self.first + 1;
        }

        if self.second < self.slice.len() {             //    second < len
            debug_assert!(self.first < self.second);    // && first < second
                                                        // => this is safe
            let res = unsafe{ Self::get_pair(ptr, self.first, self.second) };
            self.second += 1;
            res
        } else {
            None
        }
    }

    unsafe fn get_pair(ptr: *mut T, first: usize, second: usize) -> Option<(&'a mut T, &'a mut T)> {
        Some((&mut *ptr.offset(first as isize), &mut *ptr.offset(second as isize)))
    }
}