mini_rx/misc/
slice_split3.rs

1//! Split at an index and return mutable references to the elements before, after, and the element itself.
2
3use std::iter::{Iterator, ExactSizeIterator};
4use std::mem::transmute;
5
6pub struct IterMutSplit3s<'a, T> {
7    slice: &'a mut [T],
8    index: usize
9}
10
11pub trait SliceSplit3<T> {
12    fn split3_mut<'a>(&'a mut self, index: usize) -> (&'a mut [T], &'a mut T, &'a mut [T]);
13    fn iter_mut_split3s<'a>(&'a mut self) -> IterMutSplit3s<'a, T>;
14}
15
16impl<T> SliceSplit3<T> for [T] {
17    fn split3_mut<'a>(&'a mut self, index: usize) -> (&'a mut [T], &'a mut T, &'a mut [T]) {
18        let (before, current_and_after) = self.split_at_mut(index);
19        let (current, after) = current_and_after.split_first_mut().unwrap();
20        (before, current, after)
21    }
22
23    fn iter_mut_split3s<'a>(&'a mut self) -> IterMutSplit3s<'a, T> {
24        IterMutSplit3s::new(self)
25    }
26}
27
28impl<'a, T> IterMutSplit3s<'a, T> {
29    fn new(slice: &'a mut [T]) -> IterMutSplit3s<'a, T> {
30        IterMutSplit3s {
31            slice,
32            index: 0
33        }
34    }
35}
36
37impl<'a, T> Iterator for IterMutSplit3s<'a, T> {
38    type Item = (&'a mut [T], &'a mut T, &'a mut [T]);
39
40    fn next(&mut self) -> Option<Self::Item> {
41        if self.index >= self.slice.len() {
42            None
43        } else {
44            let split3 = self.slice.split3_mut(self.index);
45            self.index += 1;
46            Some(unsafe { transmute::<(&mut [T], &mut T, &mut [T]), (&'a mut [T], &'a mut T, &'a mut [T])>(split3) })
47        }
48    }
49
50    fn size_hint(&self) -> (usize, Option<usize>) {
51        (0, Some(self.slice.len()))
52    }
53
54    fn count(self) -> usize {
55        self.slice.len()
56    }
57}
58
59impl<'a, T> ExactSizeIterator for IterMutSplit3s<'a, T> {}