@@ -12,26 +12,29 @@ use std::mem;
12
12
13
13
use crate :: base:: dimension:: { Dim , U1 } ;
14
14
use 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
+ }
16
26
17
27
macro_rules! iterator {
18
28
( 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
-
30
29
// TODO: we need to specialize for the case where the matrix storage is owned (in which
31
30
// 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
+ {
33
34
/// 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 {
35
38
let shape = storage. shape( ) ;
36
39
let strides = storage. strides( ) ;
37
40
let inner_offset = shape. 0 . value( ) * strides. 0 . value( ) ;
@@ -55,7 +58,7 @@ macro_rules! iterator {
55
58
unsafe { ptr. add( inner_offset) }
56
59
} ;
57
60
58
- $Name {
61
+ RawIter {
59
62
ptr,
60
63
inner_ptr: ptr,
61
64
inner_end,
@@ -66,11 +69,13 @@ macro_rules! iterator {
66
69
}
67
70
}
68
71
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;
71
76
72
77
#[ inline]
73
- fn next( & mut self ) -> Option <$Ref > {
78
+ fn next( & mut self ) -> Option <Self :: Item > {
74
79
unsafe {
75
80
if self . size == 0 {
76
81
None
@@ -102,10 +107,7 @@ macro_rules! iterator {
102
107
self . ptr = self . ptr. add( stride) ;
103
108
}
104
109
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)
109
111
}
110
112
}
111
113
}
@@ -121,11 +123,11 @@ macro_rules! iterator {
121
123
}
122
124
}
123
125
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 >
126
128
{
127
129
#[ inline]
128
- fn next_back( & mut self ) -> Option <$Ref > {
130
+ fn next_back( & mut self ) -> Option <Self :: Item > {
129
131
unsafe {
130
132
if self . size == 0 {
131
133
None
@@ -152,24 +154,88 @@ macro_rules! iterator {
152
154
. ptr
153
155
. add( ( outer_remaining * outer_stride + inner_remaining * inner_stride) ) ;
154
156
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)
159
158
}
160
159
}
161
160
}
162
161
}
163
162
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 >
166
165
{
167
166
#[ inline]
168
167
fn len( & self ) -> usize {
169
168
self . size
170
169
}
171
170
}
172
171
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
+
173
239
impl <' a, T , R : Dim , C : Dim , S : ' a + $Storage<T , R , C >> FusedIterator
174
240
for $Name<' a, T , R , C , S >
175
241
{
@@ -180,6 +246,30 @@ macro_rules! iterator {
180
246
iterator ! ( struct MatrixIter for RawStorage . ptr -> * const T , & ' a T , & ' a S , Clone , Debug ) ;
181
247
iterator ! ( struct MatrixIterMut for RawStorageMut . ptr_mut -> * mut T , & ' a mut T , & ' a mut S , Debug ) ;
182
248
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
+
183
273
/*
184
274
*
185
275
* Row iterators.
0 commit comments