diff --git a/src/arrayvec.rs b/src/arrayvec.rs index 3527669..b039a0d 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -147,9 +147,11 @@ impl ArrayVec { #[inline] pub fn append(&mut self, other: &mut Self) { let new_len = self.len() + other.len(); - assert!(new_len <= A::CAPACITY, - "ArrayVec::append> total length {} exceeds capacity {}!", - new_len, A::CAPACITY + assert!( + new_len <= A::CAPACITY, + "ArrayVec::append> total length {} exceeds capacity {}!", + new_len, + A::CAPACITY ); for item in other.drain(..) { @@ -174,7 +176,10 @@ impl ArrayVec { /// assert_eq!(av3, &[7, 8, 9][..]); /// ``` #[inline] - pub fn try_append<'other>(&mut self, other: &'other mut Self) -> Option<&'other mut Self> { + pub fn try_append<'other>( + &mut self, + other: &'other mut Self, + ) -> Option<&'other mut Self> { let new_len = self.len() + other.len(); if new_len > A::CAPACITY { return Some(other); @@ -403,8 +408,8 @@ impl ArrayVec { assert!(x.is_none(), "ArrayVec::insert> capacity overflow!"); } - /// Tries to insert an item at the position given, moving all following elements +1 - /// index. + /// Tries to insert an item at the position given, moving all following + /// elements +1 index. /// Returns back the element if the capacity is exhausted, /// otherwise returns None. /// @@ -730,6 +735,74 @@ impl ArrayVec { new } + /// Creates a splicing iterator that removes the specified range in the + /// vector, yields the removed items, and replaces them with elements from + /// the provided iterator. + /// + /// `splice` fuses the provided iterator, so elements after the first `None` + /// are ignored. + /// + /// ## Panics + /// * If the start is greater than the end. + /// * If the end is past the edge of the vec. + /// * If the provided iterator panics. + /// * If the new length would overflow the capacity of the array. Because + /// `ArrayVecSplice` adds elements to this vec in its destructor when + /// necessary, this panic would occur when it is dropped. + /// + /// ## Example + /// ```rust + /// use tinyvec::*; + /// let mut av = array_vec!([i32; 4] => 1, 2, 3); + /// let av2: ArrayVec<[i32; 4]> = av.splice(1.., 4..=6).collect(); + /// assert_eq!(av.as_slice(), &[1, 4, 5, 6][..]); + /// assert_eq!(av2.as_slice(), &[2, 3][..]); + /// + /// av.splice(.., None); + /// assert_eq!(av.as_slice(), &[]); + /// ``` + #[inline] + pub fn splice( + &mut self, + range: R, + replacement: I, + ) -> ArrayVecSplice<'_, A, core::iter::Fuse> + where + R: RangeBounds, + I: IntoIterator, + { + use core::ops::Bound; + let start = match range.start_bound() { + Bound::Included(x) => *x, + Bound::Excluded(x) => x + 1, + Bound::Unbounded => 0, + }; + let end = match range.end_bound() { + Bound::Included(x) => x + 1, + Bound::Excluded(x) => *x, + Bound::Unbounded => self.len(), + }; + assert!( + start <= end, + "ArrayVec::splice> Illegal range, {} to {}", + start, + end + ); + assert!( + end <= self.len(), + "ArrayVec::splice> Range ends at {} but length is only {}!", + end, + self.len() + ); + + ArrayVecSplice { + removal_start: start, + removal_end: end, + parent: self, + replacement: replacement.into_iter().fuse(), + } + } + /// Remove an element, swapping the end of the vec into its place. /// /// ## Panics @@ -905,6 +978,110 @@ impl<'p, A: Array> Drop for ArrayVecDrain<'p, A> { } } +/// Splicing iterator for `ArrayVec` +/// See [`ArrayVec::splice`](ArrayVec::::splice) +pub struct ArrayVecSplice<'p, A: Array, I: Iterator> { + parent: &'p mut ArrayVec, + removal_start: usize, + removal_end: usize, + replacement: I, +} + +impl<'p, A: Array, I: Iterator> Iterator + for ArrayVecSplice<'p, A, I> +{ + type Item = A::Item; + + fn next(&mut self) -> Option { + if self.removal_start < self.removal_end { + match self.replacement.next() { + Some(replacement) => { + let removed = core::mem::replace( + &mut self.parent[self.removal_start], + replacement, + ); + self.removal_start += 1; + Some(removed) + } + None => { + let removed = self.parent.remove(self.removal_start); + self.removal_end -= 1; + Some(removed) + } + } + } else { + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } +} + +impl<'p, A, I> ExactSizeIterator for ArrayVecSplice<'p, A, I> +where + A: Array, + I: Iterator, +{ + #[inline] + fn len(&self) -> usize { + self.removal_end - self.removal_start + } +} + +impl<'p, A, I> FusedIterator for ArrayVecSplice<'p, A, I> +where + A: Array, + I: Iterator, +{ +} + +impl<'p, A, I> DoubleEndedIterator for ArrayVecSplice<'p, A, I> +where + A: Array, + I: Iterator + DoubleEndedIterator, +{ + fn next_back(&mut self) -> Option { + if self.removal_start < self.removal_end { + match self.replacement.next_back() { + Some(replacement) => { + let removed = core::mem::replace( + &mut self.parent[self.removal_end - 1], + replacement, + ); + self.removal_end -= 1; + Some(removed) + } + None => { + let removed = self.parent.remove(self.removal_end - 1); + self.removal_end -= 1; + Some(removed) + } + } + } else { + None + } + } +} + +impl<'p, A: Array, I: Iterator> Drop + for ArrayVecSplice<'p, A, I> +{ + fn drop(&mut self) { + for _ in self.by_ref() {} + + // FIXME: reserve lower bound of size_hint + + for replacement in self.replacement.by_ref() { + self.parent.insert(self.removal_end, replacement); + self.removal_end += 1; + } + } +} + impl AsMut<[A::Item]> for ArrayVec { #[inline(always)] #[must_use] @@ -1335,4 +1512,3 @@ impl ArrayVec { self.drain_to_vec_and_reserve(0) } } - diff --git a/src/tinyvec.rs b/src/tinyvec.rs index 956a39f..d446c79 100644 --- a/src/tinyvec.rs +++ b/src/tinyvec.rs @@ -161,11 +161,12 @@ impl TinyVec { /// assert!(tv.is_inline()); /// ``` pub fn shrink_to_fit(&mut self) - where A: Default, + where + A: Default, { let vec = match self { TinyVec::Inline(_) => return, - TinyVec::Heap(h) => h, + TinyVec::Heap(h) => h, }; if vec.len() > A::CAPACITY { @@ -191,7 +192,7 @@ impl TinyVec { #[allow(clippy::missing_inline_in_public_items)] pub fn move_to_the_heap(&mut self) { let arr = match self { - TinyVec::Heap(_) => return, + TinyVec::Heap(_) => return, TinyVec::Inline(a) => a, }; @@ -211,10 +212,10 @@ impl TinyVec { /// ``` pub fn move_to_the_heap_and_reserve(&mut self, n: usize) { let arr = match self { - TinyVec::Heap(h) => return h.reserve(n), + TinyVec::Heap(h) => return h.reserve(n), TinyVec::Inline(a) => a, }; - + let v = arr.drain_to_vec_and_reserve(n); *self = TinyVec::Heap(v); } @@ -231,7 +232,7 @@ impl TinyVec { /// ``` pub fn reserve(&mut self, n: usize) { let arr = match self { - TinyVec::Heap(h) => return h.reserve(n), + TinyVec::Heap(h) => return h.reserve(n), TinyVec::Inline(a) => a, }; @@ -250,7 +251,7 @@ impl TinyVec { /// From [Vec::reserve_exact](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.reserve_exact) /// ```text /// Note that the allocator may give the collection more space than it requests. - /// Therefore, capacity can not be relied upon to be precisely minimal. + /// Therefore, capacity can not be relied upon to be precisely minimal. /// Prefer reserve if future insertions are expected. /// ``` /// ```rust @@ -263,7 +264,7 @@ impl TinyVec { /// ``` pub fn reserve_exact(&mut self, n: usize) { let arr = match self { - TinyVec::Heap(h) => return h.reserve_exact(n), + TinyVec::Heap(h) => return h.reserve_exact(n), TinyVec::Inline(a) => a, }; @@ -285,7 +286,7 @@ impl TinyVec { let iter = other.drain(..); match self { - TinyVec::Heap(h) => h.extend(iter), + TinyVec::Heap(h) => h.extend(iter), TinyVec::Inline(a) => a.extend(iter), } } @@ -455,7 +456,7 @@ impl TinyVec { self.reserve(sli.len()); match self { TinyVec::Inline(a) => a.extend_from_slice(sli), - TinyVec::Heap(h) => h.extend_from_slice(sli), + TinyVec::Heap(h) => h.extend_from_slice(sli), } } @@ -505,19 +506,22 @@ impl TinyVec { /// ``` #[inline] pub fn insert(&mut self, index: usize, item: A::Item) { - assert!(index <= self.len(), - "insertion index (is {}) should be <= len (is {})", - index, self.len() + assert!( + index <= self.len(), + "insertion index (is {}) should be <= len (is {})", + index, + self.len() ); let arr = match self { - TinyVec::Heap(v) => return v.insert(index, item), + TinyVec::Heap(v) => return v.insert(index, item), TinyVec::Inline(a) => a, }; if let Some(x) = arr.try_insert(index, item) { let mut v = Vec::with_capacity(arr.len() * 2); - let mut it = arr.iter_mut().map(|r| core::mem::replace(r, Default::default())); + let mut it = + arr.iter_mut().map(|r| core::mem::replace(r, Default::default())); v.extend(it.by_ref().take(index)); v.push(x); v.extend(it); @@ -576,7 +580,7 @@ impl TinyVec { #[inline(always)] pub fn push(&mut self, val: A::Item) { let arr = match self { - TinyVec::Heap(v) => return v.push(val), + TinyVec::Heap(v) => return v.push(val), TinyVec::Inline(a) => a, }; @@ -663,13 +667,13 @@ impl TinyVec { #[inline] pub fn resize_with A::Item>(&mut self, new_len: usize, f: F) { match new_len.checked_sub(self.len()) { - None => return self.truncate(new_len), + None => return self.truncate(new_len), Some(n) => self.reserve(n), } match self { TinyVec::Inline(a) => a.resize_with(new_len, f), - TinyVec::Heap(v) => v.resize_with(new_len, f), + TinyVec::Heap(v) => v.resize_with(new_len, f), } } @@ -720,6 +724,71 @@ impl TinyVec { } } + /// Creates a splicing iterator that removes the specified range in the + /// vector, yields the removed items, and replaces them with elements from + /// the provided iterator. + /// + /// `splice` fuses the provided iterator, so elements after the first `None` + /// are ignored. + /// + /// ## Panics + /// * If the start is greater than the end. + /// * If the end is past the edge of the vec. + /// * If the provided iterator panics. + /// + /// ## Example + /// ```rust + /// use tinyvec::*; + /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); + /// let tv2: TinyVec<[i32; 4]> = tv.splice(1.., 4..=6).collect(); + /// assert_eq!(tv.as_slice(), &[1, 4, 5, 6][..]); + /// assert_eq!(tv2.as_slice(), &[2, 3][..]); + /// + /// tv.splice(.., None); + /// assert_eq!(tv.as_slice(), &[]); + /// ``` + #[inline] + pub fn splice( + &mut self, + range: R, + replacement: I, + ) -> TinyVecSplice<'_, A, core::iter::Fuse> + where + R: RangeBounds, + I: IntoIterator, + { + use core::ops::Bound; + let start = match range.start_bound() { + Bound::Included(x) => *x, + Bound::Excluded(x) => x + 1, + Bound::Unbounded => 0, + }; + let end = match range.end_bound() { + Bound::Included(x) => x + 1, + Bound::Excluded(x) => *x, + Bound::Unbounded => self.len(), + }; + assert!( + start <= end, + "TinyVec::splice> Illegal range, {} to {}", + start, + end + ); + assert!( + end <= self.len(), + "TinyVec::splice> Range ends at {} but length is only {}!", + end, + self.len() + ); + + TinyVecSplice { + removal_start: start, + removal_end: end, + parent: self, + replacement: replacement.into_iter().fuse(), + } + } + /// Remove an element, swapping the end of the vec into its place. /// /// ## Panics @@ -800,6 +869,113 @@ impl<'p, A: Array> Drop for TinyVecDrain<'p, A> { } } +/// Splicing iterator for `TinyVec` +/// See [`TinyVec::splice`](TinyVec::::splice) +pub struct TinyVecSplice<'p, A: Array, I: Iterator> { + parent: &'p mut TinyVec, + removal_start: usize, + removal_end: usize, + replacement: I, +} + +impl<'p, A, I> Iterator for TinyVecSplice<'p, A, I> +where + A: Array, + I: Iterator, +{ + type Item = A::Item; + + fn next(&mut self) -> Option { + if self.removal_start < self.removal_end { + match self.replacement.next() { + Some(replacement) => { + let removed = core::mem::replace( + &mut self.parent[self.removal_start], + replacement, + ); + self.removal_start += 1; + Some(removed) + } + None => { + let removed = self.parent.remove(self.removal_start); + self.removal_end -= 1; + Some(removed) + } + } + } else { + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } +} + +impl<'p, A, I> ExactSizeIterator for TinyVecSplice<'p, A, I> +where + A: Array, + I: Iterator, +{ + #[inline] + fn len(&self) -> usize { + self.removal_end - self.removal_start + } +} + +impl<'p, A, I> FusedIterator for TinyVecSplice<'p, A, I> +where + A: Array, + I: Iterator, +{ +} + +impl<'p, A, I> DoubleEndedIterator for TinyVecSplice<'p, A, I> +where + A: Array, + I: Iterator + DoubleEndedIterator, +{ + fn next_back(&mut self) -> Option { + if self.removal_start < self.removal_end { + match self.replacement.next_back() { + Some(replacement) => { + let removed = core::mem::replace( + &mut self.parent[self.removal_end - 1], + replacement, + ); + self.removal_end -= 1; + Some(removed) + } + None => { + let removed = self.parent.remove(self.removal_end - 1); + self.removal_end -= 1; + Some(removed) + } + } + } else { + None + } + } +} + +impl<'p, A: Array, I: Iterator> Drop + for TinyVecSplice<'p, A, I> +{ + fn drop(&mut self) { + for _ in self.by_ref() {} + + let (lower_bound, _) = self.replacement.size_hint(); + self.parent.reserve(lower_bound); + + for replacement in self.replacement.by_ref() { + self.parent.insert(self.removal_end, replacement); + self.removal_end += 1; + } + } +} + impl AsMut<[A::Item]> for TinyVec { #[inline(always)] #[must_use] @@ -839,19 +1015,19 @@ impl Extend for TinyVec { let (lower_bound, _) = iter.size_hint(); self.reserve(lower_bound); - let a = match self { + let a = match self { TinyVec::Heap(h) => return h.extend(iter), TinyVec::Inline(a) => a, }; - + let mut iter = a.fill(iter); let maybe = iter.next(); - + let surely = match maybe { Some(x) => x, None => return, }; - + let mut v = a.drain_to_vec_and_reserve(a.len()); v.push(surely); v.extend(iter); diff --git a/tests/arrayvec.rs b/tests/arrayvec.rs index d8c9690..490fd96 100644 --- a/tests/arrayvec.rs +++ b/tests/arrayvec.rs @@ -184,3 +184,169 @@ fn ArrayVec_drain() { assert_eq!(Vec::from_iter(av.clone().drain(1..=1)), vec![2]); assert_eq!(Vec::from_iter(av.clone().drain(1..=2)), vec![2, 3]); } + +#[test] +fn ArrayVec_splice() { + let mut av: ArrayVec<[i32; 10]> = Default::default(); + av.push(1); + av.push(2); + av.push(3); + + // splice returns the same things as drain + assert_eq!(Vec::from_iter(av.clone().splice(.., None)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(av.clone().splice(..2, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(av.clone().splice(..3, None)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(av.clone().splice(..=1, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(av.clone().splice(..=2, None)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(av.clone().splice(0.., None)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(av.clone().splice(1.., None)), vec![2, 3]); + + assert_eq!(Vec::from_iter(av.clone().splice(0..2, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(av.clone().splice(0..3, None)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(av.clone().splice(1..2, None)), vec![2]); + assert_eq!(Vec::from_iter(av.clone().splice(1..3, None)), vec![2, 3]); + + assert_eq!(Vec::from_iter(av.clone().splice(0..=1, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(av.clone().splice(0..=2, None)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(av.clone().splice(1..=1, None)), vec![2]); + assert_eq!(Vec::from_iter(av.clone().splice(1..=2, None)), vec![2, 3]); + + // splice removes the same things as drain + let mut av2 = av.clone(); + av2.splice(.., None); + assert_eq!(av2, array_vec![]); + + let mut av2 = av.clone(); + av2.splice(..2, None); + assert_eq!(av2, array_vec![3]); + + let mut av2 = av.clone(); + av2.splice(..3, None); + assert_eq!(av2, array_vec![]); + + let mut av2 = av.clone(); + av2.splice(..=1, None); + assert_eq!(av2, array_vec![3]); + let mut av2 = av.clone(); + av2.splice(..=2, None); + assert_eq!(av2, array_vec![]); + + let mut av2 = av.clone(); + av2.splice(0.., None); + assert_eq!(av2, array_vec![]); + let mut av2 = av.clone(); + av2.splice(1.., None); + assert_eq!(av2, array_vec![1]); + + let mut av2 = av.clone(); + av2.splice(0..2, None); + assert_eq!(av2, array_vec![3]); + + let mut av2 = av.clone(); + av2.splice(0..3, None); + assert_eq!(av2, array_vec![]); + let mut av2 = av.clone(); + av2.splice(1..2, None); + assert_eq!(av2, array_vec![1, 3]); + + let mut av2 = av.clone(); + av2.splice(1..3, None); + assert_eq!(av2, array_vec![1]); + + let mut av2 = av.clone(); + av2.splice(0..=1, None); + assert_eq!(av2, array_vec![3]); + + let mut av2 = av.clone(); + av2.splice(0..=2, None); + assert_eq!(av2, array_vec![]); + + let mut av2 = av.clone(); + av2.splice(1..=1, None); + assert_eq!(av2, array_vec![1, 3]); + + let mut av2 = av.clone(); + av2.splice(1..=2, None); + assert_eq!(av2, array_vec![1]); + + // splice adds the elements correctly + let mut av2 = av.clone(); + av2.splice(.., 4..=6); + assert_eq!(av2, array_vec![4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(..2, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6, 3]); + + let mut av2 = av.clone(); + av2.splice(..3, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(..=1, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6, 3]); + + let mut av2 = av.clone(); + av2.splice(..=2, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(0.., 4..=6); + assert_eq!(av2, array_vec![4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(1.., 4..=6); + assert_eq!(av2, array_vec![1, 4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(0..2, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6, 3]); + + let mut av2 = av.clone(); + av2.splice(0..3, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(1..2, 4..=6); + assert_eq!(av2, array_vec![1, 4, 5, 6, 3]); + + let mut av2 = av.clone(); + av2.splice(1..3, 4..=6); + assert_eq!(av2, array_vec![1, 4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(0..=1, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6, 3]); + + let mut av2 = av.clone(); + av2.splice(0..=2, 4..=6); + assert_eq!(av2, array_vec![4, 5, 6]); + + let mut av2 = av.clone(); + av2.splice(1..=1, 4..=6); + assert_eq!(av2, array_vec![1, 4, 5, 6, 3]); + + let mut av2 = av.clone(); + av2.splice(1..=2, 4..=6); + assert_eq!(av2, array_vec![1, 4, 5, 6]); + + // splice adds the elements correctly when the replacement is smaller + let mut av2 = av.clone(); + av2.splice(.., Some(4)); + assert_eq!(av2, array_vec![4]); + + let mut av2 = av.clone(); + av2.splice(..2, Some(4)); + assert_eq!(av2, array_vec![4, 3]); + + let mut av2 = av.clone(); + av2.splice(1.., Some(4)); + assert_eq!(av2, array_vec![1, 4]); + + let mut av2 = av.clone(); + av2.splice(1..=1, Some(4)); + assert_eq!(av2, array_vec![1, 4, 3]); +} diff --git a/tests/tinyvec.rs b/tests/tinyvec.rs index 8f48798..9a2b485 100644 --- a/tests/tinyvec.rs +++ b/tests/tinyvec.rs @@ -60,6 +60,172 @@ fn TinyVec_drain() { assert_eq!(Vec::from_iter(tv.clone().drain(1..=2)), vec![2, 3]); } +#[test] +fn TinyVec_splice() { + let mut tv: TinyVec<[i32; 10]> = Default::default(); + tv.push(1); + tv.push(2); + tv.push(3); + + // splice returns the same things as drain + assert_eq!(Vec::from_iter(tv.clone().splice(.., None)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().splice(..2, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(tv.clone().splice(..3, None)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().splice(..=1, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(tv.clone().splice(..=2, None)), vec![1, 2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().splice(0.., None)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(tv.clone().splice(1.., None)), vec![2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().splice(0..2, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(tv.clone().splice(0..3, None)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(tv.clone().splice(1..2, None)), vec![2]); + assert_eq!(Vec::from_iter(tv.clone().splice(1..3, None)), vec![2, 3]); + + assert_eq!(Vec::from_iter(tv.clone().splice(0..=1, None)), vec![1, 2]); + assert_eq!(Vec::from_iter(tv.clone().splice(0..=2, None)), vec![1, 2, 3]); + assert_eq!(Vec::from_iter(tv.clone().splice(1..=1, None)), vec![2]); + assert_eq!(Vec::from_iter(tv.clone().splice(1..=2, None)), vec![2, 3]); + + // splice removes the same things as drain + let mut tv2 = tv.clone(); + tv2.splice(.., None); + assert_eq!(tv2, tiny_vec![]); + + let mut tv2 = tv.clone(); + tv2.splice(..2, None); + assert_eq!(tv2, tiny_vec![3]); + + let mut tv2 = tv.clone(); + tv2.splice(..3, None); + assert_eq!(tv2, tiny_vec![]); + + let mut tv2 = tv.clone(); + tv2.splice(..=1, None); + assert_eq!(tv2, tiny_vec![3]); + let mut tv2 = tv.clone(); + tv2.splice(..=2, None); + assert_eq!(tv2, tiny_vec![]); + + let mut tv2 = tv.clone(); + tv2.splice(0.., None); + assert_eq!(tv2, tiny_vec![]); + let mut tv2 = tv.clone(); + tv2.splice(1.., None); + assert_eq!(tv2, tiny_vec![1]); + + let mut tv2 = tv.clone(); + tv2.splice(0..2, None); + assert_eq!(tv2, tiny_vec![3]); + + let mut tv2 = tv.clone(); + tv2.splice(0..3, None); + assert_eq!(tv2, tiny_vec![]); + let mut tv2 = tv.clone(); + tv2.splice(1..2, None); + assert_eq!(tv2, tiny_vec![1, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(1..3, None); + assert_eq!(tv2, tiny_vec![1]); + + let mut tv2 = tv.clone(); + tv2.splice(0..=1, None); + assert_eq!(tv2, tiny_vec![3]); + + let mut tv2 = tv.clone(); + tv2.splice(0..=2, None); + assert_eq!(tv2, tiny_vec![]); + + let mut tv2 = tv.clone(); + tv2.splice(1..=1, None); + assert_eq!(tv2, tiny_vec![1, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(1..=2, None); + assert_eq!(tv2, tiny_vec![1]); + + // splice adds the elements correctly + let mut tv2 = tv.clone(); + tv2.splice(.., 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(..2, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(..3, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(..=1, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(..=2, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(0.., 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(1.., 4..=6); + assert_eq!(tv2, tiny_vec![1, 4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(0..2, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(0..3, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(1..2, 4..=6); + assert_eq!(tv2, tiny_vec![1, 4, 5, 6, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(1..3, 4..=6); + assert_eq!(tv2, tiny_vec![1, 4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(0..=1, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(0..=2, 4..=6); + assert_eq!(tv2, tiny_vec![4, 5, 6]); + + let mut tv2 = tv.clone(); + tv2.splice(1..=1, 4..=6); + assert_eq!(tv2, tiny_vec![1, 4, 5, 6, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(1..=2, 4..=6); + assert_eq!(tv2, tiny_vec![1, 4, 5, 6]); + + // splice adds the elements correctly when the replacement is smaller + let mut tv2 = tv.clone(); + tv2.splice(.., Some(4)); + assert_eq!(tv2, tiny_vec![4]); + + let mut tv2 = tv.clone(); + tv2.splice(..2, Some(4)); + assert_eq!(tv2, tiny_vec![4, 3]); + + let mut tv2 = tv.clone(); + tv2.splice(1.., Some(4)); + assert_eq!(tv2, tiny_vec![1, 4]); + + let mut tv2 = tv.clone(); + tv2.splice(1..=1, Some(4)); + assert_eq!(tv2, tiny_vec![1, 4, 3]); +} + #[test] fn TinyVec_resize() { let mut tv: TinyVec<[i32; 10]> = Default::default(); @@ -149,6 +315,5 @@ fn TinyVec_move_to_heap_and_shrink() { assert_eq!(tv.capacity(), 4); tv.extend(2..=4); assert_eq!(tv.capacity(), 4); - assert_eq!(tv.as_slice(), [1,2,3,4]); + assert_eq!(tv.as_slice(), [1, 2, 3, 4]); } -