allocator_api2/stable/vec/
splice.rs1use core::ptr::{self};
2use core::slice::{self};
3
4use crate::stable::alloc::{Allocator, Global};
5
6use super::{Drain, Vec};
7
8#[derive(Debug)]
21pub struct Splice<'a, I: Iterator + 'a, A: Allocator + 'a = Global> {
22    pub(super) drain: Drain<'a, I::Item, A>,
23    pub(super) replace_with: I,
24}
25
26impl<I: Iterator, A: Allocator> Iterator for Splice<'_, I, A> {
27    type Item = I::Item;
28
29    #[inline(always)]
30    fn next(&mut self) -> Option<Self::Item> {
31        self.drain.next()
32    }
33
34    #[inline(always)]
35    fn size_hint(&self) -> (usize, Option<usize>) {
36        self.drain.size_hint()
37    }
38}
39
40impl<I: Iterator, A: Allocator> DoubleEndedIterator for Splice<'_, I, A> {
41    #[inline(always)]
42    fn next_back(&mut self) -> Option<Self::Item> {
43        self.drain.next_back()
44    }
45}
46
47impl<I: Iterator, A: Allocator> ExactSizeIterator for Splice<'_, I, A> {}
48
49impl<I: Iterator, A: Allocator> Drop for Splice<'_, I, A> {
50    #[inline]
51    fn drop(&mut self) {
52        self.drain.by_ref().for_each(drop);
53
54        unsafe {
55            if self.drain.tail_len == 0 {
56                self.drain.vec.as_mut().extend(self.replace_with.by_ref());
57                return;
58            }
59
60            if !self.drain.fill(&mut self.replace_with) {
62                return;
63            }
64
65            let (lower_bound, _upper_bound) = self.replace_with.size_hint();
68            if lower_bound > 0 {
69                self.drain.move_tail(lower_bound);
70                if !self.drain.fill(&mut self.replace_with) {
71                    return;
72                }
73            }
74
75            let mut collected = self
78                .replace_with
79                .by_ref()
80                .collect::<Vec<I::Item>>()
81                .into_iter();
82            if collected.len() > 0 {
84                self.drain.move_tail(collected.len());
85                let filled = self.drain.fill(&mut collected);
86                debug_assert!(filled);
87                debug_assert_eq!(collected.len(), 0);
88            }
89        }
90        }
92}
93
94impl<T, A: Allocator> Drain<'_, T, A> {
96    #[inline(always)]
101    unsafe fn fill<I: Iterator<Item = T>>(&mut self, replace_with: &mut I) -> bool {
102        let vec = unsafe { self.vec.as_mut() };
103        let range_start = vec.len;
104        let range_end = self.tail_start;
105        let range_slice = unsafe {
106            slice::from_raw_parts_mut(vec.as_mut_ptr().add(range_start), range_end - range_start)
107        };
108
109        for place in range_slice {
110            if let Some(new_item) = replace_with.next() {
111                unsafe { ptr::write(place, new_item) };
112                vec.len += 1;
113            } else {
114                return false;
115            }
116        }
117        true
118    }
119
120    #[inline(always)]
122    unsafe fn move_tail(&mut self, additional: usize) {
123        let vec = unsafe { self.vec.as_mut() };
124        let len = self.tail_start + self.tail_len;
125        vec.buf.reserve(len, additional);
126
127        let new_tail_start = self.tail_start + additional;
128        unsafe {
129            let src = vec.as_ptr().add(self.tail_start);
130            let dst = vec.as_mut_ptr().add(new_tail_start);
131            ptr::copy(src, dst, self.tail_len);
132        }
133        self.tail_start = new_tail_start;
134    }
135}