@@ -17,93 +17,33 @@ pub struct Zip<A, B> {
1717 index : usize ,
1818 len : usize ,
1919}
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- }
3420
35- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
36- impl < A , B > Iterator for Zip < A , B >
21+ impl < A , B > Zip < A , B >
3722where
3823 A : Iterator ,
3924 B : Iterator ,
4025{
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)
6628 }
67- }
6829
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 ( )
7833 }
7934}
8035
81- // Zip specialization trait
8236#[ doc( hidden) ]
83- trait ZipImpl < A , B > {
84- type Item ;
37+ trait ZipNew < A , B > {
8538 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 ;
9739}
9840
99- // General Zip impl
10041#[ doc( hidden) ]
101- impl < A , B > ZipImpl < A , B > for Zip < A , B >
42+ impl < A , B > ZipNew < A , B > for Zip < A , B >
10243where
10344 A : Iterator ,
10445 B : Iterator ,
10546{
106- type Item = ( A :: Item , B :: Item ) ;
10747 default fn new ( a : A , b : B ) -> Self {
10848 Zip {
10949 a,
@@ -112,25 +52,28 @@ where
11252 len : 0 , // unused
11353 }
11454 }
55+ }
11556
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 }
12666 }
67+ }
12768
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+ {
12875 #[ 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 ) > {
13477 let a_sz = self . a . len ( ) ;
13578 let b_sz = self . b . len ( ) ;
13679 if a_sz != b_sz {
@@ -151,6 +94,71 @@ where
15194 _ => unreachable ! ( ) ,
15295 }
15396 }
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+ }
154162
155163 #[ inline]
156164 default fn size_hint ( & self ) -> ( usize , Option < usize > ) {
@@ -169,25 +177,20 @@ where
169177 ( lower, upper)
170178 }
171179
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
173181 where
174182 Self : TrustedRandomAccess ,
175183 {
176184 unreachable ! ( "Always specialized" ) ;
177185 }
178186}
179187
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 >
182190where
183191 A : TrustedRandomAccess + Iterator ,
184192 B : TrustedRandomAccess + Iterator ,
185193{
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-
191194 #[ inline]
192195 fn next ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
193196 if self . index < self . len {
@@ -243,49 +246,7 @@ where
243246 }
244247
245248 #[ 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 {
289250 let idx = self . index + idx;
290251 // SAFETY: the caller must uphold the contract for
291252 // `Iterator::__iterator_get_unchecked`.
0 commit comments