diff --git a/src/collections/scoped_buffer.rs b/src/collections/scoped_buffer.rs index d3eea0f78a8c985c0cab8b599d4d5f9eaa715f2e..f6f62b77ed4bca0048e38c9acbb44f1261537656 100644 --- a/src/collections/scoped_buffer.rs +++ b/src/collections/scoped_buffer.rs @@ -5,8 +5,9 @@ /// procedure, we push stuff into the buffer. At the end we take out what we /// have put in. /// -/// It is unsafe because we're using pointers to take care of borrowing rules. -/// The correctness of use is checked in debug mode. +/// It is unsafe because we're using pointers to circumvent borrowing rules in +/// the name of code cleanliness. The correctness of use is checked in debug +/// mode. /// The buffer itself. This struct should be the shared buffer. The type `T` is /// intentionally `Copy` such that it can be copied out and the underlying @@ -15,6 +16,9 @@ pub(crate) struct ScopedBuffer { pub inner: Vec, } +/// A section of the buffer. Keeps track of where we started the section. When +/// done with the section one must call `into_vec` or `forget` to remove the +/// section from the underlying buffer. pub(crate) struct ScopedSection { inner: *mut Vec, start_size: u32, @@ -48,11 +52,17 @@ impl ScopedSection { #[inline] pub(crate) fn push(&mut self, value: T) { let vec = unsafe{&mut *self.inner}; - debug_assert!_eq(vec.len(), self.cur_size as usize, "trying to push onto section, but size is larger than expected"); + debug_assert_eq!(vec.len(), self.cur_size as usize, "trying to push onto section, but size is larger than expected"); vec.push(value); if cfg!(debug_assertions) { self.cur_size += 1; } } + pub(crate) fn len(&self) -> usize { + let vec = unsafe{&mut *self.inner}; + 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; + } + #[inline] pub(crate) fn forget(self) { let vec = unsafe{&mut *self.inner}; @@ -70,6 +80,15 @@ impl ScopedSection { } } +impl std::ops::Index for ScopedSection { + type Output = T; + + fn index(&self, idx: usize) -> &Self::Output { + let vec = unsafe{&*self.inner}; + return vec[self.start_size as usize + idx] + } +} + #[cfg(debug_assertions)] impl Drop for ScopedBuffer { fn drop(&mut self) {