|
2 | 2 | use super::AsVecIntoIter;
|
3 | 3 | use crate::alloc::{Allocator, Global};
|
4 | 4 | use crate::raw_vec::RawVec;
|
| 5 | +use core::array; |
5 | 6 | use core::fmt;
|
6 | 7 | use core::intrinsics::arith_offset;
|
7 | 8 | use core::iter::{
|
8 | 9 | FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccessNoCoerce,
|
9 | 10 | };
|
10 | 11 | use core::marker::PhantomData;
|
11 |
| -use core::mem::{self, ManuallyDrop}; |
| 12 | +use core::mem::{self, ManuallyDrop, MaybeUninit}; |
12 | 13 | #[cfg(not(no_global_oom_handling))]
|
13 | 14 | use core::ops::Deref;
|
14 | 15 | use core::ptr::{self, NonNull};
|
@@ -124,7 +125,6 @@ impl<T, A: Allocator> IntoIter<T, A> {
|
124 | 125 | }
|
125 | 126 |
|
126 | 127 | /// Forgets to Drop the remaining elements while still allowing the backing allocation to be freed.
|
127 |
| - #[cfg(not(no_global_oom_handling))] |
128 | 128 | pub(crate) fn forget_remaining_elements(&mut self) {
|
129 | 129 | self.ptr = self.end;
|
130 | 130 | }
|
@@ -204,6 +204,43 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
|
204 | 204 | self.len()
|
205 | 205 | }
|
206 | 206 |
|
| 207 | + #[inline] |
| 208 | + fn next_chunk<const N: usize>(&mut self) -> Result<[T; N], core::array::IntoIter<T, N>> { |
| 209 | + let mut raw_ary = MaybeUninit::uninit_array(); |
| 210 | + |
| 211 | + let len = self.len(); |
| 212 | + |
| 213 | + if mem::size_of::<T>() == 0 { |
| 214 | + if len < N { |
| 215 | + self.forget_remaining_elements(); |
| 216 | + // Safety: ZSTs can be conjured ex nihilo, only the amount has to be correct |
| 217 | + return Err(unsafe { array::IntoIter::new_unchecked(raw_ary, 0..len) }); |
| 218 | + } |
| 219 | + |
| 220 | + self.ptr = unsafe { arith_offset(self.ptr as *const i8, N as isize) as *mut T }; |
| 221 | + // Safety: ditto |
| 222 | + return Ok(unsafe { MaybeUninit::array_assume_init(raw_ary) }); |
| 223 | + } |
| 224 | + |
| 225 | + if len < N { |
| 226 | + // Safety: `len` indicates that this many elements are available and we just checked that |
| 227 | + // it fits into the array. |
| 228 | + unsafe { |
| 229 | + ptr::copy_nonoverlapping(self.ptr, raw_ary.as_mut_ptr() as *mut T, len); |
| 230 | + self.forget_remaining_elements(); |
| 231 | + return Err(array::IntoIter::new_unchecked(raw_ary, 0..len)); |
| 232 | + } |
| 233 | + } |
| 234 | + |
| 235 | + // Safety: `len` is larger than the array size. Copy a fixed amount here to fully initialize |
| 236 | + // the array. |
| 237 | + return unsafe { |
| 238 | + ptr::copy_nonoverlapping(self.ptr, raw_ary.as_mut_ptr() as *mut T, N); |
| 239 | + self.ptr = self.ptr.add(N); |
| 240 | + Ok(MaybeUninit::array_assume_init(raw_ary)) |
| 241 | + }; |
| 242 | + } |
| 243 | + |
207 | 244 | unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item
|
208 | 245 | where
|
209 | 246 | Self: TrustedRandomAccessNoCoerce,
|
|
0 commit comments