alloc/collections/vec_deque/
spec_extend.rs1use core::iter::{Copied, Rev, TrustedLen};
2use core::slice;
3
4use super::{Drain, VecDeque};
5use crate::alloc::Allocator;
6#[cfg(not(test))]
7use crate::vec;
8
9pub(super) trait SpecExtend<T, I> {
11 fn spec_extend(&mut self, iter: I);
12}
13
14impl<T, I, A: Allocator> SpecExtend<T, I> for VecDeque<T, A>
15where
16 I: Iterator<Item = T>,
17{
18 default fn spec_extend(&mut self, mut iter: I) {
19 while let Some(element) = iter.next() {
26 let (lower, _) = iter.size_hint();
27 self.reserve(lower.saturating_add(1));
28
29 unsafe { self.push_unchecked(element) };
31
32 while self.len < self.capacity() {
34 let Some(element) = iter.next() else {
35 return;
36 };
37 unsafe { self.push_unchecked(element) };
39 }
40 }
41 }
42}
43
44impl<T, I, A: Allocator> SpecExtend<T, I> for VecDeque<T, A>
45where
46 I: TrustedLen<Item = T>,
47{
48 default fn spec_extend(&mut self, iter: I) {
49 let (low, high) = iter.size_hint();
51 if let Some(additional) = high {
52 if true {
{
match (&low, &additional) {
(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::Some(format_args!("TrustedLen iterator\'s size hint is not exact: {0:?}",
(low, high))));
}
}
}
};
};debug_assert_eq!(
53 low,
54 additional,
55 "TrustedLen iterator's size hint is not exact: {:?}",
56 (low, high)
57 );
58 self.reserve(additional);
59
60 let written = unsafe {
62 self.write_iter_wrapping(self.to_wrapped_index(self.len), iter, additional)
63 };
64
65 if true {
{
match (&additional, &written) {
(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::Some(format_args!("The number of items written to VecDeque doesn\'t match the TrustedLen size hint")));
}
}
}
};
};debug_assert_eq!(
66 additional, written,
67 "The number of items written to VecDeque doesn't match the TrustedLen size hint"
68 );
69 } else {
70 { ::core::panicking::panic_fmt(format_args!("capacity overflow")); };panic!("capacity overflow");
76 }
77 }
78}
79
80#[cfg(not(test))]
81impl<T, A1: Allocator, A2: Allocator> SpecExtend<T, vec::IntoIter<T, A2>> for VecDeque<T, A1> {
82 fn spec_extend(&mut self, iterator: vec::IntoIter<T, A2>) {
83 let slice = iterator.as_slice();
84 self.reserve(slice.len());
85
86 unsafe {
88 self.copy_slice(self.to_wrapped_index(self.len), slice);
89 self.len += slice.len();
90 }
91 iterator.forget_remaining_elements_and_dealloc();
92 }
93}
94
95impl<'a, T: 'a, I, A: Allocator> SpecExtend<&'a T, I> for VecDeque<T, A>
96where
97 I: Iterator<Item = &'a T>,
98 T: Copy,
99{
100 default fn spec_extend(&mut self, iterator: I) {
101 self.spec_extend(iterator.copied())
102 }
103}
104
105impl<'a, T: 'a, A: Allocator> SpecExtend<&'a T, slice::Iter<'a, T>> for VecDeque<T, A>
106where
107 T: Copy,
108{
109 fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) {
110 let slice = iterator.as_slice();
111 self.reserve(slice.len());
112
113 unsafe {
115 self.copy_slice(self.to_wrapped_index(self.len), slice);
116 self.len += slice.len();
117 }
118 }
119}
120
121pub(super) trait SpecExtendFront<T, I> {
123 #[track_caller]
124 fn spec_extend_front(&mut self, iter: I);
125}
126
127impl<T, I, A: Allocator> SpecExtendFront<T, I> for VecDeque<T, A>
128where
129 I: Iterator<Item = T>,
130{
131 #[track_caller]
132 default fn spec_extend_front(&mut self, mut iter: I) {
133 while let Some(element) = iter.next() {
140 let (lower, _) = iter.size_hint();
141 self.reserve(lower.saturating_add(1));
142
143 unsafe { self.push_front_unchecked(element) };
145
146 while self.len < self.capacity() {
148 let Some(element) = iter.next() else {
149 return;
150 };
151 unsafe { self.push_front_unchecked(element) };
153 }
154 }
155 }
156}
157
158#[cfg(not(test))]
159impl<T, A1: Allocator, A2: Allocator> SpecExtendFront<T, vec::IntoIter<T, A2>> for VecDeque<T, A1> {
160 #[track_caller]
161 fn spec_extend_front(&mut self, iterator: vec::IntoIter<T, A2>) {
162 let slice = iterator.as_slice();
163 self.reserve(slice.len());
164 unsafe { prepend_reversed(self, slice) };
166 iterator.forget_remaining_elements_and_dealloc();
167 }
168}
169
170#[cfg(not(test))]
171impl<T, A1: Allocator, A2: Allocator> SpecExtendFront<T, Rev<vec::IntoIter<T, A2>>>
172 for VecDeque<T, A1>
173{
174 #[track_caller]
175 fn spec_extend_front(&mut self, iterator: Rev<vec::IntoIter<T, A2>>) {
176 let iterator = iterator.into_inner();
177 let slice = iterator.as_slice();
178 self.reserve(slice.len());
179 unsafe { prepend(self, slice) };
181 iterator.forget_remaining_elements_and_dealloc();
182 }
183}
184
185impl<'a, T, A: Allocator> SpecExtendFront<T, Copied<slice::Iter<'a, T>>> for VecDeque<T, A>
186where
187 Copied<slice::Iter<'a, T>>: Iterator<Item = T>,
188{
189 #[track_caller]
190 fn spec_extend_front(&mut self, iter: Copied<slice::Iter<'a, T>>) {
191 let slice = iter.into_inner().as_slice();
192 self.reserve(slice.len());
193 unsafe { prepend_reversed(self, slice) };
195 }
196}
197
198impl<'a, T, A: Allocator> SpecExtendFront<T, Rev<Copied<slice::Iter<'a, T>>>> for VecDeque<T, A>
199where
200 Rev<Copied<slice::Iter<'a, T>>>: Iterator<Item = T>,
201{
202 #[track_caller]
203 fn spec_extend_front(&mut self, iter: Rev<Copied<slice::Iter<'a, T>>>) {
204 let slice = iter.into_inner().into_inner().as_slice();
205 self.reserve(slice.len());
206 unsafe { prepend(self, slice) };
208 }
209}
210
211impl<'a, T, A1: Allocator, A2: Allocator> SpecExtendFront<T, Drain<'a, T, A2>> for VecDeque<T, A1> {
212 #[track_caller]
213 fn spec_extend_front(&mut self, mut iter: Drain<'a, T, A2>) {
214 if iter.remaining == 0 {
215 return;
216 }
217
218 self.reserve(iter.remaining);
219
220 let (left, right) = unsafe { iter.as_slices() };
222 unsafe {
226 prepend_reversed(self, &*left);
227 prepend_reversed(self, &*right)
228 };
229
230 iter.idx += iter.remaining;
231 iter.remaining = 0;
232 }
233}
234
235impl<'a, T, A1: Allocator, A2: Allocator> SpecExtendFront<T, Rev<Drain<'a, T, A2>>>
236 for VecDeque<T, A1>
237{
238 #[track_caller]
239 fn spec_extend_front(&mut self, iter: Rev<Drain<'a, T, A2>>) {
240 let mut iter = iter.into_inner();
241
242 if iter.remaining == 0 {
243 return;
244 }
245
246 self.reserve(iter.remaining);
247
248 let (left, right) = unsafe { iter.as_slices() };
250 unsafe {
254 prepend(self, &*right);
255 prepend(self, &*left);
256 }
257
258 iter.idx += iter.remaining;
259 iter.remaining = 0;
260 }
261}
262
263unsafe fn prepend<T, A: Allocator>(deque: &mut VecDeque<T, A>, slice: &[T]) {
270 unsafe {
272 deque.head = deque.wrap_sub(deque.head, slice.len());
273 deque.copy_slice(deque.head, slice);
274 deque.len += slice.len();
275 }
276}
277
278unsafe fn prepend_reversed<T, A: Allocator>(deque: &mut VecDeque<T, A>, slice: &[T]) {
285 unsafe {
287 deque.head = deque.wrap_sub(deque.head, slice.len());
288 deque.copy_slice_reversed(deque.head, slice);
289 deque.len += slice.len();
290 }
291}