1use std::cell::{Cell, UnsafeCell};
2use std::fmt;
3use std::marker::PhantomData;
4#[cfg(nightly)]
5use std::iterator::FusedIterator;
6
7pub struct Storage<T> {
11 window_size: usize,
12 window_offset: Cell<usize>,
14 uniquely_owned: Cell<bool>,
16 data: UnsafeCell<Vec<T>>,
17}
18
19impl<T> Storage<T> {
20 pub fn new(window_size: usize) -> Storage<T> {
25 Storage::from_vec(Vec::with_capacity(window_size), window_size)
26 }
27
28 pub fn from_vec<S: Into<Vec<T>>>(vec: S, window_size: usize) -> Storage<T> {
34 Storage {
35 window_size: window_size,
36 window_offset: Cell::new(0),
37 uniquely_owned: Cell::new(true),
38 data: UnsafeCell::new(vec.into())
39 }
40 }
41
42 fn new_window<'a>(&'a self) -> Window<'a, T> {
43 assert!(self.uniquely_owned.get(), "next() called before previous Window went out of scope");
45 let data = unsafe { &mut *self.data.get() };
46 let window_offset = self.window_offset.get();
47
48 self.uniquely_owned.set(false);
49
50 Window { drop_flag: &self.uniquely_owned, data: &mut data[..], window_offset: window_offset }
51 }
52
53 fn push(&self, elt: T) -> bool {
56 assert!(self.uniquely_owned.get(), "next() called before previous Window went out of scope");
57 let data = unsafe { &mut *self.data.get() };
58 let window_offset = self.window_offset.get();
59
60 if data.len() < self.window_size
63 {
64 data.push(elt);
65 return data.len() == self.window_size;
66 }
67
68 debug_assert!(data.len() == self.window_size);
69
70 let new_offset;
72 if window_offset >= (self.window_size - 1) {
73 new_offset = 0;
74 } else {
75 new_offset = window_offset + 1;
76 }
77
78 data[window_offset] = elt;
79 self.window_offset.set(new_offset);
80 true
81 }
82
83 fn clear(&self) {
85 assert!(self.uniquely_owned.get(), "next() called before previous Window went out of scope");
86 let data = unsafe { &mut *self.data.get() };
87 data.clear();
88 }
89}
90
91impl<T> Into<Vec<T>> for Storage<T> {
92 fn into(self) -> Vec<T> {
93 assert!(self.uniquely_owned.get(), "Storage dereferenced before previous Window went out of scope");
94 unsafe {
95 self.data.into_inner()
96 }
97 }
98}
99
100pub struct Window<'a, T: 'a> {
131 drop_flag: &'a Cell<bool>,
132 window_offset: usize,
134 data: &'a mut [T],
135}
136
137impl<'a, T> Window<'a, T>
138{
139 pub fn iter(&self) -> WindowIter<T> {
140 WindowIter {
141 data: self.data,
142 current_index: self.window_offset,
143 iteration_num: 0
144 }
145 }
146
147 pub fn iter_mut(&mut self) -> WindowIterMut<T> {
148 WindowIterMut {
149 data: self.data.as_mut_ptr(),
150 data_len: self.data.len(),
151 current_index: self.window_offset,
152 iteration_num: 0,
153 _p: PhantomData
154 }
155 }
156}
157
158impl<'a, T> fmt::Debug for Window<'a, T> where T: fmt::Debug
159{
160 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161 f.write_str("Window")?;
162 return f.debug_list().entries(self.into_iter()).finish();
163 }
164}
165
166impl<'a, T> Drop for Window<'a, T> {
167 fn drop(&mut self) {
168 self.drop_flag.set(true);
170 }
171}
172
173impl<'a, 'b, T> PartialEq<&'b [T]> for Window<'a, T> where T: PartialEq
174{
175 fn eq(&self, other: &&'b [T]) -> bool {
176 if self.data.len() != other.len() { return false }
177 for (i, x) in self.into_iter().enumerate() {
178 if *x != other[i] { return false }
179 }
180 true
181 }
182}
183
184impl<'a, T> IntoIterator for &'a Window<'a, T>
185{
186 type Item = &'a T;
187 type IntoIter = WindowIter<'a, T>;
188 fn into_iter(self) -> Self::IntoIter {
189 self.iter()
190 }
191}
192
193pub struct WindowIter<'a, T: 'a>
194{
195 data: &'a [T],
196 current_index: usize,
197 iteration_num: usize,
199}
200
201impl<'a, T> Iterator for WindowIter<'a, T>
202{
203 type Item = &'a T;
204
205 fn next(&mut self) -> Option<Self::Item> {
206 let current_element = &self.data[self.current_index];
207
208 if self.iteration_num >= self.data.len() {
209 return None;
211 } else if self.current_index >= (self.data.len() - 1) {
212 self.current_index = 0;
214 } else {
215 self.current_index += 1;
216 }
217
218 self.iteration_num += 1;
219 Some(current_element)
220 }
221
222 fn size_hint(&self) -> (usize, Option<usize>) {
223 (self.data.len(), Some(self.data.len()))
224 }
225}
226
227impl<'a, T> ExactSizeIterator for WindowIter<'a, T> {}
228#[cfg(nightly)]
229impl<'a, T> FusedIterator for WindowIter<'a, T> {}
230
231pub struct WindowIterMut<'a, T: 'a>
232{
233 data: *mut T,
234 data_len: usize,
235 current_index: usize,
236 iteration_num: usize,
238 _p: PhantomData<&'a T>,
239}
240
241impl<'a, T> Iterator for WindowIterMut<'a, T>
242{
243 type Item = &'a mut T;
244
245 fn next(&mut self) -> Option<Self::Item> {
246 let current_element = unsafe { self.data.offset(self.current_index as isize).as_mut().unwrap() };
247
248 if self.iteration_num >= self.data_len {
249 return None;
251 } else if self.current_index >= (self.data_len - 1) {
252 self.current_index = 0;
254 } else {
255 self.current_index += 1;
256 }
257
258 self.iteration_num += 1;
259 Some(current_element)
260 }
261
262 fn size_hint(&self) -> (usize, Option<usize>) {
263 (self.data_len, Some(self.data_len))
264 }
265}
266
267impl<'a, T> ExactSizeIterator for WindowIterMut<'a, T> {}
268#[cfg(nightly)]
269impl<'a, T> FusedIterator for WindowIterMut<'a, T> {}
270
271pub struct Adaptor<'a, I: Iterator> where <I as Iterator>::Item: 'a {
275 iter: I,
276 done: bool,
277 storage: &'a Storage<I::Item>,
278}
279
280impl<'a, I: Iterator> Adaptor<'a, I> {
281 pub fn new(iter: I, storage: &'a Storage<I::Item>) -> Adaptor<'a, I> {
285 storage.clear();
287
288 Adaptor {
289 iter: iter,
290 done: false,
291 storage: storage,
292 }
293 }
294}
295
296impl<'a, I: Iterator> Iterator for Adaptor<'a, I> {
297 type Item = Window<'a, I::Item>;
298
299 fn next(&mut self) -> Option<Self::Item> {
300 if self.done || self.storage.window_size == 0 {
301 return None;
302 }
303 self.done = true;
304
305 for elt in &mut self.iter {
306 self.done = false;
307 if self.storage.push(elt) {
308 break;
309 }
310 }
311
312 if !self.done {
313 Some(self.storage.new_window())
315 } else {
316 None
317 }
318 }
319
320 fn size_hint(&self) -> (usize, Option<usize>) {
321 let size = self.storage.window_size;
322 let (mut lower, mut upper): (usize, Option<usize>) = self.iter.size_hint();
323
324 if size == 0 {
325 return (0, None);
326 }
327
328 lower = match lower {
329 0 => 0,
330 x if x >= size => x - size + 1,
331 _ => 1
332 };
333
334 upper = upper.map(|upper|
335 match upper {
336 0 => 0,
337 x if x >= size => x - size + 1,
338 _ => 1
339 }
340 );
341
342 (lower, upper)
343 }
344}