1#![feature(core)]
2
3extern crate core;
4
5use core::iter::FromIterator;
6use core::{iter,mem,slice};
7
8#[derive(Clone,Eq,PartialEq,Hash)]
15pub struct CircularBuffer<T>{
16 list: Box<[T]>,
17 first: usize
18}
19
20impl<T> CircularBuffer<T>{
21 #[inline]
23 pub fn len(&self) -> usize{self.list.len()}
24
25 pub fn queue(&mut self,mut elem: T) -> T{
29 let len = self.len();
30 self.first = (self.first + len - 1) % len;
31 mem::swap(unsafe{self.list.get_unchecked_mut(self.first)},&mut elem);
32 elem
33 }
34
35 pub fn set_first(&mut self,index: usize){
38 self.first = (index + self.first) % self.len();
39 }
40
41 pub fn get(&self,index: usize) -> &T{
44 let len = self.len();
45 unsafe{self.list.get_unchecked((index + self.first) % len)}
46 }
47
48 pub fn get_mut(&mut self,index: usize) -> &mut T{
51 let len = self.len();
52 unsafe{self.list.get_unchecked_mut((index + self.first) % len)}
53 }
54
55 pub fn swap_internal(&mut self,a: usize,b: usize){
58 let len = self.len();
59 self.list.swap((a + self.first) % len,(b + self.first) % len);
60 }
61
62 pub fn swap(&mut self,index: usize,mut elem: T) -> T{
65 mem::swap(self.get_mut(index),&mut elem);
66 elem
67 }
68
69 pub fn iter_circular<'s>(&'s self) -> IterCircular<'s,T>{
72 self.list.iter().cycle().skip(self.first)
73 }
74
75 pub fn iter<'s>(&'s self) -> Iter<'s,T>{
77 self.iter_circular().take(self.len())
78 }
79
80 #[inline]
86 pub unsafe fn from_raw_parts(list: Box<[T]>,first: usize) -> Self{
87 CircularBuffer{list: list,first: first}
88 }
89
90 #[inline]
92 pub fn into_raw_parts(self) -> (Box<[T]>,usize){
93 (self.list,self.first)
94 }
95}
96
97impl<T> From<Vec<T>> for CircularBuffer<T>{
98 #[inline]
99 fn from(vec: Vec<T>) -> Self{
100 debug_assert!(vec.len() > 0);
101 CircularBuffer{
102 list: vec.into_boxed_slice(),
103 first: 0
104 }
105 }
106}
107
108impl<T> From<Box<[T]>> for CircularBuffer<T>{
109 #[inline]
110 fn from(l: Box<[T]>) -> Self{
111 debug_assert!(l.len() > 0);
112 CircularBuffer{
113 list: l,
114 first: 0
115 }
116 }
117}
118
119impl<T> FromIterator<T> for CircularBuffer<T>{
120 #[inline]
121 fn from_iter<I>(i: I) -> Self
122 where I: IntoIterator<Item=T>
123 {
124 CircularBuffer::from(Vec::from_iter(i))
125 }
126}
127
128pub type Iter<'t,T> = iter::Take<IterCircular<'t,T>>;
129pub type IterCircular<'t,T> = iter::Skip<iter::Cycle<slice::Iter<'t,T>>>;
130
131#[test]
132fn test_len(){
133 let l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
134 assert_eq!(l.len(),4);
135
136 let l = CircularBuffer::from(Box::new(['a','b']) as Box<[char]>);
137 assert_eq!(l.len(),2);
138
139 let l = CircularBuffer::from(Box::new(['a']) as Box<[char]>);
140 assert_eq!(l.len(),1);
141}
142
143#[test]
144#[should_panic]
145fn test_len_empty(){
146 let _ = CircularBuffer::from(Box::new([]) as Box<[char]>);
147}
148
149#[test]
150fn test_queue(){
151 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
152 assert_eq!(l.first,0);
153 assert_eq!(&*l.list,&['a','b','c','d']);
154
155 l.queue('9');
156 assert_eq!(l.first,3);
157 assert_eq!(&*l.list,&['a','b','c','9']);
158
159 l.queue('8');
160 assert_eq!(l.first,2);
161 assert_eq!(&*l.list,&['a','b','8','9']);
162
163 l.queue('7');
164 assert_eq!(l.first,1);
165 assert_eq!(&*l.list,&['a','7','8','9']);
166
167 l.queue('6');
168 assert_eq!(l.first,0);
169 assert_eq!(&*l.list,&['6','7','8','9']);
170
171 l.queue('5');
172 assert_eq!(l.first,3);
173 assert_eq!(&*l.list,&['6','7','8','5']);
174
175 l.queue('4');
176 assert_eq!(l.first,2);
177 assert_eq!(&*l.list,&['6','7','4','5']);
178}
179
180#[test]
181fn test_set_first(){
182 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
183 l.set_first(0);
184 assert_eq!(l.first,0);
185
186 l.set_first(1);
187 assert_eq!(l.first,1);
188
189 l.set_first(1);
190 assert_eq!(l.first,2);
191
192 l.set_first(1);
193 assert_eq!(l.first,3);
194
195 l.set_first(1);
196 assert_eq!(l.first,0);
197
198 l.set_first(2);
199 assert_eq!(l.first,2);
200
201 l.set_first(4);
202 assert_eq!(l.first,2);
203}
204
205#[test]
206fn test_get(){
207 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
208 l.set_first(0);
209 assert_eq!(l.first,0);
210 assert_eq!(*l.get(0),'a');
211 assert_eq!(*l.get(1),'b');
212 assert_eq!(*l.get(2),'c');
213 assert_eq!(*l.get(3),'d');
214
215 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
216 l.set_first(1);
217 assert_eq!(l.first,1);
218 assert_eq!(*l.get(0),'b');
219 assert_eq!(*l.get(1),'c');
220 assert_eq!(*l.get(2),'d');
221 assert_eq!(*l.get(3),'a');
222
223 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
224 l.set_first(2);
225 assert_eq!(l.first,2);
226 assert_eq!(*l.get(0),'c');
227 assert_eq!(*l.get(1),'d');
228 assert_eq!(*l.get(2),'a');
229 assert_eq!(*l.get(3),'b');
230
231 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
232 l.set_first(3);
233 assert_eq!(l.first,3);
234 assert_eq!(*l.get(0),'d');
235 assert_eq!(*l.get(1),'a');
236 assert_eq!(*l.get(2),'b');
237 assert_eq!(*l.get(3),'c');
238
239 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
240 l.set_first(4);
241 assert_eq!(l.first,0);
242 assert_eq!(*l.get(0),'a');
243 assert_eq!(*l.get(1),'b');
244 assert_eq!(*l.get(2),'c');
245 assert_eq!(*l.get(3),'d');
246
247 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
248 l.set_first(5);
249 assert_eq!(l.first,1);
250 assert_eq!(*l.get(0),'b');
251 assert_eq!(*l.get(1),'c');
252 assert_eq!(*l.get(2),'d');
253 assert_eq!(*l.get(3),'a');
254}
255
256#[test]
257fn test_get_mut(){
258 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
259 l.set_first(0);
260 assert_eq!(l.first,0);
261 assert_eq!(*l.get_mut(0),'a');
262 assert_eq!(*l.get_mut(1),'b');
263 assert_eq!(*l.get_mut(2),'c');
264 assert_eq!(*l.get_mut(3),'d');
265
266 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
267 l.set_first(1);
268 assert_eq!(l.first,1);
269 assert_eq!(*l.get_mut(0),'b');
270 assert_eq!(*l.get_mut(1),'c');
271 assert_eq!(*l.get_mut(2),'d');
272 assert_eq!(*l.get_mut(3),'a');
273
274 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
275 l.set_first(2);
276 assert_eq!(l.first,2);
277 assert_eq!(*l.get_mut(0),'c');
278 assert_eq!(*l.get_mut(1),'d');
279 assert_eq!(*l.get_mut(2),'a');
280 assert_eq!(*l.get_mut(3),'b');
281
282 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
283 l.set_first(3);
284 assert_eq!(l.first,3);
285 assert_eq!(*l.get_mut(0),'d');
286 assert_eq!(*l.get_mut(1),'a');
287 assert_eq!(*l.get_mut(2),'b');
288 assert_eq!(*l.get_mut(3),'c');
289
290 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
291 l.set_first(4);
292 assert_eq!(l.first,0);
293 assert_eq!(*l.get_mut(0),'a');
294 assert_eq!(*l.get_mut(1),'b');
295 assert_eq!(*l.get_mut(2),'c');
296 assert_eq!(*l.get_mut(3),'d');
297
298 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
299 l.set_first(5);
300 assert_eq!(l.first,1);
301 assert_eq!(*l.get_mut(0),'b');
302 assert_eq!(*l.get_mut(1),'c');
303 assert_eq!(*l.get_mut(2),'d');
304 assert_eq!(*l.get_mut(3),'a');
305}
306
307#[test]
308fn test_swap(){
309 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
310 assert_eq!(&*l.list,&['a','b','c','d']);
311
312 l.swap(0,'0');
313 assert_eq!(&*l.list,&['0','b','c','d']);
314
315 l.swap(1,'1');
316 assert_eq!(&*l.list,&['0','1','c','d']);
317
318 l.swap(2,'2');
319 assert_eq!(&*l.list,&['0','1','2','d']);
320
321 l.swap(3,'3');
322 assert_eq!(&*l.list,&['0','1','2','3']);
323
324 l.swap(4,'4');
325 assert_eq!(&*l.list,&['4','1','2','3']);
326
327 l.swap(5,'5');
328 assert_eq!(&*l.list,&['4','5','2','3']);
329
330 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
331 l.set_first(1);
332 assert_eq!(&*l.list,&['a','b','c','d']);
333
334 l.swap(0,'0');
335 assert_eq!(&*l.list,&['a','0','c','d']);
336
337 l.swap(1,'1');
338 assert_eq!(&*l.list,&['a','0','1','d']);
339
340 l.swap(2,'2');
341 assert_eq!(&*l.list,&['a','0','1','2']);
342
343 l.swap(3,'3');
344 assert_eq!(&*l.list,&['3','0','1','2']);
345
346 l.swap(4,'4');
347 assert_eq!(&*l.list,&['3','4','1','2']);
348
349 l.swap(5,'5');
350 assert_eq!(&*l.list,&['3','4','5','2']);
351}
352
353#[test]
354fn test_swap_internal(){
355 let mut l = CircularBuffer::from(Box::new(['a','b','c','d']) as Box<[char]>);
356 assert_eq!(&*l.list,&['a','b','c','d']);
357
358 l.swap_internal(0,3);
359 assert_eq!(&*l.list,&['d','b','c','a']);
360
361 l.swap_internal(3,0);
362 assert_eq!(&*l.list,&['a','b','c','d']);
363
364 l.swap_internal(1,2);
365 assert_eq!(&*l.list,&['a','c','b','d']);
366
367 l.swap_internal(2,1);
368 assert_eq!(&*l.list,&['a','b','c','d']);
369
370 l.swap_internal(0,5);
371 assert_eq!(&*l.list,&['b','a','c','d']);
372
373 l.swap_internal(5,0);
374 assert_eq!(&*l.list,&['a','b','c','d']);
375}
376
377#[test]
378fn test_iter(){
379 let l = unsafe{CircularBuffer::from_raw_parts(Box::new(['a','b','c']) as Box<[char]>,0)};
380 let mut i = l.iter();
381
382 assert_eq!(*i.next().unwrap(),'a');
383 assert_eq!(*i.next().unwrap(),'b');
384 assert_eq!(*i.next().unwrap(),'c');
385 assert!(i.next().is_none());
386
387 let l = unsafe{CircularBuffer::from_raw_parts(Box::new(['a','b','c']) as Box<[char]>,1)};
388 let mut i = l.iter();
389
390 assert_eq!(*i.next().unwrap(),'b');
391 assert_eq!(*i.next().unwrap(),'c');
392 assert_eq!(*i.next().unwrap(),'a');
393 assert!(i.next().is_none());
394
395 let l = unsafe{CircularBuffer::from_raw_parts(Box::new(['a','b','c']) as Box<[char]>,2)};
396 let mut i = l.iter();
397
398 assert_eq!(*i.next().unwrap(),'c');
399 assert_eq!(*i.next().unwrap(),'a');
400 assert_eq!(*i.next().unwrap(),'b');
401 assert!(i.next().is_none());
402}
403
404#[test]
405fn test_iter_circular(){
406 let l = unsafe{CircularBuffer::from_raw_parts(Box::new(['a','b','c']) as Box<[char]>,0)};
407 let mut i = l.iter_circular();
408
409 assert_eq!(*i.next().unwrap(),'a');
410 assert_eq!(*i.next().unwrap(),'b');
411 assert_eq!(*i.next().unwrap(),'c');
412 assert_eq!(*i.next().unwrap(),'a');
413 assert_eq!(*i.next().unwrap(),'b');
414 assert_eq!(*i.next().unwrap(),'c');
415 assert_eq!(*i.next().unwrap(),'a');
416 assert_eq!(*i.next().unwrap(),'b');
417 assert_eq!(*i.next().unwrap(),'c');
418
419 let l = unsafe{CircularBuffer::from_raw_parts(Box::new(['a','b','c']) as Box<[char]>,1)};
420 let mut i = l.iter_circular();
421
422 assert_eq!(*i.next().unwrap(),'b');
423 assert_eq!(*i.next().unwrap(),'c');
424 assert_eq!(*i.next().unwrap(),'a');
425 assert_eq!(*i.next().unwrap(),'b');
426 assert_eq!(*i.next().unwrap(),'c');
427 assert_eq!(*i.next().unwrap(),'a');
428 assert_eq!(*i.next().unwrap(),'b');
429 assert_eq!(*i.next().unwrap(),'c');
430 assert_eq!(*i.next().unwrap(),'a');
431
432 let l = unsafe{CircularBuffer::from_raw_parts(Box::new(['a','b','c']) as Box<[char]>,2)};
433 let mut i = l.iter_circular();
434
435 assert_eq!(*i.next().unwrap(),'c');
436 assert_eq!(*i.next().unwrap(),'a');
437 assert_eq!(*i.next().unwrap(),'b');
438 assert_eq!(*i.next().unwrap(),'c');
439 assert_eq!(*i.next().unwrap(),'a');
440 assert_eq!(*i.next().unwrap(),'b');
441 assert_eq!(*i.next().unwrap(),'c');
442 assert_eq!(*i.next().unwrap(),'a');
443 assert_eq!(*i.next().unwrap(),'b');
444}