Document public vector accessors

This commit is contained in:
2026-07-31 03:25:47 +02:00
parent 0c84689e8c
commit 3dbcff919b
3 changed files with 34 additions and 1 deletions
+21 -1
View File
@@ -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<T>) -> 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<T> {
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<R>(&mut self, f: impl FnOnce(&mut Vec<T>) -> R) -> R {
let mut vec = self.take();
// This is unwind-safe. If the closure panics, the inner `Vec<T>` 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.
+8
View File
@@ -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()
+5
View File
@@ -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()