1
1
use core:: fmt;
2
2
use core:: iter:: { FusedIterator , TrustedLen , TrustedRandomAccess , TrustedRandomAccessNoCoerce } ;
3
+ use core:: marker:: PhantomData ;
3
4
use core:: mem:: MaybeUninit ;
4
5
use core:: ops:: Try ;
6
+ use core:: ptr:: NonNull ;
5
7
6
8
use super :: { count, wrap_index, RingSlices } ;
7
9
@@ -13,38 +15,53 @@ use super::{count, wrap_index, RingSlices};
13
15
/// [`iter`]: super::VecDeque::iter
14
16
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
15
17
pub struct Iter < ' a , T : ' a > {
16
- ring : & ' a [ MaybeUninit < T > ] ,
18
+ ring : NonNull < [ T ] > ,
17
19
tail : usize ,
18
20
head : usize ,
21
+ _marker : PhantomData < & ' a T > ,
19
22
}
20
23
21
24
impl < ' a , T > Iter < ' a , T > {
22
25
pub ( super ) fn new ( ring : & ' a [ MaybeUninit < T > ] , tail : usize , head : usize ) -> Self {
23
- Iter { ring, tail, head }
26
+ Iter {
27
+ ring : unsafe { NonNull :: new_unchecked ( ring as * const [ MaybeUninit < T > ] as * mut _ ) } ,
28
+ tail,
29
+ head,
30
+ _marker : PhantomData ,
31
+ }
32
+ }
33
+
34
+ unsafe fn ring ( & self ) -> & ' a [ MaybeUninit < T > ] {
35
+ unsafe {
36
+ core:: slice:: from_raw_parts (
37
+ self . ring . as_ptr ( ) as * const MaybeUninit < T > ,
38
+ self . ring . len ( ) ,
39
+ )
40
+ }
24
41
}
25
42
}
26
43
44
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
45
+ unsafe impl < T : Sync > Sync for Iter < ' _ , T > { }
46
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
47
+ unsafe impl < T : Sync > Send for Iter < ' _ , T > { }
48
+
27
49
#[ stable( feature = "collection_debug" , since = "1.17.0" ) ]
28
50
impl < T : fmt:: Debug > fmt:: Debug for Iter < ' _ , T > {
29
51
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
30
- let ( front, back) = RingSlices :: ring_slices ( self . ring , self . head , self . tail ) ;
52
+ let ( front, back) = unsafe { RingSlices :: ring_slices ( self . ring ( ) , self . head , self . tail ) } ;
31
53
// Safety:
32
54
// - `self.head` and `self.tail` in a ring buffer are always valid indices.
33
55
// - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
34
- unsafe {
35
- f. debug_tuple ( "Iter" )
36
- . field ( & MaybeUninit :: slice_assume_init_ref ( front) )
37
- . field ( & MaybeUninit :: slice_assume_init_ref ( back) )
38
- . finish ( )
39
- }
56
+ f. debug_tuple ( "Iter" ) . field ( & front) . field ( & back) . finish ( )
40
57
}
41
58
}
42
59
43
60
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
44
61
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
45
62
impl < T > Clone for Iter < ' _ , T > {
46
63
fn clone ( & self ) -> Self {
47
- Iter { ring : self . ring , tail : self . tail , head : self . head }
64
+ Iter { ring : self . ring , tail : self . tail , head : self . head , _marker : PhantomData }
48
65
}
49
66
}
50
67
@@ -62,7 +79,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
62
79
// Safety:
63
80
// - `self.tail` in a ring buffer is always a valid index.
64
81
// - `self.head` and `self.tail` equality is checked above.
65
- unsafe { Some ( self . ring . get_unchecked ( tail) . assume_init_ref ( ) ) }
82
+ unsafe { Some ( self . ring ( ) . get_unchecked ( tail) . assume_init_ref ( ) ) }
66
83
}
67
84
68
85
#[ inline]
@@ -75,11 +92,11 @@ impl<'a, T> Iterator for Iter<'a, T> {
75
92
where
76
93
F : FnMut ( Acc , Self :: Item ) -> Acc ,
77
94
{
78
- let ( front, back) = RingSlices :: ring_slices ( self . ring , self . head , self . tail ) ;
79
95
// Safety:
80
96
// - `self.head` and `self.tail` in a ring buffer are always valid indices.
81
97
// - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
82
98
unsafe {
99
+ let ( front, back) = RingSlices :: ring_slices ( self . ring ( ) , self . head , self . tail ) ;
83
100
accum = MaybeUninit :: slice_assume_init_ref ( front) . iter ( ) . fold ( accum, & mut f) ;
84
101
MaybeUninit :: slice_assume_init_ref ( back) . iter ( ) . fold ( accum, & mut f)
85
102
}
@@ -94,12 +111,13 @@ impl<'a, T> Iterator for Iter<'a, T> {
94
111
let ( mut iter, final_res) ;
95
112
if self . tail <= self . head {
96
113
// Safety: single slice self.ring[self.tail..self.head] is initialized.
97
- iter = unsafe { MaybeUninit :: slice_assume_init_ref ( & self . ring [ self . tail ..self . head ] ) }
98
- . iter ( ) ;
114
+ iter =
115
+ unsafe { MaybeUninit :: slice_assume_init_ref ( & self . ring ( ) [ self . tail ..self . head ] ) }
116
+ . iter ( ) ;
99
117
final_res = iter. try_fold ( init, & mut f) ;
100
118
} else {
101
- // Safety: two slices: self.ring[self.tail..], self.ring[..self.head] both are initialized.
102
- let ( front, back) = self . ring . split_at ( self . tail ) ;
119
+ // Safety: two slices: self.ring() [self.tail..], self.ring() [..self.head] both are initialized.
120
+ let ( front, back) = unsafe { self . ring ( ) . split_at ( self . tail ) } ;
103
121
104
122
let mut back_iter = unsafe { MaybeUninit :: slice_assume_init_ref ( back) . iter ( ) } ;
105
123
let res = back_iter. try_fold ( init, & mut f) ;
@@ -133,7 +151,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
133
151
// that is in bounds.
134
152
unsafe {
135
153
let idx = wrap_index ( self . tail . wrapping_add ( idx) , self . ring . len ( ) ) ;
136
- self . ring . get_unchecked ( idx) . assume_init_ref ( )
154
+ self . ring ( ) . get_unchecked ( idx) . assume_init_ref ( )
137
155
}
138
156
}
139
157
}
@@ -149,18 +167,18 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
149
167
// Safety:
150
168
// - `self.head` in a ring buffer is always a valid index.
151
169
// - `self.head` and `self.tail` equality is checked above.
152
- unsafe { Some ( self . ring . get_unchecked ( self . head ) . assume_init_ref ( ) ) }
170
+ unsafe { Some ( self . ring ( ) . get_unchecked ( self . head ) . assume_init_ref ( ) ) }
153
171
}
154
172
155
173
fn rfold < Acc , F > ( self , mut accum : Acc , mut f : F ) -> Acc
156
174
where
157
175
F : FnMut ( Acc , Self :: Item ) -> Acc ,
158
176
{
159
- let ( front, back) = RingSlices :: ring_slices ( self . ring , self . head , self . tail ) ;
160
177
// Safety:
161
178
// - `self.head` and `self.tail` in a ring buffer are always valid indices.
162
179
// - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
163
180
unsafe {
181
+ let ( front, back) = RingSlices :: ring_slices ( self . ring ( ) , self . head , self . tail ) ;
164
182
accum = MaybeUninit :: slice_assume_init_ref ( back) . iter ( ) . rfold ( accum, & mut f) ;
165
183
MaybeUninit :: slice_assume_init_ref ( front) . iter ( ) . rfold ( accum, & mut f)
166
184
}
@@ -174,14 +192,14 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
174
192
{
175
193
let ( mut iter, final_res) ;
176
194
if self . tail <= self . head {
177
- // Safety: single slice self.ring[self.tail..self.head] is initialized.
195
+ // Safety: single slice self.ring() [self.tail..self.head] is initialized.
178
196
iter = unsafe {
179
- MaybeUninit :: slice_assume_init_ref ( & self . ring [ self . tail ..self . head ] ) . iter ( )
197
+ MaybeUninit :: slice_assume_init_ref ( & self . ring ( ) [ self . tail ..self . head ] ) . iter ( )
180
198
} ;
181
199
final_res = iter. try_rfold ( init, & mut f) ;
182
200
} else {
183
- // Safety: two slices: self.ring[self.tail..], self.ring[..self.head] both are initialized.
184
- let ( front, back) = self . ring . split_at ( self . tail ) ;
201
+ // Safety: two slices: self.ring() [self.tail..], self.ring() [..self.head] both are initialized.
202
+ let ( front, back) = unsafe { self . ring ( ) . split_at ( self . tail ) } ;
185
203
186
204
let mut front_iter =
187
205
unsafe { MaybeUninit :: slice_assume_init_ref ( & front[ ..self . head ] ) . iter ( ) } ;
0 commit comments