continue refactor
This commit is contained in:
@@ -47,6 +47,10 @@ impl<'vec, T> ContentGuard<'vec, T> {
|
||||
self.erased.capacity()
|
||||
}
|
||||
|
||||
pub fn push(&mut self, value: T) {
|
||||
self.with(|vec| vec.push(value));
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn length(&self) -> usize {
|
||||
self.erased.length()
|
||||
@@ -68,4 +72,16 @@ impl<'vec, T> ContentGuard<'vec, T> {
|
||||
// SAFETY: The pointer and length correctly represent the currently initialized elements.
|
||||
unsafe { self.erased.parts.as_slice_mut() }
|
||||
}
|
||||
|
||||
#[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() }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn into_slice_mut(self) -> &'vec mut [T] {
|
||||
// SAFETY: The pointer and length correctly represent the currently initialized elements.
|
||||
unsafe { self.erased.parts.as_slice_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -101,7 +101,7 @@ impl TypeErasedVec {
|
||||
/// Clears all elements currently stored in the `TypeErasedVec`.
|
||||
///
|
||||
/// Will fail if `T` does not have the same `Layout` as the underlying capacity.
|
||||
pub fn try_to_type<T>(&mut self) -> Option<ContentGuard<'_, T>> {
|
||||
pub fn try_as_type<T>(&mut self) -> Option<ContentGuard<'_, T>> {
|
||||
self.clear();
|
||||
// SAFETY: The vector has been cleared, meaning there are no existing elements
|
||||
// that could be invalidated or improperly dropped by the cast.
|
||||
@@ -113,9 +113,9 @@ impl TypeErasedVec {
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if `T` does not have the same `Layout` as the underlying capacity.
|
||||
pub fn to_type<T>(&mut self) -> ContentGuard<'_, T> {
|
||||
pub fn as_type<T>(&mut self) -> ContentGuard<'_, T> {
|
||||
let layout = self.layout;
|
||||
self.try_to_type().unwrap_or_else(|| {
|
||||
self.try_as_type().unwrap_or_else(|| {
|
||||
panic!(
|
||||
"Target type layout must exactly match the erased layout. Capacity is reserved for {:?} but {} has {:?}",
|
||||
layout,
|
||||
@@ -130,13 +130,13 @@ impl TypeErasedVec {
|
||||
///
|
||||
/// # Safety
|
||||
/// `T` must have the same `Layout` as the underlying capacity.
|
||||
pub unsafe fn to_type_unchecked<T>(&mut self) -> ContentGuard<'_, T> {
|
||||
pub unsafe fn as_type_unchecked<T>(&mut self) -> ContentGuard<'_, T> {
|
||||
let layout = self.layout;
|
||||
let res = self.try_to_type();
|
||||
let res = self.try_as_type();
|
||||
|
||||
if cfg!(debug_assertions) && res.is_none() {
|
||||
unreachable!(
|
||||
"Calling `to_type_unchecked` with an incompatible layout is UB! Target type layout must exactly match the erased layout. Capacity is reserved for {:?} but {} has {:?}",
|
||||
"Calling `as_type_unchecked` with an incompatible layout is UB! Target type layout must exactly match the erased layout. Capacity is reserved for {:?} but {} has {:?}",
|
||||
layout,
|
||||
std::any::type_name::<T>(),
|
||||
Layout::new::<T>()
|
||||
@@ -152,7 +152,7 @@ impl TypeErasedVec {
|
||||
/// # Errors
|
||||
/// Returns the original `TypeErasedVec` if `T` does not have the same `Layout`.
|
||||
pub fn try_into_vec<T>(mut self) -> Result<Vec<T>, Self> {
|
||||
if let Some(mut guard) = self.try_to_type::<T>() {
|
||||
if let Some(mut guard) = self.try_as_type::<T>() {
|
||||
Ok(guard.take())
|
||||
} else {
|
||||
Err(self)
|
||||
@@ -165,7 +165,7 @@ impl TypeErasedVec {
|
||||
/// Panics if `T` does not have the same `Layout` as the underlying capacity.
|
||||
#[must_use]
|
||||
pub fn into_vec<T>(mut self) -> Vec<T> {
|
||||
self.to_type::<T>().take()
|
||||
self.as_type::<T>().take()
|
||||
}
|
||||
|
||||
/// Convert the capacity of the erased `Vec` into a `Vec<T>`.
|
||||
@@ -175,7 +175,7 @@ impl TypeErasedVec {
|
||||
#[must_use]
|
||||
pub unsafe fn into_vec_unchecked<T>(mut self) -> Vec<T> {
|
||||
// SAFETY: Ensured by the caller.
|
||||
unsafe { self.to_type_unchecked().take() }
|
||||
unsafe { self.as_type_unchecked().take() }
|
||||
}
|
||||
|
||||
/// Clear a type erased vec allowing it be safely shared across threads, preserving the capacity
|
||||
|
||||
+10
-10
@@ -128,7 +128,7 @@ fn test_cast_type_success_and_mutation() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_to_type_clears_elements() {
|
||||
fn test_try_as_type_clears_elements() {
|
||||
let drop_count = Rc::new(Cell::new(0));
|
||||
let mut vec = Vec::with_capacity(5);
|
||||
|
||||
@@ -140,8 +140,8 @@ fn test_try_to_type_clears_elements() {
|
||||
let mut erased = TypeErasedVec::new(vec);
|
||||
assert_erased_state(&erased, 3, Layout::new::<DropTracker>());
|
||||
|
||||
let Some(guard) = erased.try_to_type::<DropTracker>() else {
|
||||
panic!("try_to_type failed despite matching layouts");
|
||||
let Some(guard) = erased.try_as_type::<DropTracker>() else {
|
||||
panic!("try_as_type failed despite matching layouts");
|
||||
};
|
||||
|
||||
assert_guard_state(&guard, 0);
|
||||
@@ -190,7 +190,7 @@ fn test_conversion_methods() {
|
||||
assert!(restored.capacity() >= initial_cap);
|
||||
|
||||
let mut erased2 = TypeErasedVec::new(restored);
|
||||
let mut guard = erased2.to_type::<String>();
|
||||
let mut guard = erased2.as_type::<String>();
|
||||
guard.reserve(20);
|
||||
let new_cap = guard.capacity();
|
||||
|
||||
@@ -222,10 +222,10 @@ fn test_try_into_vec_failure_and_recovery() {
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Target type layout must exactly match")]
|
||||
fn test_to_type_panics_on_layout_mismatch() {
|
||||
fn test_as_type_panics_on_layout_mismatch() {
|
||||
let vec = Vec::<u32>::new();
|
||||
let mut erased = TypeErasedVec::new(vec);
|
||||
let _ = erased.to_type::<u64>();
|
||||
let _ = erased.as_type::<u64>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -238,18 +238,18 @@ fn test_into_vec_panics_on_layout_mismatch() {
|
||||
|
||||
#[test]
|
||||
#[cfg(debug_assertions)]
|
||||
#[should_panic(expected = "Calling `to_type_unchecked` with an incompatible layout is UB!")]
|
||||
fn test_to_type_unchecked_panics_on_layout_mismatch_in_debug() {
|
||||
#[should_panic(expected = "Calling `as_type_unchecked` with an incompatible layout is UB!")]
|
||||
fn test_as_type_unchecked_panics_on_layout_mismatch_in_debug() {
|
||||
let vec = Vec::<u32>::new();
|
||||
let mut erased = TypeErasedVec::new(vec);
|
||||
unsafe {
|
||||
let _ = erased.to_type_unchecked::<u64>();
|
||||
let _ = erased.as_type_unchecked::<u64>();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(debug_assertions)]
|
||||
#[should_panic(expected = "Calling `to_type_unchecked` with an incompatible layout is UB!")]
|
||||
#[should_panic(expected = "Calling `as_type_unchecked` with an incompatible layout is UB!")]
|
||||
fn test_into_vec_unchecked_panics_on_layout_mismatch_in_debug() {
|
||||
let vec = Vec::<u32>::new();
|
||||
let erased = TypeErasedVec::new(vec);
|
||||
|
||||
Reference in New Issue
Block a user