@@ -14,6 +14,7 @@ use core::{
1414 ops:: DerefMut ,
1515 ops:: Index ,
1616 ops:: IndexMut ,
17+ ptr,
1718 ptr:: NonNull ,
1819 slice,
1920 slice:: SliceIndex ,
@@ -636,3 +637,183 @@ impl_slice_eq! { [A: Allocator] Vec<T, A>, [U] }
636637impl_slice_eq ! { [ A : Allocator ] [ T ] , Vec <U , A > }
637638impl_slice_eq ! { [ A : Allocator , const N : usize ] Vec <T , A >, [ U ; N ] }
638639impl_slice_eq ! { [ A : Allocator , const N : usize ] Vec <T , A >, & [ U ; N ] }
640+
641+ impl < ' a , T , A > IntoIterator for & ' a Vec < T , A >
642+ where
643+ A : Allocator ,
644+ {
645+ type Item = & ' a T ;
646+ type IntoIter = slice:: Iter < ' a , T > ;
647+
648+ fn into_iter ( self ) -> Self :: IntoIter {
649+ self . iter ( )
650+ }
651+ }
652+
653+ impl < ' a , T , A : Allocator > IntoIterator for & ' a mut Vec < T , A >
654+ where
655+ A : Allocator ,
656+ {
657+ type Item = & ' a mut T ;
658+ type IntoIter = slice:: IterMut < ' a , T > ;
659+
660+ fn into_iter ( self ) -> Self :: IntoIter {
661+ self . iter_mut ( )
662+ }
663+ }
664+
665+ /// An [`Iterator`] implementation for [`Vec`] that moves elements out of a vector.
666+ ///
667+ /// This structure is created by the [`Vec::into_iter`] method on [`Vec`] (provided by the
668+ /// [`IntoIterator`] trait).
669+ ///
670+ /// # Examples
671+ ///
672+ /// ```
673+ /// let v = kernel::kvec![0, 1, 2]?;
674+ /// let iter = v.into_iter();
675+ ///
676+ /// # Ok::<(), Error>(())
677+ /// ```
678+ pub struct IntoIter < T , A : Allocator > {
679+ ptr : * mut T ,
680+ buf : NonNull < T > ,
681+ len : usize ,
682+ cap : usize ,
683+ _p : PhantomData < A > ,
684+ }
685+
686+ impl < T , A > IntoIter < T , A >
687+ where
688+ A : Allocator ,
689+ {
690+ fn as_raw_mut_slice ( & mut self ) -> * mut [ T ] {
691+ ptr:: slice_from_raw_parts_mut ( self . ptr , self . len )
692+ }
693+ }
694+
695+ impl < T , A > Iterator for IntoIter < T , A >
696+ where
697+ A : Allocator ,
698+ {
699+ type Item = T ;
700+
701+ /// # Examples
702+ ///
703+ /// ```
704+ /// let v = kernel::kvec![1, 2, 3]?;
705+ /// let mut it = v.into_iter();
706+ ///
707+ /// assert_eq!(it.next(), Some(1));
708+ /// assert_eq!(it.next(), Some(2));
709+ /// assert_eq!(it.next(), Some(3));
710+ /// assert_eq!(it.next(), None);
711+ ///
712+ /// # Ok::<(), Error>(())
713+ /// ```
714+ fn next ( & mut self ) -> Option < T > {
715+ if self . len == 0 {
716+ return None ;
717+ }
718+
719+ let current = self . ptr ;
720+
721+ // SAFETY: We can't overflow; decreasing `self.len` by one every time we advance `self.ptr`
722+ // by one guarantees that.
723+ unsafe { self . ptr = self . ptr . add ( 1 ) } ;
724+
725+ self . len -= 1 ;
726+
727+ // SAFETY: `current` is guaranteed to point at a valid element within the buffer.
728+ Some ( unsafe { current. read ( ) } )
729+ }
730+
731+ /// # Examples
732+ ///
733+ /// ```
734+ /// let v: KVec<u32> = kernel::kvec![1, 2, 3]?;
735+ /// let mut iter = v.into_iter();
736+ /// let size = iter.size_hint().0;
737+ ///
738+ /// iter.next();
739+ /// assert_eq!(iter.size_hint().0, size - 1);
740+ ///
741+ /// iter.next();
742+ /// assert_eq!(iter.size_hint().0, size - 2);
743+ ///
744+ /// iter.next();
745+ /// assert_eq!(iter.size_hint().0, size - 3);
746+ ///
747+ /// # Ok::<(), Error>(())
748+ /// ```
749+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
750+ ( self . len , Some ( self . len ) )
751+ }
752+ }
753+
754+ impl < T , A > Drop for IntoIter < T , A >
755+ where
756+ A : Allocator ,
757+ {
758+ fn drop ( & mut self ) {
759+ // SAFETY: The pointer in `self.0` is guaranteed to be valid by the type invariant.
760+ unsafe { ptr:: drop_in_place ( self . as_raw_mut_slice ( ) ) } ;
761+
762+ // If `cap == 0` we never allocated any memory in the first place.
763+ if self . cap != 0 {
764+ // SAFETY: `self.buf` was previously allocated with `A`.
765+ unsafe { A :: free ( self . buf . cast ( ) ) } ;
766+ }
767+ }
768+ }
769+
770+ impl < T , A > IntoIterator for Vec < T , A >
771+ where
772+ A : Allocator ,
773+ {
774+ type Item = T ;
775+ type IntoIter = IntoIter < T , A > ;
776+
777+ /// Consumes the `Vec<T, A>` and creates an `Iterator`, which moves each value out of the
778+ /// vector (from start to end).
779+ ///
780+ /// # Examples
781+ ///
782+ /// ```
783+ /// let v = kernel::kvec![1, 2]?;
784+ /// let mut v_iter = v.into_iter();
785+ ///
786+ /// let first_element: Option<u32> = v_iter.next();
787+ ///
788+ /// assert_eq!(first_element, Some(1));
789+ /// assert_eq!(v_iter.next(), Some(2));
790+ /// assert_eq!(v_iter.next(), None);
791+ ///
792+ /// # Ok::<(), Error>(())
793+ /// ```
794+ ///
795+ /// ```
796+ /// let v = kernel::kvec![];
797+ /// let mut v_iter = v.into_iter();
798+ ///
799+ /// let first_element: Option<u32> = v_iter.next();
800+ ///
801+ /// assert_eq!(first_element, None);
802+ ///
803+ /// # Ok::<(), Error>(())
804+ /// ```
805+ #[ inline]
806+ fn into_iter ( self ) -> Self :: IntoIter {
807+ let ( ptr, len, cap) = self . into_raw_parts ( ) ;
808+
809+ IntoIter {
810+ ptr,
811+ // SAFETY: `ptr` is either a dangling pointer or a pointer to a valid memory
812+ // allocation, allocated with `A`.
813+ buf : unsafe { NonNull :: new_unchecked ( ptr) } ,
814+ len,
815+ cap,
816+ _p : PhantomData :: < A > ,
817+ }
818+ }
819+ }
0 commit comments