diff --git a/src/any_value/mod.rs b/src/any_value/mod.rs index cf44f7d..74b35e9 100644 --- a/src/any_value/mod.rs +++ b/src/any_value/mod.rs @@ -211,7 +211,7 @@ pub trait AnyValueCloneable: AnyValueSizeless { unsafe fn clone_into(&self, out: *mut u8); #[inline] - fn lazy_clone(&self) -> LazyClone + fn lazy_clone(&self) -> LazyClone<'_, Self> where Self: Sized { LazyClone::new(self) diff --git a/src/any_vec.rs b/src/any_vec.rs index 088d91d..9aaecfc 100644 --- a/src/any_vec.rs +++ b/src/any_vec.rs @@ -7,8 +7,8 @@ use core::ops::{Deref, DerefMut, Range, RangeBounds}; use core::ptr::NonNull; use core::{fmt, ptr, slice}; use core::slice::{from_raw_parts, from_raw_parts_mut}; -use crate::{AnyVecTyped, into_range, mem, ops}; -use crate::any_value::{AnyValue, AnyValueSizeless}; +use crate::{AnyVecTyped, into_range, mem, ops, assert_types_equal}; +use crate::any_value::{AnyValue, AnyValueSizeless, Unknown}; use crate::any_vec_raw::{AnyVecRaw, DropFn}; use crate::ops::{TempValue, Remove, SwapRemove, remove, swap_remove, Pop, pop}; use crate::ops::{Drain, Splice, drain, splice}; @@ -423,7 +423,7 @@ impl AnyVec /// Returns [`AnyVecRef`] - typed view to const AnyVec, /// if container holds elements of type T, or None if it isn’t. #[inline] - pub fn downcast_ref(&self) -> Option> { + pub fn downcast_ref(&self) -> Option> { if self.element_typeid() == TypeId::of::() { unsafe{ Some(self.downcast_ref_unchecked()) } } else { @@ -438,14 +438,14 @@ impl AnyVec /// The container elements must be of type `T`. /// Calling this method with the incorrect type is undefined behavior. #[inline] - pub unsafe fn downcast_ref_unchecked(&self) -> AnyVecRef { + pub unsafe fn downcast_ref_unchecked(&self) -> AnyVecRef<'_, T, M> { AnyVecRef(AnyVecTyped::new(NonNull::from(&self.raw))) } /// Returns [`AnyVecMut`] - typed view to mut AnyVec, /// if container holds elements of type T, or None if it isn’t. #[inline] - pub fn downcast_mut(&mut self) -> Option> { + pub fn downcast_mut(&mut self) -> Option> { if self.element_typeid() == TypeId::of::() { unsafe{ Some(self.downcast_mut_unchecked()) } } else { @@ -460,7 +460,7 @@ impl AnyVec /// The container elements must be of type `T`. /// Calling this method with the incorrect type is undefined behavior. #[inline] - pub unsafe fn downcast_mut_unchecked(&mut self) -> AnyVecMut { + pub unsafe fn downcast_mut_unchecked(&mut self) -> AnyVecMut<'_, T, M> { AnyVecMut(AnyVecTyped::new(NonNull::from(&mut self.raw))) } @@ -489,12 +489,12 @@ impl AnyVec } #[inline] - pub fn iter(&self) -> IterRef{ + pub fn iter(&self) -> IterRef<'_, Traits, M>{ Iter::new(AnyVecPtr::from(self), 0, self.len()) } #[inline] - pub fn iter_mut(&mut self) -> IterMut{ + pub fn iter_mut(&mut self) -> IterMut<'_, Traits, M>{ let len = self.len(); Iter::new(AnyVecPtr::from(self), 0, len) } @@ -505,12 +505,12 @@ impl AnyVec /// /// * Panics if index is out of bounds. #[inline] - pub fn at(&self, index: usize) -> ElementRef{ + pub fn at(&self, index: usize) -> ElementRef<'_, Traits, M>{ self.get(index).unwrap() } #[inline] - pub fn get(&self, index: usize) -> Option>{ + pub fn get(&self, index: usize) -> Option>{ if index < self.len(){ Some(unsafe{ self.get_unchecked(index) }) } else { @@ -519,7 +519,7 @@ impl AnyVec } #[inline] - pub unsafe fn get_unchecked(&self, index: usize) -> ElementRef{ + pub unsafe fn get_unchecked(&self, index: usize) -> ElementRef<'_, Traits, M>{ let element_ptr = self.raw.get_unchecked(index) as *mut u8; ElementRef( ManuallyDrop::new(ElementPointer::new( @@ -535,12 +535,12 @@ impl AnyVec /// /// * Panics if index is out of bounds. #[inline] - pub fn at_mut(&mut self, index: usize) -> ElementMut{ + pub fn at_mut(&mut self, index: usize) -> ElementMut<'_, Traits, M>{ self.get_mut(index).unwrap() } #[inline] - pub fn get_mut(&mut self, index: usize) -> Option>{ + pub fn get_mut(&mut self, index: usize) -> Option>{ if index < self.len(){ Some(unsafe{ self.get_unchecked_mut(index) }) } else { @@ -549,7 +549,7 @@ impl AnyVec } #[inline] - pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> ElementMut { + pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> ElementMut<'_, Traits, M> { let element_ptr = self.raw.get_unchecked_mut(index); ElementMut( ManuallyDrop::new(ElementPointer::new( @@ -625,7 +625,7 @@ impl AnyVec /// [`mem::forget`]: core::mem::forget /// #[inline] - pub fn pop(&mut self) -> Option> { + pub fn pop(&mut self) -> Option> { if self.is_empty(){ None } else { @@ -648,7 +648,7 @@ impl AnyVec /// [`mem::forget`]: core::mem::forget /// #[inline] - pub fn remove(&mut self, index: usize) -> Remove { + pub fn remove(&mut self, index: usize) -> Remove<'_, Traits, M> { self.raw.index_check(index); TempValue::new(remove::Remove::new( AnyVecPtr::from(self), @@ -669,13 +669,31 @@ impl AnyVec /// [`mem::forget`]: core::mem::forget /// #[inline] - pub fn swap_remove(&mut self, index: usize) -> SwapRemove { + pub fn swap_remove(&mut self, index: usize) -> SwapRemove<'_, Traits, M> { self.raw.index_check(index); TempValue::new(swap_remove::SwapRemove::new( AnyVecPtr::from(self), index )) } + + /// Moves all the elements of `other` into `self`, leaving `other` empty. + /// + /// # Panics + /// + /// * Panics if types mismatch. + /// * Panics if out of memory. + pub fn append( + &mut self, other: &mut AnyVec + ) where + OtherTraits: ?Sized + Trait, + OtherM: MemBuilder + { + assert_types_equal(other.element_typeid(), self.element_typeid()); + unsafe{ + self.raw.append_unchecked::(&mut other.raw); + } + } /// Removes the specified range from the vector in bulk, returning all removed /// elements as an iterator. If the iterator is dropped before being fully consumed, @@ -697,7 +715,7 @@ impl AnyVec /// [`mem::forget`]: core::mem::forget /// #[inline] - pub fn drain(&mut self, range: impl RangeBounds) -> Drain { + pub fn drain(&mut self, range: impl RangeBounds) -> Drain<'_, Traits, M> { let Range{start, end} = into_range(self.len(), range); ops::Iter(drain::Drain::new( AnyVecPtr::from(self), @@ -729,7 +747,7 @@ impl AnyVec /// #[inline] pub fn splice(&mut self, range: impl RangeBounds, replace_with: I) - -> Splice + -> Splice<'_, Traits, M, I::IntoIter> where I::IntoIter: ExactSizeIterator, I::Item: AnyValue diff --git a/src/any_vec_raw.rs b/src/any_vec_raw.rs index d75d3c5..7f77cc6 100644 --- a/src/any_vec_raw.rs +++ b/src/any_vec_raw.rs @@ -209,6 +209,38 @@ impl AnyVecRaw { self.len += 1; } + + /// # Safety + /// + /// Type is not checked. + pub unsafe fn append_unchecked( + &mut self, other: &mut AnyVecRaw + ) { + self.reserve(other.len); + + // copy + unsafe { + if !Unknown::is::(){ + ptr::copy_nonoverlapping( + other.mem.as_ptr().cast::(), + self.mem.as_mut_ptr().cast::().add(self.len), + other.len + ); + } else { + let element_size = self.element_layout().size(); + ptr::copy_nonoverlapping( + other.mem.as_ptr(), + self.mem.as_mut_ptr().add(self.len*element_size), + other.len*element_size + ); + } + } + + // update len(s) + self.len += other.len; + other.len = 0; + + } #[inline] pub fn clear(&mut self){ diff --git a/src/any_vec_typed.rs b/src/any_vec_typed.rs index d2b2f84..1d81957 100644 --- a/src/any_vec_typed.rs +++ b/src/any_vec_typed.rs @@ -147,6 +147,19 @@ impl<'a, T: 'static, M: MemBuilder + 'a> AnyVecTyped<'a, T, M>{ } } + /// Moves all the elements of `other` into `self`, leaving `other` empty. + /// + /// # Panics + /// + /// * Panics if out of memory. + pub fn append( + &mut self, other: &mut AnyVecTyped + ) { + unsafe{ + self.this_mut().append_unchecked::(other.this_mut()); + } + } + #[inline] pub fn drain(&mut self, range: impl RangeBounds) -> impl ElementIterator + 'a diff --git a/tests/any_vec.rs b/tests/any_vec.rs index dcd85ab..411d754 100644 --- a/tests/any_vec.rs +++ b/tests/any_vec.rs @@ -271,6 +271,33 @@ fn any_vec_splice_test() { ]); } +#[test] +fn append_test() { + let mut any_vec: AnyVec = AnyVec::new::(); + any_vec.push(AnyValueWrapper::new(String::from("0"))); + any_vec.push(AnyValueWrapper::new(String::from("1"))); + any_vec.push(AnyValueWrapper::new(String::from("2"))); + any_vec.push(AnyValueWrapper::new(String::from("3"))); + any_vec.push(AnyValueWrapper::new(String::from("4"))); + + let mut any_vec2: AnyVec = AnyVec::new::(); + any_vec2.push(AnyValueWrapper::new(String::from("100"))); + any_vec2.push(AnyValueWrapper::new(String::from("200"))); + + any_vec.append(&mut any_vec2); + + assert_equal(any_vec.downcast_ref::().unwrap().as_slice(), &[ + String::from("0"), + String::from("1"), + String::from("2"), + String::from("3"), + String::from("4"), + String::from("100"), + String::from("200"), + ]); + assert!(any_vec2.is_empty()); +} + #[test] fn any_vec_insert_front(){ let mut any_vec: AnyVec = AnyVec::new::(); diff --git a/tests/any_vec_typed.rs b/tests/any_vec_typed.rs index 6fa7047..3bd5758 100644 --- a/tests/any_vec_typed.rs +++ b/tests/any_vec_typed.rs @@ -196,6 +196,35 @@ fn any_vec_debug() { assert_eq!(format!("{vec:?}"), format!("{control_vec:?}")); } +#[test] +fn append_test() { + let mut any_vec: AnyVec = AnyVec::new::(); + let mut vec = any_vec.downcast_mut::().unwrap(); + vec.push(String::from("0")); + vec.push(String::from("1")); + vec.push(String::from("2")); + vec.push(String::from("3")); + vec.push(String::from("4")); + + let mut any_vec2: AnyVec = AnyVec::new::(); + let mut vec2 = any_vec2.downcast_mut::().unwrap(); + vec2.push(String::from("100")); + vec2.push(String::from("200")); + + vec.append(&mut vec2); + + assert_equal(any_vec.downcast_ref::().unwrap().as_slice(), &[ + String::from("0"), + String::from("1"), + String::from("2"), + String::from("3"), + String::from("4"), + String::from("100"), + String::from("200"), + ]); + assert!(any_vec2.is_empty()); +} + /* #[test] fn any_vec_index_test() {