diff --git a/src/guard.rs b/src/guard.rs index b6b5ef9..5e23cea 100644 --- a/src/guard.rs +++ b/src/guard.rs @@ -2,7 +2,9 @@ use crate::TypeErasedVec; use std::marker::PhantomData; use std::mem::ManuallyDrop; -/// Provides access to a `TypeErasedVec` with a temporarily fixed type `T` +/// Provides typed access to a [`TypeErasedVec`] allocation. +/// +/// Dropping the guard retains its initialized elements in the erased vector. pub struct ContentGuard<'vec, T> { erased: &'vec mut TypeErasedVec, reerase: fn(Vec) -> TypeErasedVec, @@ -19,6 +21,9 @@ impl<'vec, T> ContentGuard<'vec, T> { } } + /// Removes all elements and the allocation from the guard. + /// + /// The guard remains usable with an empty, zero-capacity vector. pub fn take(&mut self) -> Vec { let erased = std::mem::replace(self.erased, (self.reerase)(Vec::new())); let erased = ManuallyDrop::new(erased); @@ -27,6 +32,9 @@ impl<'vec, T> ContentGuard<'vec, T> { unsafe { erased.parts.into_vec() } } + /// Calls `function` with the underlying vector and then type-erases it again. + /// + /// Mutations made by `function` are retained on normal return. pub fn with(&mut self, f: impl FnOnce(&mut Vec) -> R) -> R { let mut vec = self.take(); // This is unwind-safe. If the closure panics, the inner `Vec` drops normally. @@ -37,51 +45,63 @@ impl<'vec, T> ContentGuard<'vec, T> { res } + /// Removes and drops all initialized elements. pub fn clear(&mut self) { self.with(Vec::clear); } + /// Reserves capacity for at least `additional` more elements. pub fn reserve(&mut self, additional: usize) { self.with(|vec| vec.reserve(additional)); } + /// Returns the allocation's capacity in elements. #[must_use] pub fn capacity(&self) -> usize { self.erased.capacity() } + /// Appends an element. pub fn push(&mut self, value: T) { self.with(|vec| vec.push(value)); } + /// Returns the number of initialized elements. #[must_use] pub fn length(&self) -> usize { self.erased.length() } + /// Returns `true` when there are no initialized elements. #[must_use] pub fn is_empty(&self) -> bool { self.erased.is_empty() } + /// Borrows the initialized elements as a slice. #[must_use] pub fn as_slice(&self) -> &[T] { // SAFETY: The pointer and length correctly represent the currently initialized elements. unsafe { self.erased.parts.as_slice() } } + /// Mutably borrows the initialized elements as a slice. #[must_use] pub fn as_slice_mut(&mut self) -> &mut [T] { // SAFETY: The pointer and length correctly represent the currently initialized elements. unsafe { self.erased.parts.as_slice_mut() } } + /// Consumes the guard and borrows the initialized elements for the erased + /// vector's lifetime. #[must_use] pub fn into_slice(self) -> &'vec [T] { // SAFETY: The pointer and length correctly represent the currently initialized elements. unsafe { self.erased.parts.as_slice() } } + /// Consumes the guard and mutably borrows the initialized elements for the + /// erased vector's lifetime. #[must_use] pub fn into_slice_mut(self) -> &'vec mut [T] { // SAFETY: The pointer and length correctly represent the currently initialized elements. diff --git a/src/lib.rs b/src/lib.rs index 65a3e58..12e8981 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -87,26 +87,34 @@ impl TypeErasedVec { unsafe { (self.vtable.reserve)(&mut self.parts, additional) }; } + /// Returns the element layout associated with the allocation. #[must_use] pub fn layout(&self) -> Layout { self.layout } + /// Returns the allocation's capacity in elements. #[must_use] pub fn capacity(&self) -> usize { self.parts.cap } + /// Returns the number of initialized elements. #[must_use] pub fn length(&self) -> usize { self.parts.len } + /// Returns `true` when there are no initialized elements. #[must_use] pub fn is_empty(&self) -> bool { self.parts.len == 0 } + /// Returns the allocation's capacity in bytes. + /// + /// Zero-sized elements always report zero bytes, regardless of their + /// logical capacity. #[must_use] pub fn capacity_bytes(&self) -> usize { self.parts.cap * self.layout.size() diff --git a/src/send.rs b/src/send.rs index 1ec7d8c..d670e17 100644 --- a/src/send.rs +++ b/src/send.rs @@ -30,26 +30,31 @@ macro_rules! define_thread_safe_erased_vec { self.0.reserve(additional); } + /// Returns the element layout associated with the allocation. #[must_use] pub fn layout(&self) -> Layout { self.0.layout() } + /// Returns the allocation's capacity in elements. #[must_use] pub fn capacity(&self) -> usize { self.0.capacity() } + /// Returns the number of initialized elements. #[must_use] pub fn length(&self) -> usize { self.0.length() } + /// Returns `true` when there are no initialized elements. #[must_use] pub fn is_empty(&self) -> bool { self.0.is_empty() } + /// Returns the allocation's capacity in bytes. #[must_use] pub fn capacity_bytes(&self) -> usize { self.0.capacity_bytes()