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
use super::abstract_mut::AbstractMut;
use super::with_id::LastId;
use crate::entity_id::EntityId;
#[cfg(feature = "parallel")]
use rayon::iter::plumbing::Producer;

#[allow(missing_docs)]
pub struct Tight<Storage> {
    pub(super) storage: Storage,
    pub(super) current: usize,
    pub(super) end: usize,
}

impl<Storage: AbstractMut> Iterator for Tight<Storage> {
    type Item = Storage::Out;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.current < self.end {
            self.current += 1;

            Some(unsafe { self.storage.get_data(self.current - 1) })
        } else {
            None
        }
    }
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let exact = self.end - self.current;

        (exact, Some(exact))
    }
    #[inline]
    fn fold<B, F>(mut self, mut init: B, mut f: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> B,
    {
        while self.current < self.end {
            self.current += 1;

            init = f(init, unsafe { self.storage.get_data(self.current - 1) });
        }

        init
    }
}

impl<Storage: AbstractMut> ExactSizeIterator for Tight<Storage> {
    #[inline]
    fn len(&self) -> usize {
        self.end - self.current
    }
}

impl<Storage: AbstractMut> DoubleEndedIterator for Tight<Storage> {
    #[inline]
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.current < self.end {
            self.end -= 1;

            Some(unsafe { self.storage.get_data(self.end) })
        } else {
            None
        }
    }
    #[inline]
    fn rfold<B, F>(mut self, mut init: B, mut f: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> B,
    {
        while self.current < self.end {
            self.end -= 1;

            init = f(init, unsafe { self.storage.get_data(self.end) });
        }

        init
    }
}

impl<Storage: AbstractMut> LastId for Tight<Storage> {
    #[inline]
    unsafe fn last_id(&self) -> EntityId {
        self.storage.get_id(self.current - 1)
    }
    #[inline]
    unsafe fn last_id_back(&self) -> EntityId {
        self.storage.get_id(self.end + 1)
    }
}

#[cfg(feature = "parallel")]
impl<Storage: AbstractMut + Clone + Send> Producer for Tight<Storage> {
    type Item = <Self as Iterator>::Item;
    type IntoIter = Self;

    #[inline]
    fn into_iter(self) -> Self::IntoIter {
        self
    }
    #[inline]
    fn split_at(mut self, index: usize) -> (Self, Self) {
        let second_half = Tight {
            storage: self.storage.clone(),
            current: self.current + index,
            end: self.end,
        };

        self.end = second_half.current;

        (self, second_half)
    }
}