@@ -12,26 +12,29 @@ use std::mem;
1212
1313use crate :: base:: dimension:: { Dim , U1 } ;
1414use crate :: base:: storage:: { RawStorage , RawStorageMut } ;
15- use crate :: base:: { Matrix , MatrixView , MatrixViewMut , Scalar } ;
15+ use crate :: base:: { Matrix , MatrixView , MatrixViewMut , Scalar , ViewStorage , ViewStorageMut } ;
16+
17+ #[ derive( Clone , Debug ) ]
18+ struct RawIter < Ptr , T , R : Dim , C : Dim , RStride : Dim , CStride : Dim > {
19+ ptr : Ptr ,
20+ inner_ptr : Ptr ,
21+ inner_end : Ptr ,
22+ size : usize ,
23+ strides : ( RStride , CStride ) ,
24+ _phantoms : PhantomData < ( fn ( ) -> T , R , C ) > ,
25+ }
1626
1727macro_rules! iterator {
1828 ( struct $Name: ident for $Storage: ident. $ptr: ident -> $Ptr: ty, $Ref: ty, $SRef: ty, $( $derives: ident) ,* $( , ) ?) => {
19- /// An iterator through a dense matrix with arbitrary strides matrix.
20- #[ derive( $( $derives) ,* ) ]
21- pub struct $Name<' a, T , R : Dim , C : Dim , S : ' a + $Storage<T , R , C >> {
22- ptr: $Ptr,
23- inner_ptr: $Ptr,
24- inner_end: $Ptr,
25- size: usize , // We can't use an end pointer here because a stride might be zero.
26- strides: ( S :: RStride , S :: CStride ) ,
27- _phantoms: PhantomData <( $Ref, R , C , S ) >,
28- }
29-
3029 // TODO: we need to specialize for the case where the matrix storage is owned (in which
3130 // case the iterator is trivial because it does not have any stride).
32- impl <' a, T , R : Dim , C : Dim , S : ' a + $Storage<T , R , C >> $Name<' a, T , R , C , S > {
31+ impl <T , R : Dim , C : Dim , RStride : Dim , CStride : Dim >
32+ RawIter <$Ptr, T , R , C , RStride , CStride >
33+ {
3334 /// Creates a new iterator for the given matrix storage.
34- pub fn new( storage: $SRef) -> $Name<' a, T , R , C , S > {
35+ fn new<' a, S : $Storage<T , R , C , RStride = RStride , CStride = CStride >>(
36+ storage: $SRef,
37+ ) -> Self {
3538 let shape = storage. shape( ) ;
3639 let strides = storage. strides( ) ;
3740 let inner_offset = shape. 0 . value( ) * strides. 0 . value( ) ;
@@ -55,7 +58,7 @@ macro_rules! iterator {
5558 unsafe { ptr. add( inner_offset) }
5659 } ;
5760
58- $Name {
61+ RawIter {
5962 ptr,
6063 inner_ptr: ptr,
6164 inner_end,
@@ -66,11 +69,13 @@ macro_rules! iterator {
6669 }
6770 }
6871
69- impl <' a, T , R : Dim , C : Dim , S : ' a + $Storage<T , R , C >> Iterator for $Name<' a, T , R , C , S > {
70- type Item = $Ref;
72+ impl <T , R : Dim , C : Dim , RStride : Dim , CStride : Dim > Iterator
73+ for RawIter <$Ptr, T , R , C , RStride , CStride >
74+ {
75+ type Item = $Ptr;
7176
7277 #[ inline]
73- fn next( & mut self ) -> Option <$Ref > {
78+ fn next( & mut self ) -> Option <Self :: Item > {
7479 unsafe {
7580 if self . size == 0 {
7681 None
@@ -102,10 +107,7 @@ macro_rules! iterator {
102107 self . ptr = self . ptr. add( stride) ;
103108 }
104109
105- // We want either `& *last` or `&mut *last` here, depending
106- // on the mutability of `$Ref`.
107- #[ allow( clippy:: transmute_ptr_to_ref) ]
108- Some ( mem:: transmute( old) )
110+ Some ( old)
109111 }
110112 }
111113 }
@@ -121,11 +123,11 @@ macro_rules! iterator {
121123 }
122124 }
123125
124- impl <' a , T , R : Dim , C : Dim , S : ' a + $Storage< T , R , C > > DoubleEndedIterator
125- for $Name< ' a , T , R , C , S >
126+ impl <T , R : Dim , C : Dim , RStride : Dim , CStride : Dim > DoubleEndedIterator
127+ for RawIter <$Ptr , T , R , C , RStride , CStride >
126128 {
127129 #[ inline]
128- fn next_back( & mut self ) -> Option <$Ref > {
130+ fn next_back( & mut self ) -> Option <Self :: Item > {
129131 unsafe {
130132 if self . size == 0 {
131133 None
@@ -152,24 +154,88 @@ macro_rules! iterator {
152154 . ptr
153155 . add( ( outer_remaining * outer_stride + inner_remaining * inner_stride) ) ;
154156
155- // We want either `& *last` or `&mut *last` here, depending
156- // on the mutability of `$Ref`.
157- #[ allow( clippy:: transmute_ptr_to_ref) ]
158- Some ( mem:: transmute( last) )
157+ Some ( last)
159158 }
160159 }
161160 }
162161 }
163162
164- impl <' a , T , R : Dim , C : Dim , S : ' a + $Storage< T , R , C > > ExactSizeIterator
165- for $Name< ' a , T , R , C , S >
163+ impl <T , R : Dim , C : Dim , RStride : Dim , CStride : Dim > ExactSizeIterator
164+ for RawIter <$Ptr , T , R , C , RStride , CStride >
166165 {
167166 #[ inline]
168167 fn len( & self ) -> usize {
169168 self . size
170169 }
171170 }
172171
172+ impl <T , R : Dim , C : Dim , RStride : Dim , CStride : Dim > FusedIterator
173+ for RawIter <$Ptr, T , R , C , RStride , CStride >
174+ {
175+ }
176+
177+ /// An iterator through a dense matrix with arbitrary strides matrix.
178+ #[ derive( $( $derives) ,* ) ]
179+ pub struct $Name<' a, T , R : Dim , C : Dim , S : ' a + $Storage<T , R , C >> {
180+ inner: RawIter <$Ptr, T , R , C , S :: RStride , S :: CStride >,
181+ _marker: PhantomData <$Ref>,
182+ }
183+
184+ impl <' a, T , R : Dim , C : Dim , S : ' a + $Storage<T , R , C >> $Name<' a, T , R , C , S > {
185+ /// Creates a new iterator for the given matrix storage.
186+ pub fn new( storage: $SRef) -> Self {
187+ Self {
188+ inner: RawIter :: <$Ptr, T , R , C , S :: RStride , S :: CStride >:: new( storage) ,
189+ _marker: PhantomData ,
190+ }
191+ }
192+ }
193+
194+ impl <' a, T , R : Dim , C : Dim , S : ' a + $Storage<T , R , C >> Iterator for $Name<' a, T , R , C , S > {
195+ type Item = $Ref;
196+
197+ #[ inline( always) ]
198+ fn next( & mut self ) -> Option <Self :: Item > {
199+ // We want either `& *last` or `&mut *last` here, depending
200+ // on the mutability of `$Ref`.
201+ #[ allow( clippy:: transmute_ptr_to_ref) ]
202+ self . inner. next( ) . map( |ptr| unsafe { mem:: transmute( ptr) } )
203+ }
204+
205+ #[ inline( always) ]
206+ fn size_hint( & self ) -> ( usize , Option <usize >) {
207+ self . inner. size_hint( )
208+ }
209+
210+ #[ inline( always) ]
211+ fn count( self ) -> usize {
212+ self . inner. count( )
213+ }
214+ }
215+
216+ impl <' a, T , R : Dim , C : Dim , S : ' a + $Storage<T , R , C >> DoubleEndedIterator
217+ for $Name<' a, T , R , C , S >
218+ {
219+ #[ inline( always) ]
220+ fn next_back( & mut self ) -> Option <Self :: Item > {
221+ // We want either `& *last` or `&mut *last` here, depending
222+ // on the mutability of `$Ref`.
223+ #[ allow( clippy:: transmute_ptr_to_ref) ]
224+ self . inner
225+ . next_back( )
226+ . map( |ptr| unsafe { mem:: transmute( ptr) } )
227+ }
228+ }
229+
230+ impl <' a, T , R : Dim , C : Dim , S : ' a + $Storage<T , R , C >> ExactSizeIterator
231+ for $Name<' a, T , R , C , S >
232+ {
233+ #[ inline( always) ]
234+ fn len( & self ) -> usize {
235+ self . inner. len( )
236+ }
237+ }
238+
173239 impl <' a, T , R : Dim , C : Dim , S : ' a + $Storage<T , R , C >> FusedIterator
174240 for $Name<' a, T , R , C , S >
175241 {
@@ -180,6 +246,30 @@ macro_rules! iterator {
180246iterator ! ( struct MatrixIter for RawStorage . ptr -> * const T , & ' a T , & ' a S , Clone , Debug ) ;
181247iterator ! ( struct MatrixIterMut for RawStorageMut . ptr_mut -> * mut T , & ' a mut T , & ' a mut S , Debug ) ;
182248
249+ impl < ' a , T , R : Dim , C : Dim , RStride : Dim , CStride : Dim >
250+ MatrixIter < ' a , T , R , C , ViewStorage < ' a , T , R , C , RStride , CStride > >
251+ {
252+ /// Creates a new iterator for the given matrix storage view.
253+ pub fn new_owned ( storage : ViewStorage < ' a , T , R , C , RStride , CStride > ) -> Self {
254+ Self {
255+ inner : RawIter :: < * const T , T , R , C , RStride , CStride > :: new ( & storage) ,
256+ _marker : PhantomData ,
257+ }
258+ }
259+ }
260+
261+ impl < ' a , T , R : Dim , C : Dim , RStride : Dim , CStride : Dim >
262+ MatrixIterMut < ' a , T , R , C , ViewStorageMut < ' a , T , R , C , RStride , CStride > >
263+ {
264+ /// Creates a new iterator for the given matrix storage view.
265+ pub fn new_owned_mut ( mut storage : ViewStorageMut < ' a , T , R , C , RStride , CStride > ) -> Self {
266+ Self {
267+ inner : RawIter :: < * mut T , T , R , C , RStride , CStride > :: new ( & mut storage) ,
268+ _marker : PhantomData ,
269+ }
270+ }
271+ }
272+
183273/*
184274 *
185275 * Row iterators.
0 commit comments