@@ -105,10 +105,73 @@ impl<A, B> DoubleEndedIterator for Zip<A, B>
105
105
where
106
106
A : DoubleEndedIterator + ExactSizeIterator ,
107
107
B : DoubleEndedIterator + ExactSizeIterator ,
108
+ {
109
+ #[ inline]
110
+ default fn next_back ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
111
+ let a_sz = self . a . len ( ) ;
112
+ let b_sz = self . b . len ( ) ;
113
+ if a_sz != b_sz {
114
+ // Adjust a, b to equal length
115
+ if a_sz > b_sz {
116
+ for _ in 0 ..a_sz - b_sz {
117
+ self . a . next_back ( ) ;
118
+ }
119
+ } else {
120
+ for _ in 0 ..b_sz - a_sz {
121
+ self . b . next_back ( ) ;
122
+ }
123
+ }
124
+ }
125
+ match ( self . a . next_back ( ) , self . b . next_back ( ) ) {
126
+ ( Some ( x) , Some ( y) ) => Some ( ( x, y) ) ,
127
+ ( None , None ) => None ,
128
+ _ => unreachable ! ( ) ,
129
+ }
130
+ }
131
+ }
132
+
133
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
134
+ impl < A , B > DoubleEndedIterator for Zip < A , B >
135
+ where
136
+ A : TrustedRandomAccess + DoubleEndedIterator + ExactSizeIterator ,
137
+ B : TrustedRandomAccess + DoubleEndedIterator + ExactSizeIterator ,
108
138
{
109
139
#[ inline]
110
140
fn next_back ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
111
- ZipImpl :: next_back ( self )
141
+ let a_side_effect = A :: may_have_side_effect ( ) ;
142
+ let b_side_effect = B :: may_have_side_effect ( ) ;
143
+ if a_side_effect || b_side_effect {
144
+ let sz_a = self . a . size ( ) ;
145
+ let sz_b = self . b . size ( ) ;
146
+ // Adjust a, b to equal length, make sure that only the first call
147
+ // of `next_back` does this, otherwise we will break the restriction
148
+ // on calls to `self.next_back()` after calling `get_unchecked()`.
149
+ if sz_a != sz_b {
150
+ let sz_a = self . a . size ( ) ;
151
+ if a_side_effect && sz_a > self . len {
152
+ for _ in 0 ..sz_a - cmp:: max ( self . len , self . index ) {
153
+ self . a . next_back ( ) ;
154
+ }
155
+ }
156
+ let sz_b = self . b . size ( ) ;
157
+ if b_side_effect && sz_b > self . len {
158
+ for _ in 0 ..sz_b - self . len {
159
+ self . b . next_back ( ) ;
160
+ }
161
+ }
162
+ }
163
+ }
164
+ if self . index < self . len {
165
+ self . len -= 1 ;
166
+ let i = self . len ;
167
+ // SAFETY: `i` is smaller than the previous value of `self.len`,
168
+ // which is also smaller than or equal to `self.a.len()` and `self.b.len()`
169
+ unsafe {
170
+ Some ( ( self . a . __iterator_get_unchecked ( i) , self . b . __iterator_get_unchecked ( i) ) )
171
+ }
172
+ } else {
173
+ None
174
+ }
112
175
}
113
176
}
114
177
@@ -119,10 +182,6 @@ trait ZipImpl<A, B> {
119
182
fn next ( & mut self ) -> Option < Self :: Item > ;
120
183
fn size_hint ( & self ) -> ( usize , Option < usize > ) ;
121
184
fn nth ( & mut self , n : usize ) -> Option < Self :: Item > ;
122
- fn next_back ( & mut self ) -> Option < Self :: Item >
123
- where
124
- A : DoubleEndedIterator + ExactSizeIterator ,
125
- B : DoubleEndedIterator + ExactSizeIterator ;
126
185
// This has the same safety requirements as `Iterator::__iterator_get_unchecked`
127
186
unsafe fn get_unchecked ( & mut self , idx : usize ) -> <Self as Iterator >:: Item
128
187
where
@@ -150,33 +209,6 @@ where
150
209
self . super_nth ( n)
151
210
}
152
211
153
- #[ inline]
154
- default fn next_back ( & mut self ) -> Option < ( A :: Item , B :: Item ) >
155
- where
156
- A : DoubleEndedIterator + ExactSizeIterator ,
157
- B : DoubleEndedIterator + ExactSizeIterator ,
158
- {
159
- let a_sz = self . a . len ( ) ;
160
- let b_sz = self . b . len ( ) ;
161
- if a_sz != b_sz {
162
- // Adjust a, b to equal length
163
- if a_sz > b_sz {
164
- for _ in 0 ..a_sz - b_sz {
165
- self . a . next_back ( ) ;
166
- }
167
- } else {
168
- for _ in 0 ..b_sz - a_sz {
169
- self . b . next_back ( ) ;
170
- }
171
- }
172
- }
173
- match ( self . a . next_back ( ) , self . b . next_back ( ) ) {
174
- ( Some ( x) , Some ( y) ) => Some ( ( x, y) ) ,
175
- ( None , None ) => None ,
176
- _ => unreachable ! ( ) ,
177
- }
178
- }
179
-
180
212
#[ inline]
181
213
default fn size_hint ( & self ) -> ( usize , Option < usize > ) {
182
214
let ( a_lower, a_upper) = self . a . size_hint ( ) ;
@@ -262,48 +294,6 @@ where
262
294
self . super_nth ( n - delta)
263
295
}
264
296
265
- #[ inline]
266
- fn next_back ( & mut self ) -> Option < ( A :: Item , B :: Item ) >
267
- where
268
- A : DoubleEndedIterator + ExactSizeIterator ,
269
- B : DoubleEndedIterator + ExactSizeIterator ,
270
- {
271
- let a_side_effect = A :: may_have_side_effect ( ) ;
272
- let b_side_effect = B :: may_have_side_effect ( ) ;
273
- if a_side_effect || b_side_effect {
274
- let sz_a = self . a . size ( ) ;
275
- let sz_b = self . b . size ( ) ;
276
- // Adjust a, b to equal length, make sure that only the first call
277
- // of `next_back` does this, otherwise we will break the restriction
278
- // on calls to `self.next_back()` after calling `get_unchecked()`.
279
- if sz_a != sz_b {
280
- let sz_a = self . a . size ( ) ;
281
- if a_side_effect && sz_a > self . len {
282
- for _ in 0 ..sz_a - cmp:: max ( self . len , self . index ) {
283
- self . a . next_back ( ) ;
284
- }
285
- }
286
- let sz_b = self . b . size ( ) ;
287
- if b_side_effect && sz_b > self . len {
288
- for _ in 0 ..sz_b - self . len {
289
- self . b . next_back ( ) ;
290
- }
291
- }
292
- }
293
- }
294
- if self . index < self . len {
295
- self . len -= 1 ;
296
- let i = self . len ;
297
- // SAFETY: `i` is smaller than the previous value of `self.len`,
298
- // which is also smaller than or equal to `self.a.len()` and `self.b.len()`
299
- unsafe {
300
- Some ( ( self . a . __iterator_get_unchecked ( i) , self . b . __iterator_get_unchecked ( i) ) )
301
- }
302
- } else {
303
- None
304
- }
305
- }
306
-
307
297
#[ inline]
308
298
unsafe fn get_unchecked ( & mut self , idx : usize ) -> <Self as Iterator >:: Item {
309
299
let idx = self . index + idx;
0 commit comments