diff --git a/src/lib.rs b/src/lib.rs index 7bdde64..f45b6a3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -415,26 +415,6 @@ impl SmallVec { impl SmallVec { const IS_ZST: bool = size_of::() == 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 @@ -723,7 +703,7 @@ impl SmallVec { if result.is_ok() { // SAFETY: the allocation succeeded, so self.raw.heap is now // active - unsafe { self.set_on_heap() }; + self.length.set_location::(); } result } else { @@ -743,7 +723,7 @@ impl SmallVec { align: align_of::(), allocator: &self.allocator }); - self.set_inline(); + self.length.set_location::(); } } Ok(()) @@ -800,7 +780,7 @@ impl SmallVec { 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::(); self.allocator.deallocate( ptr.cast(), Layout::from_size_align_unchecked(capacity * size_of::(), align_of::()) @@ -833,7 +813,7 @@ impl SmallVec { 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::(); self.allocator.deallocate( ptr.cast(), Layout::from_size_align_unchecked( @@ -1411,7 +1391,7 @@ impl SmallVec { }?; // SAFETY: the allocation succeeded, so self.raw.heap is now active - unsafe { this.set_on_heap() }; + this.length.set_location::(); } Ok(this) } diff --git a/src/taggedlen.rs b/src/taggedlen.rs index 3d33822..f3e6a6e 100644 --- a/src/taggedlen.rs +++ b/src/taggedlen.rs @@ -55,6 +55,13 @@ impl TaggedLen { (self.0 >> Self::SHIFT, (self.0 & Self::TAG) != 0) } + #[inline(always)] + pub const fn set_location(&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