rune_alloc/vec/
into_iter.rs1use core::fmt;
2use core::iter::FusedIterator;
3use core::marker::PhantomData;
4use core::mem::{self, ManuallyDrop};
5use core::slice::{self};
6
7use crate::alloc::SizedTypeProperties;
8use crate::alloc::{Allocator, Global};
9use crate::ptr::{self, NonNull};
10use crate::raw_vec::RawVec;
11
12pub struct IntoIter<T, A: Allocator = Global> {
24 pub(super) buf: NonNull<T>,
25 pub(super) phantom: PhantomData<T>,
26 pub(super) cap: usize,
27 pub(super) alloc: ManuallyDrop<A>,
30 pub(super) ptr: *const T,
31 pub(super) end: *const T, }
35
36impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
39 }
40}
41
42impl<T, A: Allocator> IntoIter<T, A> {
43 pub fn as_slice(&self) -> &[T] {
55 unsafe { slice::from_raw_parts(self.ptr, self.len()) }
56 }
57
58 pub fn as_mut_slice(&mut self) -> &mut [T] {
72 unsafe { &mut *self.as_raw_mut_slice() }
73 }
74
75 #[inline]
77 pub fn allocator(&self) -> &A {
78 &self.alloc
79 }
80
81 fn as_raw_mut_slice(&mut self) -> *mut [T] {
82 ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len())
83 }
84
85 #[cfg(rune_nightly)]
87 pub(crate) fn forget_remaining_elements(&mut self) {
88 self.end = self.ptr;
91 }
92}
93
94impl<T, A: Allocator> AsRef<[T]> for IntoIter<T, A> {
95 fn as_ref(&self) -> &[T] {
96 self.as_slice()
97 }
98}
99
100unsafe impl<T: Send, A: Allocator + Send> Send for IntoIter<T, A> {}
101unsafe impl<T: Sync, A: Allocator + Sync> Sync for IntoIter<T, A> {}
102
103impl<T, A: Allocator> Iterator for IntoIter<T, A> {
104 type Item = T;
105
106 #[inline]
107 fn next(&mut self) -> Option<T> {
108 if self.ptr == self.end {
109 None
110 } else if T::IS_ZST {
111 self.end = self.end.wrapping_byte_sub(1);
114
115 Some(unsafe { mem::zeroed() })
117 } else {
118 let old = self.ptr;
119 self.ptr = unsafe { self.ptr.add(1) };
120
121 Some(unsafe { ptr::read(old) })
122 }
123 }
124
125 #[inline]
126 fn size_hint(&self) -> (usize, Option<usize>) {
127 let exact = if T::IS_ZST {
128 self.end.addr().wrapping_sub(self.ptr.addr())
129 } else {
130 unsafe { self.end.offset_from_unsigned(self.ptr) }
131 };
132 (exact, Some(exact))
133 }
134
135 #[inline]
136 fn count(self) -> usize {
137 self.len()
138 }
139}
140
141impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
142 #[inline]
143 fn next_back(&mut self) -> Option<T> {
144 if self.end == self.ptr {
145 None
146 } else if T::IS_ZST {
147 self.end = self.end.wrapping_byte_sub(1);
149
150 Some(unsafe { mem::zeroed() })
152 } else {
153 self.end = unsafe { self.end.sub(1) };
154
155 Some(unsafe { ptr::read(self.end) })
156 }
157 }
158}
159
160impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {}
161
162impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
163
164impl<T, A> Default for IntoIter<T, A>
165where
166 A: Allocator + Default,
167{
168 fn default() -> Self {
177 super::Vec::new_in(Default::default()).into_iter()
178 }
179}
180
181#[cfg(rune_nightly)]
182unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter<T, A> {
183 fn drop(&mut self) {
184 struct DropGuard<'a, T, A: Allocator>(&'a mut IntoIter<T, A>);
185
186 impl<T, A: Allocator> Drop for DropGuard<'_, T, A> {
187 fn drop(&mut self) {
188 unsafe {
189 let alloc = ManuallyDrop::take(&mut self.0.alloc);
191 let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc);
193 }
194 }
195 }
196
197 let guard = DropGuard(self);
198 unsafe {
200 ptr::drop_in_place(guard.0.as_raw_mut_slice());
201 }
202 }
204}
205
206#[cfg(not(rune_nightly))]
207impl<T, A: Allocator> Drop for IntoIter<T, A> {
208 fn drop(&mut self) {
209 struct DropGuard<'a, T, A: Allocator>(&'a mut IntoIter<T, A>);
210
211 impl<T, A: Allocator> Drop for DropGuard<'_, T, A> {
212 fn drop(&mut self) {
213 unsafe {
214 let alloc = ManuallyDrop::take(&mut self.0.alloc);
216 let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc);
218 }
219 }
220 }
221
222 let guard = DropGuard(self);
223 unsafe {
225 ptr::drop_in_place(guard.0.as_raw_mut_slice());
226 }
227 }
229}