On 12.09.24 00:52, Danilo Krummrich wrote: > Implement `IntoIterator` for `Vec`, `Vec`'s `IntoIter` type, as well as > `Iterator` for `IntoIter`. > > `Vec::into_iter` disassembles the `Vec` into its raw parts; additionally, > `IntoIter` keeps track of a separate pointer, which is incremented > correspondingsly as the iterator advances, while the length, or the count > of elements, is decremented. > > This also means that `IntoIter` takes the ownership of the backing > buffer and is responsible to drop the remaining elements and free the > backing buffer, if it's dropped. > > Reviewed-by: Alice Ryhl <aliceryhl@xxxxxxxxxx> > Signed-off-by: Danilo Krummrich <dakr@xxxxxxxxxx> > --- > rust/kernel/alloc.rs | 1 + > rust/kernel/alloc/kvec.rs | 181 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 182 insertions(+) One comment below, with that fixed: Reviewed-by: Benno Lossin <benno.lossin@xxxxxxxxx> --- Cheers, Benno > +impl<T, A> IntoIterator for Vec<T, A> > +where > + A: Allocator, > +{ > + type Item = T; > + type IntoIter = IntoIter<T, A>; > + > + /// Consumes the `Vec<T, A>` and creates an `Iterator`, which moves each value out of the > + /// vector (from start to end). > + /// > + /// # Examples > + /// > + /// ``` > + /// let v = kernel::kvec![1, 2]?; > + /// let mut v_iter = v.into_iter(); > + /// > + /// let first_element: Option<u32> = v_iter.next(); > + /// > + /// assert_eq!(first_element, Some(1)); > + /// assert_eq!(v_iter.next(), Some(2)); > + /// assert_eq!(v_iter.next(), None); > + /// > + /// # Ok::<(), Error>(()) > + /// ``` > + /// > + /// ``` > + /// let v = kernel::kvec![]; > + /// let mut v_iter = v.into_iter(); > + /// > + /// let first_element: Option<u32> = v_iter.next(); > + /// > + /// assert_eq!(first_element, None); > + /// > + /// # Ok::<(), Error>(()) > + /// ``` > + #[inline] > + fn into_iter(self) -> Self::IntoIter { > + let (ptr, len, cap) = self.into_raw_parts(); > + > + IntoIter { > + ptr, > + // SAFETY: `ptr` is either a dangling pointer or a pointer to a valid memory > + // allocation, allocated with `A`. > + buf: unsafe { NonNull::new_unchecked(ptr) }, Instead of this `unsafe` call, you can do let buf = self.ptr; Before the call to `into_raw_parts`. > + len, > + cap, > + _p: PhantomData::<A>, > + } > + } > +} > -- > 2.46.0 >