diff --git a/src/lib.rs b/src/lib.rs index 21a6409..247c56b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,6 +41,7 @@ use alloc::boxed::Box; use core::alloc::Layout; use core::marker::PhantomData; use core::num::NonZeroUsize; +use core::ops::Index; use core::ptr::{NonNull, Pointee}; use core::{mem, ptr}; @@ -81,9 +82,9 @@ impl Vechonk { } /// Create a new Vechonk that allocates `capacity` bytes. `capacity` gets shrunken down - /// to the next multiple of the alignment of the metadata of `T` + /// to the next multiple of the alignment of usize + metadata of `T` pub fn with_capacity(capacity: usize) -> Self { - let capacity = capacity - (capacity % Self::meta_align()); + let capacity = capacity - (capacity % Self::data_align()); let mut vechonk = Self::new(); @@ -98,16 +99,19 @@ impl Vechonk { vechonk } + /// Pushes a new element into the [`Vechonk`]. Does panic (for now) if there is no more capacity pub fn push(&mut self, element: Box) { let element_size = mem::size_of_val(element.as_ref()); let ptr = element.as_ref(); let meta = ptr::metadata(ptr); - let meta_size = Self::meta_size(); + let data_size = Self::data_size(); // just panic here instead of a proper realloc - assert!(!self.needs_grow(element_size + meta_size)); + assert!(!self.needs_grow(element_size + data_size)); + + let data: PtrData = (self.len, meta); // SAFETY: none for now unsafe { @@ -117,12 +121,12 @@ impl Vechonk { } // SAFETY: none for now - let meta_ptr = unsafe { self.ptr.as_ptr().add(self.cap - meta_size) }; - let meta_ptr = meta_ptr as *mut _; + let data_ptr = unsafe { self.ptr.as_ptr().add(self.cap - data_size) }; + let data_ptr = data_ptr as *mut _; // SAFETY: none for now unsafe { - *meta_ptr = meta; + *data_ptr = data; } self.elem_size += element_size; @@ -136,7 +140,7 @@ impl Vechonk { /// The caller must either set the `len` to zero, or copy the elements to the new allocation by saving /// `self.ptr` before calling this function. unsafe fn grow_to(&mut self, size: NonZeroUsize) { - let layout = Layout::from_size_align(size.get(), Self::meta_align()).unwrap(); + let layout = Layout::from_size_align(size.get(), Self::data_align()).unwrap(); // SAFETY: layout is guaranteed to have a non-zero size let alloced_ptr = unsafe { alloc::alloc::alloc(layout) }; @@ -148,23 +152,31 @@ impl Vechonk { } fn needs_grow(&self, additional_size: usize) -> bool { - additional_size > self.cap - (self.elem_size + self.meta_section_size()) + additional_size > self.cap - (self.elem_size + self.data_section_size()) } - fn meta_section_size(&self) -> usize { - self.len * mem::size_of::>() + fn data_section_size(&self) -> usize { + self.len * mem::size_of::>() } - fn meta_align() -> usize { - mem::align_of::>() + fn data_align() -> usize { + mem::align_of::>() } - fn meta_size() -> usize { - mem::size_of::>() + fn data_size() -> usize { + mem::size_of::>() } } -// we can only drop copy for now because destructors 🤮 +impl Index for Vechonk { + type Output = T; + + fn index(&self, _index: usize) -> &Self::Output { + todo!() + } +} + +/// don't bother with destructors for now impl Drop for Vechonk { fn drop(&mut self) { if self.cap == 0 { @@ -172,7 +184,7 @@ impl Drop for Vechonk { } // SAFETY: 1 is not 0 and a power of two. `size > usize::MAX` must always be true - let layout = Layout::from_size_align(self.cap, mem::align_of::>()).unwrap(); + let layout = Layout::from_size_align(self.cap, mem::align_of::>()).unwrap(); unsafe { alloc::alloc::dealloc(self.ptr.as_ptr(), layout) }; } @@ -184,4 +196,4 @@ impl Default for Vechonk { } } -type Meta = ::Metadata; +type PtrData = (usize, ::Metadata); diff --git a/src/test.rs b/src/test.rs index 1257914..43f46ca 100644 --- a/src/test.rs +++ b/src/test.rs @@ -50,6 +50,8 @@ fn push_two_sized_elem() { chonk.push(Box::new(2)); assert_eq!(chonk.len(), 2); + assert_eq!(chonk.elem_size, 2); + assert_eq!(chonk.data_section_size(), 16); // two indecies } #[test] @@ -60,4 +62,6 @@ fn push_two_unsized_elem() { chonk.push("uwu".into()); assert_eq!(chonk.len(), 2); + assert_eq!(chonk.elem_size, 8); + assert_eq!(chonk.data_section_size(), 32); // two indecies + lengths }