use crate::any_vec_ptr::IAnyVecRawPtr;
use crate::{any_vec_ptr, assert_types_equal, Iter};
use crate::any_value::{AnyValue, AnyValueSizeless};
use crate::ops::iter::Iterable;
pub struct Splice<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator>
where
ReplaceIter::Item: AnyValue
{
iter: Iter<'a, AnyVecPtr>,
start: usize,
original_len: usize,
replace_with: ReplaceIter
}
impl<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator>
Splice<'a, AnyVecPtr, ReplaceIter>
where
ReplaceIter::Item: AnyValue
{
#[inline]
pub fn new(
mut any_vec_ptr: AnyVecPtr, start: usize, end: usize,
replace_with: ReplaceIter
) -> Self {
debug_assert!(start <= end);
let any_vec_raw = unsafe{ any_vec_ptr.any_vec_raw_mut() };
let original_len = any_vec_raw.len;
debug_assert!(end <= original_len);
any_vec_raw.len = start;
Self{
iter: Iter::new(any_vec_ptr, start, end),
start,
original_len,
replace_with
}
}
}
impl<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator> Iterable
for
Splice<'a, AnyVecPtr, ReplaceIter>
where
ReplaceIter::Item: AnyValue
{
type Iter = Iter<'a, AnyVecPtr>;
#[inline]
fn iter(&self) -> &Self::Iter {
&self.iter
}
#[inline]
fn iter_mut(&mut self) -> &mut Self::Iter {
&mut self.iter
}
}
impl<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator> Drop
for
Splice<'a, AnyVecPtr, ReplaceIter>
where
ReplaceIter::Item: AnyValue
{
fn drop(&mut self) {
use any_vec_ptr::utils::*;
let mut any_vec_ptr = self.iter.any_vec_ptr;
let elements_left = self.original_len - self.iter.end;
let replace_end = self.start + self.replace_with.len();
let new_len = replace_end + elements_left;
{
let any_vec_raw = unsafe{any_vec_ptr.any_vec_raw_mut()};
any_vec_raw.reserve(new_len);
}
unsafe{
drop_elements_range(
any_vec_ptr,
self.iter.index,
self.iter.end
);
}
unsafe{
move_elements_at(
any_vec_ptr,
self.iter.end,
replace_end,
elements_left
);
}
unsafe{
let type_id = element_typeid(any_vec_ptr);
let element_size = element_size(any_vec_ptr);
let mut ptr = element_mut_ptr_at(any_vec_ptr, self.start);
while let Some(replace_element) = self.replace_with.next() {
assert_types_equal(type_id, replace_element.value_typeid());
replace_element.move_into::<
<ReplaceIter::Item as AnyValueSizeless>::Type
>(ptr, element_size);
ptr = ptr.add(element_size);
}
}
{
let any_vec_raw = unsafe{any_vec_ptr.any_vec_raw_mut()};
any_vec_raw.len = new_len;
}
}
}