Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 5 additions & 25 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,26 +415,6 @@ impl<T: Clone, const N: usize> SmallVec<T, N> {
impl<T, const N: usize, A: Allocator> SmallVec<T, N, A> {
const IS_ZST: bool = size_of::<T>() == 0;

/// Sets the tag to be on the heap
///
/// # Safety
///
/// The active union member must be the self.raw.heap
#[inline]
unsafe fn set_on_heap(&mut self) {
self.length = TaggedLen::new(self.len(), true);
}

/// Sets the tag to be inline
///
/// # Safety
///
/// The active union member must be the self.raw.inline
#[inline]
unsafe fn set_inline(&mut self) {
self.length = TaggedLen::new(self.len(), false);
}

/// Sets the length of a vector.
///
/// This will explicitly set the size of the vector, without actually
Expand Down Expand Up @@ -723,7 +703,7 @@ impl<T, const N: usize, A: Allocator> SmallVec<T, N, A> {
if result.is_ok() {
// SAFETY: the allocation succeeded, so self.raw.heap is now
// active
unsafe { self.set_on_heap() };
self.length.set_location::<true>();
}
result
} else {
Expand All @@ -743,7 +723,7 @@ impl<T, const N: usize, A: Allocator> SmallVec<T, N, A> {
align: align_of::<T>(),
allocator: &self.allocator
});
self.set_inline();
self.length.set_location::<false>();
}
}
Ok(())
Expand Down Expand Up @@ -800,7 +780,7 @@ impl<T, const N: usize, A: Allocator> SmallVec<T, N, A> {
unsafe {
let (ptr, capacity) = self.raw.heap;
copy_nonoverlapping(ptr.as_ptr(), self.raw.as_mut_ptr_inline(), length);
self.set_inline();
self.length.set_location::<false>();
self.allocator.deallocate(
ptr.cast(),
Layout::from_size_align_unchecked(capacity * size_of::<T>(), align_of::<T>())
Expand Down Expand Up @@ -833,7 +813,7 @@ impl<T, const N: usize, A: Allocator> SmallVec<T, N, A> {
unsafe {
let (ptr, capacity) = self.raw.heap;
copy_nonoverlapping(ptr.as_ptr(), self.raw.as_mut_ptr_inline(), length);
self.set_inline();
self.length.set_location::<false>();
self.allocator.deallocate(
ptr.cast(),
Layout::from_size_align_unchecked(
Expand Down Expand Up @@ -1411,7 +1391,7 @@ impl<T, const N: usize, A: Allocator> SmallVec<T, N, A> {
}?;

// SAFETY: the allocation succeeded, so self.raw.heap is now active
unsafe { this.set_on_heap() };
this.length.set_location::<true>();
}
Ok(this)
}
Expand Down
7 changes: 7 additions & 0 deletions src/taggedlen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ impl<T> TaggedLen<T> {
(self.0 >> Self::SHIFT, (self.0 & Self::TAG) != 0)
}

#[inline(always)]
pub const fn set_location<const ON: bool>(&mut self) {
if Self::TAG != 0 {
self.0 = (self.0 & !Self::TAG) | ON as usize;
}
}

/// # Safety
///
/// current length+n must be smaller than MAX_LEN on 64-bit target
Expand Down
Loading