1use core::ptr;
23use super::{Drain, Vec};
4use crate::alloc::{Allocator, Global};
56/// A splicing iterator for `Vec`.
7///
8/// This struct is created by [`Vec::splice()`].
9/// See its documentation for more.
10///
11/// # Example
12///
13/// ```
14/// let mut v = vec![0, 1, 2];
15/// let new = [7, 8];
16/// let iter: std::vec::Splice<'_, _> = v.splice(1.., new);
17/// ```
18#[derive(#[automatically_derived]
#[stable(feature = "vec_splice", since = "1.21.0")]
impl<'a, I: ::core::fmt::Debug + Iterator + 'a, A: ::core::fmt::Debug +
Allocator + 'a> ::core::fmt::Debug for Splice<'a, I, A> where
I::Item: ::core::fmt::Debug {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Splice",
"drain", &self.drain, "replace_with", &&self.replace_with)
}
}Debug)]
19#[stable(feature = "vec_splice", since = "1.21.0")]
20pub struct Splice<
21'a,
22 I: Iterator + 'a,
23#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global,
24> {
25pub(super) drain: Drain<'a, I::Item, A>,
26pub(super) replace_with: I,
27}
2829#[stable(feature = "vec_splice", since = "1.21.0")]
30impl<I: Iterator, A: Allocator> Iteratorfor Splice<'_, I, A> {
31type Item = I::Item;
3233fn next(&mut self) -> Option<Self::Item> {
34self.drain.next()
35 }
3637fn size_hint(&self) -> (usize, Option<usize>) {
38self.drain.size_hint()
39 }
40}
4142#[stable(feature = "vec_splice", since = "1.21.0")]
43impl<I: Iterator, A: Allocator> DoubleEndedIteratorfor Splice<'_, I, A> {
44fn next_back(&mut self) -> Option<Self::Item> {
45self.drain.next_back()
46 }
47}
4849#[stable(feature = "vec_splice", since = "1.21.0")]
50impl<I: Iterator, A: Allocator> ExactSizeIteratorfor Splice<'_, I, A> {}
5152// See also: [`crate::collections::vec_deque::Splice`].
53#[stable(feature = "vec_splice", since = "1.21.0")]
54impl<I: Iterator, A: Allocator> Dropfor Splice<'_, I, A> {
55fn drop(&mut self) {
56self.drain.by_ref().for_each(drop);
57// At this point draining is done and the only remaining tasks are splicing
58 // and moving things into the final place.
59 // Which means we can replace the slice::Iter with pointers that won't point to deallocated
60 // memory, so that Drain::drop is still allowed to call iter.len(), otherwise it would break
61 // the ptr.offset_from_unsigned contract.
62self.drain.iter = [].iter();
6364// ignore-tidy-undocumented-unsafe
65unsafe {
66if self.drain.tail_len == 0 {
67self.drain.vec.as_mut().extend(self.replace_with.by_ref());
68return;
69 }
7071// First fill the range left by drain().
72if !self.drain.fill(&mut self.replace_with) {
73return;
74 }
7576// There may be more elements. Use the lower bound as an estimate.
77 // FIXME: Is the upper bound a better guess? Or something else?
78let (lower_bound, _upper_bound) = self.replace_with.size_hint();
79if lower_bound > 0 {
80self.drain.move_tail(lower_bound);
81if !self.drain.fill(&mut self.replace_with) {
82return;
83 }
84 }
8586// Collect any remaining elements.
87 // This is a zero-length vector which does not allocate if `lower_bound` was exact.
88let mut collected = self.replace_with.by_ref().collect::<Vec<I::Item>>().into_iter();
89// Now we have an exact count.
90if collected.len() > 0 {
91self.drain.move_tail(collected.len());
92let filled = self.drain.fill(&mut collected);
93if true {
if !filled { ::core::panicking::panic("assertion failed: filled") };
};debug_assert!(filled);
94if true {
{
match (&collected.len(), &0) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
};debug_assert_eq!(collected.len(), 0);
95 }
96 }
97// Let `Drain::drop` move the tail back if necessary and restore `vec.len`.
98}
99}
100101/// Private helper methods for `Splice::drop`
102impl<T, A: Allocator> Drain<'_, T, A> {
103/// The range from `self.vec.len` to `self.tail_start` contains elements
104 /// that have been moved out.
105 /// Fill that range as much as possible with new elements from the `replace_with` iterator.
106 /// Returns `true` if we filled the entire range. (`replace_with.next()` didn’t return `None`.)
107unsafe fn fill<I: Iterator<Item = T>>(&mut self, replace_with: &mut I) -> bool {
108// SAFETY: Pointer is valid.
109let vec = unsafe { self.vec.as_mut() };
110let range_start = vec.len;
111let range_end = self.tail_start;
112// The elements in this range are not initialized so we avoid creating a slice.
113114for idx in range_start..range_end {
115let Some(new_item) = replace_with.next() else {
116return false;
117 };
118// ignore-tidy-undocumented-unsafe
119unsafe { vec.as_mut_ptr().add(idx).write(new_item) };
120 vec.len += 1;
121 }
122true
123}
124125/// Makes room for inserting more elements before the tail.
126unsafe fn move_tail(&mut self, additional: usize) {
127// SAFETY: Pointer is valid.
128let vec = unsafe { self.vec.as_mut() };
129let len = self.tail_start + self.tail_len;
130vec.buf.reserve(len, additional);
131132let new_tail_start = self.tail_start + additional;
133// ignore-tidy-undocumented-unsafe
134unsafe {
135let src = vec.as_ptr().add(self.tail_start);
136let dst = vec.as_mut_ptr().add(new_tail_start);
137 ptr::copy(src, dst, self.tail_len);
138 }
139self.tail_start = new_tail_start;
140 }
141}