@@ -128,10 +128,6 @@ impl Leds {
128
128
}
129
129
}
130
130
131
- pub fn iter ( & self ) -> LedsIterator {
132
- LedsIterator :: new ( self )
133
- }
134
-
135
131
pub fn iter_mut ( & mut self ) -> LedsMutIterator {
136
132
LedsMutIterator :: new ( self )
137
133
}
@@ -154,15 +150,6 @@ impl Leds {
154
150
}
155
151
}
156
152
157
- impl < ' a > IntoIterator for & ' a Leds {
158
- type Item = & ' a Led ;
159
- type IntoIter = LedsIterator < ' a > ;
160
-
161
- fn into_iter ( self ) -> Self :: IntoIter {
162
- self . iter ( )
163
- }
164
- }
165
-
166
153
impl < ' a > IntoIterator for & ' a mut Leds {
167
154
type Item = & ' a mut Led ;
168
155
type IntoIter = LedsMutIterator < ' a > ;
@@ -172,73 +159,21 @@ impl<'a> IntoIterator for &'a mut Leds {
172
159
}
173
160
}
174
161
175
- pub struct LedsIterator < ' a > {
176
- current_index : usize ,
177
- leds : & ' a Leds
178
- }
179
-
180
- impl < ' a > LedsIterator < ' a > {
181
- fn new ( leds : & ' a Leds ) -> Self {
182
- LedsIterator { current_index : 0 , leds }
183
- }
184
-
185
- fn len ( & self ) -> usize {
186
- ITERATOR_SIZE - self . current_index
187
- }
188
-
189
- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
190
- let length = self . len ( ) ;
191
- ( length, Some ( length) )
192
- }
193
- }
194
-
195
- impl < ' a > Iterator for LedsIterator < ' a > {
196
- type Item = & ' a Led ;
197
- fn next ( & mut self ) -> Option < Self :: Item > {
198
- let current = match self . current_index {
199
- 0 => Some ( & self . leds . ld3 ) , //N
200
- 1 => Some ( & self . leds . ld5 ) , //NE
201
- 2 => Some ( & self . leds . ld7 ) , //E
202
- 3 => Some ( & self . leds . ld9 ) , //SE
203
- 4 => Some ( & self . leds . ld10 ) , //S
204
- 5 => Some ( & self . leds . ld8 ) , //SW
205
- 6 => Some ( & self . leds . ld6 ) , //W
206
- 7 => Some ( & self . leds . ld4 ) , //NW
207
- _ => None
208
- } ;
209
- self . current_index += 1 ;
210
- current
211
- }
212
-
213
- // Because we implement ExactSizedIterator, we need to ensure size_hint returns the right length
214
- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
215
- self . size_hint ( )
216
- }
217
- }
218
-
219
162
const ITERATOR_SIZE : usize = 8 ;
220
163
221
- impl < ' a > ExactSizeIterator for LedsIterator < ' a > {
222
- fn len ( & self ) -> usize {
223
- self . len ( )
224
- }
225
- }
226
-
227
- ///Marker trait that indicates LedsIterator never starts returning Some after returning None
228
- impl < ' a > FusedIterator for LedsIterator < ' a > { }
229
-
230
164
pub struct LedsMutIterator < ' a > {
231
- current_index : usize ,
165
+ index : usize ,
166
+ index_back : usize ,
232
167
leds : & ' a mut Leds
233
168
}
234
169
235
170
impl < ' a > LedsMutIterator < ' a > {
236
171
fn new ( leds : & ' a mut Leds ) -> Self {
237
- LedsMutIterator { current_index : 0 , leds }
172
+ LedsMutIterator { index : 0 , index_back : ITERATOR_SIZE , leds }
238
173
}
239
174
240
175
fn len ( & self ) -> usize {
241
- ITERATOR_SIZE - self . current_index
176
+ self . index_back - self . index
242
177
}
243
178
244
179
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
@@ -250,23 +185,28 @@ impl<'a> LedsMutIterator<'a> {
250
185
impl < ' a > Iterator for LedsMutIterator < ' a > {
251
186
type Item = & ' a mut Led ;
252
187
fn next ( & mut self ) -> Option < Self :: Item > {
253
- let current = unsafe {
254
- //Safety: Each branch is only executed once,
255
- // so we can not possibly alias a mutable reference.
256
- match self . current_index {
257
- 0 => Some ( & mut * ( & mut self . leds . ld3 as * mut _ ) ) , //N
258
- 1 => Some ( & mut * ( & mut self . leds . ld5 as * mut _ ) ) , //NE
259
- 2 => Some ( & mut * ( & mut self . leds . ld7 as * mut _ ) ) , //E
260
- 3 => Some ( & mut * ( & mut self . leds . ld9 as * mut _ ) ) , //SE
261
- 4 => Some ( & mut * ( & mut self . leds . ld10 as * mut _ ) ) , //S
262
- 5 => Some ( & mut * ( & mut self . leds . ld8 as * mut _ ) ) , //SW
263
- 6 => Some ( & mut * ( & mut self . leds . ld6 as * mut _ ) ) , //W
264
- 7 => Some ( & mut * ( & mut self . leds . ld4 as * mut _ ) ) , //NW
265
- _ => None
266
- }
267
- } ;
268
- self . current_index += 1 ;
269
- current
188
+ if self . len ( ) == 0 {
189
+ None
190
+ } else {
191
+ let current = unsafe {
192
+ //Safety: Each branch is only executed once,
193
+ // so we can not possibly alias a mutable reference.
194
+ // Oddly, this depends on DoubleSidedIterator also being implemented correctly.
195
+ match self . index {
196
+ 0 => Some ( & mut * ( & mut self . leds . ld3 as * mut _ ) ) , //N
197
+ 1 => Some ( & mut * ( & mut self . leds . ld5 as * mut _ ) ) , //NE
198
+ 2 => Some ( & mut * ( & mut self . leds . ld7 as * mut _ ) ) , //E
199
+ 3 => Some ( & mut * ( & mut self . leds . ld9 as * mut _ ) ) , //SE
200
+ 4 => Some ( & mut * ( & mut self . leds . ld10 as * mut _ ) ) , //S
201
+ 5 => Some ( & mut * ( & mut self . leds . ld8 as * mut _ ) ) , //SW
202
+ 6 => Some ( & mut * ( & mut self . leds . ld6 as * mut _ ) ) , //W
203
+ 7 => Some ( & mut * ( & mut self . leds . ld4 as * mut _ ) ) , //NW
204
+ _ => None
205
+ }
206
+ } ;
207
+ self . index += 1 ;
208
+ current
209
+ }
270
210
}
271
211
272
212
// Because we implement ExactSizedIterator, we need to ensure size_hint returns the right length
@@ -275,9 +215,42 @@ impl<'a> Iterator for LedsMutIterator<'a> {
275
215
}
276
216
}
277
217
218
+ impl < ' a > DoubleEndedIterator for LedsMutIterator < ' a > {
219
+ fn next_back ( & mut self ) -> Option < Self :: Item > {
220
+ if self . len ( ) == 0 {
221
+ None
222
+ } else {
223
+ let current = unsafe {
224
+ //Safety: Each branch is only executed once,
225
+ // and only if there are elements left to be returned,
226
+ // so we can not possibly alias a mutable reference.
227
+ // This depends on Iterator and ExactSizedIterator being implemented correctly.
228
+ // If len() does not return the correct number of remaining elements,
229
+ // this becomes unsound.
230
+ match self . index_back {
231
+ // Because we're going backwards and index_back is a usize,
232
+ // We use a one based index so we don't go negative
233
+ 0 => None , //done
234
+ 1 => Some ( & mut * ( & mut self . leds . ld3 as * mut _ ) ) , //N
235
+ 2 => Some ( & mut * ( & mut self . leds . ld5 as * mut _ ) ) , //NE
236
+ 3 => Some ( & mut * ( & mut self . leds . ld7 as * mut _ ) ) , //E
237
+ 4 => Some ( & mut * ( & mut self . leds . ld9 as * mut _ ) ) , //SE
238
+ 5 => Some ( & mut * ( & mut self . leds . ld10 as * mut _ ) ) , //S
239
+ 6 => Some ( & mut * ( & mut self . leds . ld8 as * mut _ ) ) , //SW
240
+ 7 => Some ( & mut * ( & mut self . leds . ld6 as * mut _ ) ) , //W
241
+ 8 => Some ( & mut * ( & mut self . leds . ld4 as * mut _ ) ) , //NW
242
+ _ => None //can't happen
243
+ }
244
+ } ;
245
+ self . index_back -= 1 ;
246
+ current
247
+ }
248
+ }
249
+ }
250
+
278
251
impl < ' a > ExactSizeIterator for LedsMutIterator < ' a > {
279
252
fn len ( & self ) -> usize {
280
- ITERATOR_SIZE - self . current_index
253
+ self . len ( )
281
254
}
282
255
}
283
256
0 commit comments