Skip to main content

any_vec/ops/
splice.rs

1use crate::any_vec_ptr::IAnyVecRawPtr;
2use crate::{any_vec_ptr, assert_types_equal, Iter};
3use crate::any_value::{AnyValue, AnyValueSizeless};
4use crate::ops::iter::Iterable;
5
6pub struct Splice<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator>
7where
8    ReplaceIter::Item: AnyValue
9{
10    iter: Iter<'a, AnyVecPtr>,
11    start: usize,
12    original_len: usize,
13    replace_with: ReplaceIter
14}
15
16impl<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator>
17    Splice<'a, AnyVecPtr, ReplaceIter>
18where
19    ReplaceIter::Item: AnyValue
20{
21    #[inline]
22    pub fn new(
23        mut any_vec_ptr: AnyVecPtr, start: usize, end: usize,
24        replace_with: ReplaceIter
25    ) -> Self {
26        debug_assert!(start <= end);
27        let any_vec_raw = unsafe{ any_vec_ptr.any_vec_raw_mut() };
28        let original_len = any_vec_raw.len;
29        debug_assert!(end <= original_len);
30
31        // mem::forget and element drop panic "safety".
32        any_vec_raw.len = start;
33
34        Self{
35            iter: Iter::new(any_vec_ptr, start, end),
36            start,
37            original_len,
38            replace_with
39        }
40    }
41}
42
43impl<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator> Iterable
44for
45    Splice<'a, AnyVecPtr, ReplaceIter>
46where
47    ReplaceIter::Item: AnyValue
48{
49    type Iter = Iter<'a, AnyVecPtr>;
50
51    #[inline]
52    fn iter(&self) -> &Self::Iter {
53        &self.iter
54    }
55
56    #[inline]
57    fn iter_mut(&mut self) -> &mut Self::Iter {
58        &mut self.iter
59    }
60}
61
62impl<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator> Drop
63for
64    Splice<'a, AnyVecPtr, ReplaceIter>
65where
66    ReplaceIter::Item: AnyValue
67{
68    fn drop(&mut self) {
69        use any_vec_ptr::utils::*;
70        let mut any_vec_ptr = self.iter.any_vec_ptr;
71
72        let elements_left = self.original_len - self.iter.end;
73        let replace_end = self.start + self.replace_with.len();
74        let new_len = replace_end + elements_left;
75
76        // 0. capacity.
77        {
78            let any_vec_raw = unsafe{any_vec_ptr.any_vec_raw_mut()};
79            any_vec_raw.reserve(new_len);
80        }
81
82        // 1. drop elements.
83        unsafe{
84            drop_elements_range(
85                any_vec_ptr,
86                self.iter.index,
87                self.iter.end
88            );
89        }
90
91        // 2. move elements
92        unsafe{
93            move_elements_at(
94                any_vec_ptr,
95                self.iter.end,
96                replace_end,
97                elements_left
98            );
99        }
100
101        // 3. move replace_with in
102        unsafe{
103            let type_id = element_typeid(any_vec_ptr);
104            let element_size = element_size(any_vec_ptr);
105            let mut ptr = element_mut_ptr_at(any_vec_ptr, self.start);
106            while let Some(replace_element) = self.replace_with.next() {
107                assert_types_equal(type_id, replace_element.value_typeid());
108                replace_element.move_into::<
109                    <ReplaceIter::Item as AnyValueSizeless>::Type
110                >(ptr, element_size);
111                ptr = ptr.add(element_size);
112            }
113        }
114
115        // 4. restore len
116        {
117            let any_vec_raw = unsafe{any_vec_ptr.any_vec_raw_mut()};
118            any_vec_raw.len = new_len;
119        }
120    }
121}