Update docs
This commit is contained in:
@@ -2,25 +2,14 @@
|
||||
|
||||
[](https://github.com/soruh/type_erased_vec/actions/workflows/ci.yml)
|
||||
|
||||
`type_erased_vec_capacity` retains a [`Vec`] allocation while temporarily
|
||||
erasing its element type. The allocation can later be reused by another element
|
||||
type with exactly the same [`Layout`], avoiding an unnecessary deallocation and
|
||||
allocation cycle.
|
||||
`type_erased_vec_capacity` keeps a [`Vec`] allocation available while its
|
||||
element type is temporarily erased. This is useful when a buffer is reused for
|
||||
different element types with the same [`Layout`], without freeing and
|
||||
reallocating it between uses.
|
||||
|
||||
Safe conversion APIs clear the old elements before changing the element type.
|
||||
Unsafe retained-element casts preserve the old elements and require identical
|
||||
size and alignment, valid values of the target type, and valid target-type drop
|
||||
behavior.
|
||||
|
||||
Scoped guards support borrowed, non-`'static` values whose types do not need
|
||||
drop. Outside a scoped guard, retained bytes are treated as [`MaybeUninit`] so
|
||||
expired references are never reconstructed or dropped. `SendTypeErasedVec` and
|
||||
`SendSyncTypeErasedVec` enforce `Send` and `Send + Sync` bounds, respectively,
|
||||
on every API that can initialize or reinterpret elements.
|
||||
|
||||
Operations that panic leave the erased owner valid. Layout-mismatch panics
|
||||
retain their documented behavior. Mutations completed before a panic may be
|
||||
preserved; the crate does not promise transactional rollback.
|
||||
The safe APIs clear the current elements before changing the type. A
|
||||
[`ContentGuard`] provides ordinary `Vec`-like access while the type is fixed;
|
||||
dropping the guard returns the allocation to its erased owner.
|
||||
|
||||
```rust
|
||||
use type_erased_vec_capacity::TypeErasedVec;
|
||||
@@ -35,6 +24,54 @@ assert_eq!(values.as_slice(), &[-1]);
|
||||
assert_eq!(values.capacity(), capacity);
|
||||
```
|
||||
|
||||
The guard can also be used to fill a buffer, inspect it, and leave it ready for
|
||||
the next user:
|
||||
|
||||
```rust
|
||||
use type_erased_vec_capacity::TypeErasedVec;
|
||||
|
||||
let mut buffer = TypeErasedVec::new(Vec::<u32>::with_capacity(4));
|
||||
{
|
||||
let mut values = buffer.as_type::<u32>();
|
||||
values.with(|vec| vec.extend_from_slice(&[10, 20, 30]));
|
||||
assert_eq!(values.as_slice(), &[10, 20, 30]);
|
||||
}
|
||||
|
||||
assert_eq!(buffer.length(), 3);
|
||||
```
|
||||
|
||||
For borrowed values, use a scoped guard. The guard cannot outlive the borrowed
|
||||
data, and its element type must not need a destructor:
|
||||
|
||||
```rust
|
||||
use type_erased_vec_capacity::TypeErasedVec;
|
||||
|
||||
let mut buffer = TypeErasedVec::new(Vec::<&'static str>::new());
|
||||
let message = String::from("reused buffer");
|
||||
{
|
||||
let mut values = buffer.as_type_scoped::<&str>();
|
||||
values.push(&message);
|
||||
assert_eq!(values.as_slice(), &["reused buffer"]);
|
||||
}
|
||||
```
|
||||
|
||||
When a buffer needs to cross a thread boundary, use the wrapper matching the
|
||||
element bounds:
|
||||
|
||||
```rust
|
||||
use type_erased_vec_capacity::SendTypeErasedVec;
|
||||
|
||||
let buffer = SendTypeErasedVec::new(Vec::<String>::new());
|
||||
let handle = std::thread::spawn(move || {
|
||||
let mut buffer = buffer;
|
||||
let mut values = buffer.as_type::<String>();
|
||||
values.push(String::from("work"));
|
||||
values.take()
|
||||
});
|
||||
|
||||
assert_eq!(handle.join().unwrap(), vec!["work"]);
|
||||
```
|
||||
|
||||
The minimum supported Rust version is documented in the package manifest.
|
||||
|
||||
## License
|
||||
|
||||
+11
-8
@@ -3,9 +3,12 @@ use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::ManuallyDrop;
|
||||
|
||||
/// Provides typed access to a [`TypeErasedVec`] allocation.
|
||||
/// Provides temporary, typed access to a [`TypeErasedVec`] allocation.
|
||||
///
|
||||
/// Dropping the guard retains its initialized elements in the erased vector.
|
||||
/// Use the guard like a `Vec`: inspect it with [`ContentGuard::as_slice`], add
|
||||
/// values with [`ContentGuard::push`], or make several changes with
|
||||
/// [`ContentGuard::with`]. Dropping the guard returns the current elements and
|
||||
/// allocation to the erased vector.
|
||||
pub struct ContentGuard<'vec, T> {
|
||||
erased: &'vec mut TypeErasedVec,
|
||||
reerase: fn(Vec<T>) -> TypeErasedVec,
|
||||
@@ -59,7 +62,7 @@ impl<'vec, T> ContentGuard<'vec, T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes all elements and the allocation from the guard.
|
||||
/// Takes the typed `Vec` out of the guard.
|
||||
///
|
||||
/// The guard remains usable with an empty, zero-capacity vector.
|
||||
pub fn take(&mut self) -> Vec<T> {
|
||||
@@ -75,7 +78,7 @@ impl<'vec, T> ContentGuard<'vec, T> {
|
||||
unsafe { parts.into_vec() }
|
||||
}
|
||||
|
||||
/// Calls `function` with the underlying vector and then type-erases it again.
|
||||
/// Runs `function` with the underlying `Vec` and then erases it again.
|
||||
///
|
||||
/// Mutations made by `function` are retained on normal return.
|
||||
///
|
||||
@@ -93,7 +96,7 @@ impl<'vec, T> ContentGuard<'vec, T> {
|
||||
f(restore_guard.vec_mut())
|
||||
}
|
||||
|
||||
/// Removes and drops all initialized elements.
|
||||
/// Removes and drops all elements.
|
||||
pub fn clear(&mut self) {
|
||||
self.with(Vec::clear);
|
||||
}
|
||||
@@ -103,7 +106,7 @@ impl<'vec, T> ContentGuard<'vec, T> {
|
||||
self.with(|vec| vec.reserve(additional));
|
||||
}
|
||||
|
||||
/// Returns the allocation's capacity in elements.
|
||||
/// Returns the vector's capacity in elements.
|
||||
#[must_use]
|
||||
pub const fn capacity(&self) -> usize {
|
||||
self.erased.capacity()
|
||||
@@ -114,13 +117,13 @@ impl<'vec, T> ContentGuard<'vec, T> {
|
||||
self.with(|vec| vec.push(value));
|
||||
}
|
||||
|
||||
/// Returns the number of initialized elements.
|
||||
/// Returns the number of elements currently stored.
|
||||
#[must_use]
|
||||
pub const fn length(&self) -> usize {
|
||||
self.erased.length()
|
||||
}
|
||||
|
||||
/// Returns `true` when there are no initialized elements.
|
||||
/// Returns `true` when the vector contains no elements.
|
||||
#[must_use]
|
||||
pub const fn is_empty(&self) -> bool {
|
||||
self.erased.is_empty()
|
||||
|
||||
+60
-40
@@ -17,11 +17,35 @@ use vtable::TypeErasedVecVtable;
|
||||
|
||||
use crate::parts::VecParts;
|
||||
|
||||
/// Stores the capacity of a `Vec<U>` for later reuse as a `Vec<V>` where `V` shares the same `Layout` as `U`.
|
||||
/// Keeps a `Vec` allocation available while temporarily erasing its element type.
|
||||
///
|
||||
/// Types whose destructors may be retained must be `'static`. Use
|
||||
/// [`TypeErasedVec::as_type_scoped`] for non-`'static` types that do not need
|
||||
/// drop, such as borrowed references.
|
||||
/// Safe type changes clear the current elements first. Use a [`ContentGuard`] to
|
||||
/// work with the allocation as an ordinary `Vec` while its type is fixed; when
|
||||
/// the guard is dropped, the allocation returns to this erased owner.
|
||||
///
|
||||
/// The allocation can be reused for another type only when both types have the
|
||||
/// same [`Layout`]. This makes it useful for buffers that alternate between
|
||||
/// compatible representations without repeatedly allocating.
|
||||
///
|
||||
/// ```
|
||||
/// use type_erased_vec_capacity::TypeErasedVec;
|
||||
///
|
||||
/// let mut buffer = TypeErasedVec::new(Vec::<u32>::with_capacity(3));
|
||||
/// let initial_capacity = buffer.capacity();
|
||||
/// {
|
||||
/// let mut values = buffer.as_type::<u32>();
|
||||
/// values.with(|vec| vec.extend_from_slice(&[1, 2, 3]));
|
||||
/// }
|
||||
/// {
|
||||
/// let mut values = buffer.as_type::<i32>();
|
||||
/// values.push(-1);
|
||||
/// assert_eq!(values.as_slice(), &[-1]);
|
||||
/// }
|
||||
/// assert_eq!(buffer.capacity(), initial_capacity);
|
||||
/// ```
|
||||
///
|
||||
/// Use [`TypeErasedVec::as_type_scoped`] for borrowed, non-`'static` values
|
||||
/// whose type does not need a destructor.
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// use type_erased_vec_capacity::TypeErasedVec;
|
||||
@@ -40,8 +64,7 @@ use crate::parts::VecParts;
|
||||
/// }
|
||||
/// ```
|
||||
pub struct TypeErasedVec {
|
||||
/// The Layout the capacity was allocated with. We need this to confirm that
|
||||
/// any future conversion back to a `Vec` use the correct `Layout`.
|
||||
/// Layout reserved for the allocation.
|
||||
layout: Layout,
|
||||
|
||||
/// Raw parts of the erased vector
|
||||
@@ -63,9 +86,9 @@ impl fmt::Debug for TypeErasedVec {
|
||||
}
|
||||
|
||||
impl TypeErasedVec {
|
||||
/// Type erase the underlying Capacity of a `Vec` remembering the `Layout` it was allocated with.
|
||||
/// Elements inside the `Vec` are retained.
|
||||
/// Conversion back to a `Vec` is only allowed for types with the same Layout.
|
||||
/// Erases the element type while retaining the vector's elements and allocation.
|
||||
///
|
||||
/// The elements can later be accessed as a type with the same [`Layout`].
|
||||
#[must_use]
|
||||
pub fn new<T: 'static>(vec: Vec<T>) -> Self {
|
||||
Self {
|
||||
@@ -90,7 +113,7 @@ impl TypeErasedVec {
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear any remaining elements in the vector, dropping them.
|
||||
/// Removes and drops all elements while retaining the allocation.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
@@ -101,31 +124,31 @@ impl TypeErasedVec {
|
||||
unsafe { (self.vtable.clear)(&mut self.parts) };
|
||||
}
|
||||
|
||||
/// Reserve additional elements in the vector.
|
||||
/// Reserves space for at least `additional` more elements.
|
||||
pub fn reserve(&mut self, additional: usize) {
|
||||
// SAFETY: The reserve function correctly targets the currently stored type elements.
|
||||
unsafe { (self.vtable.reserve)(&mut self.parts, additional) };
|
||||
}
|
||||
|
||||
/// Returns the element layout associated with the allocation.
|
||||
/// Returns the [`Layout`] reserved for the allocation.
|
||||
#[must_use]
|
||||
pub const fn layout(&self) -> Layout {
|
||||
self.layout
|
||||
}
|
||||
|
||||
/// Returns the allocation's capacity in elements.
|
||||
/// Returns the allocation's capacity, measured in elements of its current type.
|
||||
#[must_use]
|
||||
pub const fn capacity(&self) -> usize {
|
||||
self.parts.capacity()
|
||||
}
|
||||
|
||||
/// Returns the number of initialized elements.
|
||||
/// Returns the number of elements currently stored.
|
||||
#[must_use]
|
||||
pub const fn length(&self) -> usize {
|
||||
self.parts.length()
|
||||
}
|
||||
|
||||
/// Returns `true` when there are no initialized elements.
|
||||
/// Returns `true` when the vector contains no elements.
|
||||
#[must_use]
|
||||
pub const fn is_empty(&self) -> bool {
|
||||
self.parts.length() == 0
|
||||
@@ -144,8 +167,7 @@ impl TypeErasedVec {
|
||||
unsafe { capacity_bytes.unwrap_unchecked() }
|
||||
}
|
||||
|
||||
/// Access the erased capacity with a temporarily fixed type.
|
||||
/// Casts the present elements to the new type without calling their destructor.
|
||||
/// Reinterprets the current elements as `T` without clearing them.
|
||||
///
|
||||
/// # Safety
|
||||
/// `T` must have exactly the same [`Layout`] as the erased element type.
|
||||
@@ -169,8 +191,7 @@ impl TypeErasedVec {
|
||||
ContentGuard::new(self)
|
||||
}
|
||||
|
||||
/// Access the erased capacity with a temporarily fixed type.
|
||||
/// Clears all elements currently stored in the `TypeErasedVec`.
|
||||
/// Clears the current elements and accesses the allocation as `T`.
|
||||
///
|
||||
/// Returns `None` if `T` does not have the same [`Layout`] as the
|
||||
/// underlying capacity. On failure, the erased vector is unchanged.
|
||||
@@ -187,8 +208,7 @@ impl TypeErasedVec {
|
||||
Some(ContentGuard::new(self))
|
||||
}
|
||||
|
||||
/// Access the erased capacity with a temporarily fixed type.
|
||||
/// Clears all elements currently stored in the `TypeErasedVec`.
|
||||
/// Clears the current elements and accesses the allocation as `T`.
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if `T` does not have the same `Layout` as the underlying
|
||||
@@ -209,12 +229,12 @@ impl TypeErasedVec {
|
||||
})
|
||||
}
|
||||
|
||||
/// Access the erased capacity using a possibly non-`'static` type.
|
||||
/// Clears the current elements and accesses the allocation as a possibly
|
||||
/// non-`'static` type.
|
||||
///
|
||||
/// The previous elements are cleared. While the guard exists, its lifetime
|
||||
/// tracks `T`. Outside the guard, the allocation is treated as
|
||||
/// `MaybeUninit<T>` so expired references are never reconstructed or dropped.
|
||||
/// A layout mismatch returns `None` without changing the erased vector.
|
||||
/// The guard is tied to the lifetime of `T`, so it can safely contain
|
||||
/// borrowed values. A layout mismatch returns `None` without changing the
|
||||
/// erased vector.
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if `T` needs drop.
|
||||
@@ -233,11 +253,11 @@ impl TypeErasedVec {
|
||||
Some(ContentGuard::new_scoped(self))
|
||||
}
|
||||
|
||||
/// Access the erased capacity using a possibly non-`'static` type.
|
||||
/// Clears the current elements and accesses the allocation as a possibly
|
||||
/// non-`'static` type.
|
||||
///
|
||||
/// The previous elements are cleared. While the guard exists, its lifetime
|
||||
/// tracks `T`. Outside the guard, the allocation is treated as
|
||||
/// `MaybeUninit<T>` so expired references are never reconstructed or dropped.
|
||||
/// The guard is tied to the lifetime of `T`, so it can safely contain
|
||||
/// borrowed values.
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if `T` needs drop or does not have the erased allocation's layout.
|
||||
@@ -258,8 +278,8 @@ impl TypeErasedVec {
|
||||
})
|
||||
}
|
||||
|
||||
/// Access the erased capacity with a temporarily fixed type.
|
||||
/// Clears all elements currently stored in the `TypeErasedVec`.
|
||||
/// Clears the current elements and accesses the allocation as `T` without a
|
||||
/// release-mode layout check.
|
||||
///
|
||||
/// # Safety
|
||||
/// `T` must have the same `Layout` as the underlying capacity.
|
||||
@@ -279,7 +299,7 @@ impl TypeErasedVec {
|
||||
unsafe { res.unwrap_unchecked() }
|
||||
}
|
||||
|
||||
/// Convert the capacity of the erased `Vec` into a `Vec<T>`.
|
||||
/// Converts the erased vector into a `Vec<T>` when the layouts match.
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns the original `TypeErasedVec` if `T` does not have the same `Layout`.
|
||||
@@ -291,7 +311,7 @@ impl TypeErasedVec {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert the capacity of the erased `Vec` into a `Vec<T>`.
|
||||
/// Clears the current elements and converts the allocation into a `Vec<T>`.
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if `T` does not have the same `Layout` as the underlying capacity.
|
||||
@@ -300,7 +320,7 @@ impl TypeErasedVec {
|
||||
self.as_type::<T>().take()
|
||||
}
|
||||
|
||||
/// Convert the capacity of the erased `Vec` into a `Vec<T>`.
|
||||
/// Converts the erased vector into a `Vec<T>` without clearing its elements.
|
||||
///
|
||||
/// # Safety
|
||||
/// `T` must have exactly the same [`Layout`] as the erased element type.
|
||||
@@ -312,7 +332,8 @@ impl TypeErasedVec {
|
||||
unsafe { self.cast_type::<T>() }.take()
|
||||
}
|
||||
|
||||
/// Convert the capacity of the erased `Vec` into a `Vec<T>`.
|
||||
/// Clears the current elements and converts the allocation into a `Vec<T>`
|
||||
/// without a release-mode layout check.
|
||||
///
|
||||
/// # Safety
|
||||
/// `T` must have the same `Layout` as the underlying capacity.
|
||||
@@ -322,11 +343,10 @@ impl TypeErasedVec {
|
||||
unsafe { self.as_type_unchecked().take() }
|
||||
}
|
||||
|
||||
/// Clear a type-erased vector so it can be safely moved or shared across
|
||||
/// threads while preserving its allocation.
|
||||
/// Clears the elements and wraps the allocation for cross-thread use.
|
||||
///
|
||||
/// Use [`SendTypeErasedVec::new`] or [`SendSyncTypeErasedVec::new`] before
|
||||
/// erasing the element type when the elements themselves should be retained.
|
||||
/// Use [`SendTypeErasedVec::new`] or [`SendSyncTypeErasedVec::new`] instead
|
||||
/// when the elements themselves need to cross a thread boundary.
|
||||
#[must_use]
|
||||
pub fn send(mut self) -> SendSyncTypeErasedVec {
|
||||
self.clear();
|
||||
|
||||
+19
-19
@@ -23,7 +23,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
}
|
||||
|
||||
impl $name {
|
||||
/// Type erase a vector while retaining its elements and allocation.
|
||||
/// Erases a vector's element type while retaining its elements and allocation.
|
||||
#[must_use]
|
||||
pub fn new<T>(vec: Vec<T>) -> Self
|
||||
where
|
||||
@@ -32,17 +32,17 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
Self(TypeErasedVec::new(vec))
|
||||
}
|
||||
|
||||
/// Clear all elements while preserving the allocation.
|
||||
/// Removes and drops all elements while retaining the allocation.
|
||||
pub fn clear(&mut self) {
|
||||
self.0.clear();
|
||||
}
|
||||
|
||||
/// Reserve space for at least `additional` more elements.
|
||||
/// Reserves space for at least `additional` more elements.
|
||||
pub fn reserve(&mut self, additional: usize) {
|
||||
self.0.reserve(additional);
|
||||
}
|
||||
|
||||
/// Returns the element layout associated with the allocation.
|
||||
/// Returns the [`Layout`] reserved for the allocation.
|
||||
#[must_use]
|
||||
pub const fn layout(&self) -> Layout {
|
||||
self.0.layout()
|
||||
@@ -54,13 +54,13 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
self.0.capacity()
|
||||
}
|
||||
|
||||
/// Returns the number of initialized elements.
|
||||
/// Returns the number of elements currently stored.
|
||||
#[must_use]
|
||||
pub const fn length(&self) -> usize {
|
||||
self.0.length()
|
||||
}
|
||||
|
||||
/// Returns `true` when there are no initialized elements.
|
||||
/// Returns `true` when the vector contains no elements.
|
||||
#[must_use]
|
||||
pub const fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
@@ -72,7 +72,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
self.0.capacity_bytes()
|
||||
}
|
||||
|
||||
/// Access the erased vector as `T` without clearing its elements.
|
||||
/// Reinterprets the current elements as `T` without clearing them.
|
||||
///
|
||||
/// # Safety
|
||||
/// `T` must have exactly the same [`Layout`] as the erased element
|
||||
@@ -89,7 +89,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
unsafe { self.0.cast_type() }
|
||||
}
|
||||
|
||||
/// Clear the vector and access its allocation as a vector of `T`.
|
||||
/// Clears the current elements and accesses the allocation as `T`.
|
||||
///
|
||||
/// A layout mismatch returns `None` without changing the erased
|
||||
/// vector.
|
||||
@@ -100,7 +100,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
self.0.try_as_type()
|
||||
}
|
||||
|
||||
/// Clear the vector and access its allocation as a vector of `T`.
|
||||
/// Clears the current elements and accesses the allocation as `T`.
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if `T` does not have the erased allocation's layout. A
|
||||
@@ -112,7 +112,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
self.0.as_type()
|
||||
}
|
||||
|
||||
/// Clear the vector and access its allocation using a possibly
|
||||
/// Clears the current elements and accesses the allocation using a possibly
|
||||
/// non-`'static` type that does not need drop.
|
||||
///
|
||||
/// A layout mismatch returns `None` without changing the erased
|
||||
@@ -127,7 +127,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
self.0.try_as_type_scoped()
|
||||
}
|
||||
|
||||
/// Clear the vector and access its allocation using a possibly
|
||||
/// Clears the current elements and accesses the allocation using a possibly
|
||||
/// non-`'static` type that does not need drop.
|
||||
///
|
||||
/// # Panics
|
||||
@@ -141,7 +141,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
self.0.as_type_scoped()
|
||||
}
|
||||
|
||||
/// Clear the vector and access its allocation as a vector of `T`
|
||||
/// Clears the current elements and accesses the allocation as `T`
|
||||
/// without a release-mode layout check.
|
||||
///
|
||||
/// # Safety
|
||||
@@ -154,7 +154,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
unsafe { self.0.as_type_unchecked() }
|
||||
}
|
||||
|
||||
/// Clear the vector and convert its allocation into a `Vec<T>`.
|
||||
/// Clears the current elements and converts the allocation into a `Vec<T>`.
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns this erased vector if `T` does not have the erased
|
||||
@@ -166,7 +166,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
self.0.try_into_vec().map_err(Self)
|
||||
}
|
||||
|
||||
/// Clear the vector and convert its allocation into a `Vec<T>`.
|
||||
/// Clears the current elements and converts the allocation into a `Vec<T>`.
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if `T` does not have the erased allocation's layout.
|
||||
@@ -178,7 +178,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
self.0.into_vec()
|
||||
}
|
||||
|
||||
/// Convert the erased vector into a `Vec<T>` without clearing it.
|
||||
/// Converts the erased vector into a `Vec<T>` without clearing it.
|
||||
///
|
||||
/// # Safety
|
||||
/// `T` must have exactly the same [`Layout`] as the erased element
|
||||
@@ -195,7 +195,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
unsafe { self.0.cast_into_vec() }
|
||||
}
|
||||
|
||||
/// Clear the vector and convert its allocation into a `Vec<T>`
|
||||
/// Clears the current elements and converts the allocation into a `Vec<T>`
|
||||
/// without a release-mode layout check.
|
||||
///
|
||||
/// # Safety
|
||||
@@ -209,7 +209,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
unsafe { self.0.into_vec_unchecked() }
|
||||
}
|
||||
|
||||
/// Remove the thread-safety restriction.
|
||||
/// Returns the underlying erased vector.
|
||||
#[must_use]
|
||||
pub fn unpack(self) -> TypeErasedVec {
|
||||
self.0
|
||||
@@ -219,7 +219,7 @@ macro_rules! define_thread_safe_erased_vec {
|
||||
}
|
||||
|
||||
define_thread_safe_erased_vec!(
|
||||
/// A type-erased vector whose initialized element type is always `Send`.
|
||||
/// A type-erased vector whose elements are always `Send`.
|
||||
///
|
||||
/// The vector can be moved between threads, but it cannot be shared between
|
||||
/// threads because its elements are not required to be `Sync`.
|
||||
@@ -244,7 +244,7 @@ define_thread_safe_erased_vec!(
|
||||
);
|
||||
|
||||
define_thread_safe_erased_vec!(
|
||||
/// A type-erased vector whose initialized element type is always `Send + Sync`.
|
||||
/// A type-erased vector whose elements are always `Send + Sync`.
|
||||
///
|
||||
/// The vector can be moved or shared between threads.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user