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