diff --git a/src/collections/scoped_buffer.rs b/src/collections/scoped_buffer.rs index 7f5194cf31bc6ef317490d82f6dc413fb07e2272..518c889433f8045e9c80d5ce3862414e60c38369 100644 --- a/src/collections/scoped_buffer.rs +++ b/src/collections/scoped_buffer.rs @@ -73,54 +73,80 @@ pub(crate) struct ScopedSection { } impl ScopedSection { + /// Pushes value into section #[inline] pub(crate) fn push(&mut self, value: T) { + self.check_length(); let vec = unsafe{&mut *self.inner}; - hide!(debug_assert_eq!( - vec.len(), self.cur_size as usize, - "trying to push onto section, but size is larger than expected" - )); vec.push(value); hide!(self.cur_size += 1); } #[inline] pub(crate) fn len(&self) -> usize { + self.check_length(); let vec = unsafe{&mut *self.inner}; - hide!(debug_assert_eq!( - vec.len(), self.cur_size as usize, - "trying to get section length, but size is larger than expected" - )); return vec.len() - self.start_size as usize; } #[inline] #[allow(unused_mut)] // used in debug mode pub(crate) fn forget(mut self) { + self.check_length(); let vec = unsafe{&mut *self.inner}; - hide!({ - debug_assert_eq!( - vec.len(), self.cur_size as usize, - "trying to forget section, but size is larger than expected" - ); - self.cur_size = self.start_size; - }); + hide!(self.cur_size = self.start_size); vec.truncate(self.start_size as usize); } #[inline] #[allow(unused_mut)] // used in debug mode pub(crate) fn into_vec(mut self) -> Vec { + self.check_length(); let vec = unsafe{&mut *self.inner}; + hide!(self.cur_size = self.start_size); + let section = Vec::from_iter(vec.drain(self.start_size as usize..)); + section + } + + #[inline] + pub(crate) fn check_length(&self) { hide!({ + let vec = unsafe{&*self.inner}; debug_assert_eq!( vec.len(), self.cur_size as usize, - "trying to turn section into vec, but size is larger than expected" - ); - self.cur_size = self.start_size; - }); - let section = Vec::from_iter(vec.drain(self.start_size as usize..)); - section + "incorrect use of ScopedSection: underlying storage vector has changed size" + ) + }) + } +} + +impl ScopedSection { + #[inline] + pub(crate) fn push_unique(&mut self, value: T) { + self.check_length(); + let vec = unsafe{&mut *self.inner}; + for item in &vec[self.start_size as usize..] { + if *item == value { + // item already exists + return; + } + } + + vec.push(value); + hide!(self.cur_size += 1); + } + + #[inline] + pub(crate) fn contains(&self, value: &T) -> bool { + self.check_length(); + let vec = unsafe{&*self.inner}; + for index in self.start_size..vec.len() { + if vec[index] == value { + return true; + } + } + + return false; } }