@@ -17,93 +17,33 @@ pub struct Zip<A, B> {
17
17
index : usize ,
18
18
len : usize ,
19
19
}
20
- impl < A : Iterator , B : Iterator > Zip < A , B > {
21
- pub ( in crate :: iter) fn new ( a : A , b : B ) -> Zip < A , B > {
22
- ZipImpl :: new ( a, b)
23
- }
24
- fn super_nth ( & mut self , mut n : usize ) -> Option < ( A :: Item , B :: Item ) > {
25
- while let Some ( x) = Iterator :: next ( self ) {
26
- if n == 0 {
27
- return Some ( x) ;
28
- }
29
- n -= 1 ;
30
- }
31
- None
32
- }
33
- }
34
20
35
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
36
- impl < A , B > Iterator for Zip < A , B >
21
+ impl < A , B > Zip < A , B >
37
22
where
38
23
A : Iterator ,
39
24
B : Iterator ,
40
25
{
41
- type Item = ( A :: Item , B :: Item ) ;
42
-
43
- #[ inline]
44
- fn next ( & mut self ) -> Option < Self :: Item > {
45
- ZipImpl :: next ( self )
46
- }
47
-
48
- #[ inline]
49
- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
50
- ZipImpl :: size_hint ( self )
51
- }
52
-
53
- #[ inline]
54
- fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
55
- ZipImpl :: nth ( self , n)
56
- }
57
-
58
- #[ inline]
59
- unsafe fn __iterator_get_unchecked ( & mut self , idx : usize ) -> Self :: Item
60
- where
61
- Self : TrustedRandomAccess ,
62
- {
63
- // SAFETY: `ZipImpl::__iterator_get_unchecked` has same safety
64
- // requirements as `Iterator::__iterator_get_unchecked`.
65
- unsafe { ZipImpl :: get_unchecked ( self , idx) }
26
+ pub ( in crate :: iter) fn new ( a : A , b : B ) -> Zip < A , B > {
27
+ ZipNew :: new ( a, b)
66
28
}
67
- }
68
29
69
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
70
- impl < A , B > DoubleEndedIterator for Zip < A , B >
71
- where
72
- A : DoubleEndedIterator + ExactSizeIterator ,
73
- B : DoubleEndedIterator + ExactSizeIterator ,
74
- {
75
- #[ inline]
76
- fn next_back ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
77
- ZipImpl :: next_back ( self )
30
+ fn super_nth ( & mut self , n : usize ) -> Option < ( A :: Item , B :: Item ) > {
31
+ self . advance_by ( n) . ok ( ) ?;
32
+ self . next ( )
78
33
}
79
34
}
80
35
81
- // Zip specialization trait
82
36
#[ doc( hidden) ]
83
- trait ZipImpl < A , B > {
84
- type Item ;
37
+ trait ZipNew < A , B > {
85
38
fn new ( a : A , b : B ) -> Self ;
86
- fn next ( & mut self ) -> Option < Self :: Item > ;
87
- fn size_hint ( & self ) -> ( usize , Option < usize > ) ;
88
- fn nth ( & mut self , n : usize ) -> Option < Self :: Item > ;
89
- fn next_back ( & mut self ) -> Option < Self :: Item >
90
- where
91
- A : DoubleEndedIterator + ExactSizeIterator ,
92
- B : DoubleEndedIterator + ExactSizeIterator ;
93
- // This has the same safety requirements as `Iterator::__iterator_get_unchecked`
94
- unsafe fn get_unchecked ( & mut self , idx : usize ) -> <Self as Iterator >:: Item
95
- where
96
- Self : Iterator + TrustedRandomAccess ;
97
39
}
98
40
99
- // General Zip impl
100
41
#[ doc( hidden) ]
101
- impl < A , B > ZipImpl < A , B > for Zip < A , B >
42
+ impl < A , B > ZipNew < A , B > for Zip < A , B >
102
43
where
103
44
A : Iterator ,
104
45
B : Iterator ,
105
46
{
106
- type Item = ( A :: Item , B :: Item ) ;
107
47
default fn new ( a : A , b : B ) -> Self {
108
48
Zip {
109
49
a,
@@ -112,25 +52,28 @@ where
112
52
len : 0 , // unused
113
53
}
114
54
}
55
+ }
115
56
116
- #[ inline]
117
- default fn next ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
118
- let x = self . a . next ( ) ?;
119
- let y = self . b . next ( ) ?;
120
- Some ( ( x, y) )
121
- }
122
-
123
- #[ inline]
124
- default fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
125
- self . super_nth ( n)
57
+ #[ doc( hidden) ]
58
+ impl < A , B > ZipNew < A , B > for Zip < A , B >
59
+ where
60
+ A : TrustedRandomAccess + Iterator ,
61
+ B : TrustedRandomAccess + Iterator ,
62
+ {
63
+ fn new ( a : A , b : B ) -> Self {
64
+ let len = cmp:: min ( a. size ( ) , b. size ( ) ) ;
65
+ Zip { a, b, index : 0 , len }
126
66
}
67
+ }
127
68
69
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
70
+ impl < A , B > DoubleEndedIterator for Zip < A , B >
71
+ where
72
+ A : DoubleEndedIterator + ExactSizeIterator ,
73
+ B : DoubleEndedIterator + ExactSizeIterator ,
74
+ {
128
75
#[ inline]
129
- default fn next_back ( & mut self ) -> Option < ( A :: Item , B :: Item ) >
130
- where
131
- A : DoubleEndedIterator + ExactSizeIterator ,
132
- B : DoubleEndedIterator + ExactSizeIterator ,
133
- {
76
+ default fn next_back ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
134
77
let a_sz = self . a . len ( ) ;
135
78
let b_sz = self . b . len ( ) ;
136
79
if a_sz != b_sz {
@@ -151,6 +94,71 @@ where
151
94
_ => unreachable ! ( ) ,
152
95
}
153
96
}
97
+ }
98
+
99
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
100
+ impl < A , B > DoubleEndedIterator for Zip < A , B >
101
+ where
102
+ A : TrustedRandomAccess + DoubleEndedIterator + ExactSizeIterator ,
103
+ B : TrustedRandomAccess + DoubleEndedIterator + ExactSizeIterator ,
104
+ {
105
+ #[ inline]
106
+ fn next_back ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
107
+ let a_side_effect = A :: may_have_side_effect ( ) ;
108
+ let b_side_effect = B :: may_have_side_effect ( ) ;
109
+ if a_side_effect || b_side_effect {
110
+ let sz_a = self . a . size ( ) ;
111
+ let sz_b = self . b . size ( ) ;
112
+ // Adjust a, b to equal length, make sure that only the first call
113
+ // of `next_back` does this, otherwise we will break the restriction
114
+ // on calls to `self.next_back()` after calling `get_unchecked()`.
115
+ if sz_a != sz_b {
116
+ if a_side_effect && sz_a > self . len {
117
+ for _ in 0 ..sz_a - cmp:: max ( self . len , self . index ) {
118
+ self . a . next_back ( ) ;
119
+ }
120
+ }
121
+
122
+ if b_side_effect && sz_b > self . len {
123
+ for _ in 0 ..sz_b - self . len {
124
+ self . b . next_back ( ) ;
125
+ }
126
+ }
127
+ }
128
+ }
129
+ if self . index < self . len {
130
+ self . len -= 1 ;
131
+ let i = self . len ;
132
+ // SAFETY: `i` is smaller than the previous value of `self.len`,
133
+ // which is also smaller than or equal to `self.a.len()` and `self.b.len()`
134
+ unsafe {
135
+ Some ( ( self . a . __iterator_get_unchecked ( i) , self . b . __iterator_get_unchecked ( i) ) )
136
+ }
137
+ } else {
138
+ None
139
+ }
140
+ }
141
+ }
142
+
143
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
144
+ impl < A , B > Iterator for Zip < A , B >
145
+ where
146
+ A : Iterator ,
147
+ B : Iterator ,
148
+ {
149
+ type Item = ( A :: Item , B :: Item ) ;
150
+
151
+ #[ inline]
152
+ default fn next ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
153
+ let x = self . a . next ( ) ?;
154
+ let y = self . b . next ( ) ?;
155
+ Some ( ( x, y) )
156
+ }
157
+
158
+ #[ inline]
159
+ default fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
160
+ self . super_nth ( n)
161
+ }
154
162
155
163
#[ inline]
156
164
default fn size_hint ( & self ) -> ( usize , Option < usize > ) {
@@ -169,25 +177,20 @@ where
169
177
( lower, upper)
170
178
}
171
179
172
- default unsafe fn get_unchecked ( & mut self , _idx : usize ) -> <Self as Iterator >:: Item
180
+ default unsafe fn __iterator_get_unchecked ( & mut self , _idx : usize ) -> <Self as Iterator >:: Item
173
181
where
174
182
Self : TrustedRandomAccess ,
175
183
{
176
184
unreachable ! ( "Always specialized" ) ;
177
185
}
178
186
}
179
187
180
- #[ doc ( hidden ) ]
181
- impl < A , B > ZipImpl < A , B > for Zip < A , B >
188
+ #[ stable ( feature = "rust1" , since = "1.0.0" ) ]
189
+ impl < A , B > Iterator for Zip < A , B >
182
190
where
183
191
A : TrustedRandomAccess + Iterator ,
184
192
B : TrustedRandomAccess + Iterator ,
185
193
{
186
- fn new ( a : A , b : B ) -> Self {
187
- let len = cmp:: min ( a. size ( ) , b. size ( ) ) ;
188
- Zip { a, b, index : 0 , len }
189
- }
190
-
191
194
#[ inline]
192
195
fn next ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
193
196
if self . index < self . len {
@@ -243,49 +246,7 @@ where
243
246
}
244
247
245
248
#[ inline]
246
- fn next_back ( & mut self ) -> Option < ( A :: Item , B :: Item ) >
247
- where
248
- A : DoubleEndedIterator + ExactSizeIterator ,
249
- B : DoubleEndedIterator + ExactSizeIterator ,
250
- {
251
- let a_side_effect = A :: may_have_side_effect ( ) ;
252
- let b_side_effect = B :: may_have_side_effect ( ) ;
253
- if a_side_effect || b_side_effect {
254
- let sz_a = self . a . size ( ) ;
255
- let sz_b = self . b . size ( ) ;
256
- // Adjust a, b to equal length, make sure that only the first call
257
- // of `next_back` does this, otherwise we will break the restriction
258
- // on calls to `self.next_back()` after calling `get_unchecked()`.
259
- if sz_a != sz_b {
260
- let sz_a = self . a . size ( ) ;
261
- if a_side_effect && sz_a > self . len {
262
- for _ in 0 ..sz_a - cmp:: max ( self . len , self . index ) {
263
- self . a . next_back ( ) ;
264
- }
265
- }
266
- let sz_b = self . b . size ( ) ;
267
- if b_side_effect && sz_b > self . len {
268
- for _ in 0 ..sz_b - self . len {
269
- self . b . next_back ( ) ;
270
- }
271
- }
272
- }
273
- }
274
- if self . index < self . len {
275
- self . len -= 1 ;
276
- let i = self . len ;
277
- // SAFETY: `i` is smaller than the previous value of `self.len`,
278
- // which is also smaller than or equal to `self.a.len()` and `self.b.len()`
279
- unsafe {
280
- Some ( ( self . a . __iterator_get_unchecked ( i) , self . b . __iterator_get_unchecked ( i) ) )
281
- }
282
- } else {
283
- None
284
- }
285
- }
286
-
287
- #[ inline]
288
- unsafe fn get_unchecked ( & mut self , idx : usize ) -> <Self as Iterator >:: Item {
249
+ unsafe fn __iterator_get_unchecked ( & mut self , idx : usize ) -> <Self as Iterator >:: Item {
289
250
let idx = self . index + idx;
290
251
// SAFETY: the caller must uphold the contract for
291
252
// `Iterator::__iterator_get_unchecked`.
0 commit comments