blob: 89d23191a7634331bf95fa976995425d9b14a053 [file] [log] [blame]
Daniel Micayb47e1e92013-02-16 22:55:551// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
Graydon Hoare00c856c2012-12-04 00:48:012// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
Daniel Micayb2060172013-03-21 23:14:0211//! A double-ended queue implemented as a circular buffer
blake2-ppc0f9b9a52013-07-11 14:17:5112//!
13//! RingBuf implements the trait Deque. It should be imported with `use
14//! extra::container::Deque`.
Patrick Waltonf3723cf2013-05-17 22:28:4415
Jens Nockert1aae28a2013-07-08 16:05:1716use std::num;
Corey Richardson1662bd32013-06-28 22:32:2617use std::vec;
blake2-ppcf8ae5262013-07-30 00:06:4918use std::iterator::{FromIterator, Invert, RandomAccessIterator, Extendable};
Alex Crichton998fece2013-05-06 04:42:5419
blake2-ppc70523712013-07-10 13:27:1420use container::Deque;
21
blake2-ppc0ff5c172013-07-06 03:42:4522static INITIAL_CAPACITY: uint = 8u; // 2^3
23static MINIMUM_CAPACITY: uint = 2u;
Daniel Micayb47e1e92013-02-16 22:55:5524
blake2-ppc0f9b9a52013-07-11 14:17:5125/// RingBuf is a circular buffer that implements Deque.
blake2-ppc10c76982013-07-06 13:27:3226#[deriving(Clone)]
blake2-ppc70523712013-07-10 13:27:1427pub struct RingBuf<T> {
Daniel Micayb47e1e92013-02-16 22:55:5528 priv nelts: uint,
29 priv lo: uint,
Daniel Micayb47e1e92013-02-16 22:55:5530 priv elts: ~[Option<T>]
Marijn Haverbeke26610db2012-01-11 11:49:3331}
Roy Frostig9c818892010-07-21 01:03:0932
blake2-ppc70523712013-07-10 13:27:1433impl<T> Container for RingBuf<T> {
34 /// Return the number of elements in the RingBuf
Alex Crichtonb29c3682013-06-24 03:44:1135 fn len(&self) -> uint { self.nelts }
Daniel Micayb47e1e92013-02-16 22:55:5536}
Roy Frostig9c818892010-07-21 01:03:0937
blake2-ppc70523712013-07-10 13:27:1438impl<T> Mutable for RingBuf<T> {
39 /// Clear the RingBuf, removing all values.
Daniel Micayed7c9c42013-02-16 23:55:2540 fn clear(&mut self) {
Daniel Micay100894552013-08-03 16:45:2341 for x in self.elts.mut_iter() { *x = None }
Daniel Micayed7c9c42013-02-16 23:55:2542 self.nelts = 0;
43 self.lo = 0;
Daniel Micayed7c9c42013-02-16 23:55:2544 }
45}
46
blake2-ppc70523712013-07-10 13:27:1447impl<T> Deque<T> for RingBuf<T> {
48 /// Return a reference to the first element in the RingBuf
49 fn front<'a>(&'a self) -> Option<&'a T> {
50 if self.nelts > 0 { Some(self.get(0)) } else { None }
blake2-ppc0ff5c172013-07-06 03:42:4551 }
52
blake2-ppc70523712013-07-10 13:27:1453 /// Return a mutable reference to the first element in the RingBuf
54 fn front_mut<'a>(&'a mut self) -> Option<&'a mut T> {
55 if self.nelts > 0 { Some(self.get_mut(0)) } else { None }
Niko Matsakis03396472013-04-10 20:14:0656 }
57
blake2-ppc70523712013-07-10 13:27:1458 /// Return a reference to the last element in the RingBuf
59 fn back<'a>(&'a self) -> Option<&'a T> {
60 if self.nelts > 0 { Some(self.get(self.nelts - 1)) } else { None }
61 }
Niko Matsakis03396472013-04-10 20:14:0662
blake2-ppc70523712013-07-10 13:27:1463 /// Return a mutable reference to the last element in the RingBuf
64 fn back_mut<'a>(&'a mut self) -> Option<&'a mut T> {
65 if self.nelts > 0 { Some(self.get_mut(self.nelts - 1)) } else { None }
66 }
67
68 /// Remove and return the first element in the RingBuf, or None if it is empty
69 fn pop_front(&mut self) -> Option<T> {
blake2-ppc980646a2013-07-17 21:41:5070 let result = self.elts[self.lo].take();
blake2-ppc70523712013-07-10 13:27:1471 if result.is_some() {
72 self.lo = (self.lo + 1u) % self.elts.len();
73 self.nelts -= 1u;
blake2-ppc5d72f3f2013-07-06 03:42:4574 }
Daniel Micay61906612013-02-17 00:43:2975 result
76 }
77
blake2-ppc70523712013-07-10 13:27:1478 /// Remove and return the last element in the RingBuf, or None if it is empty
79 fn pop_back(&mut self) -> Option<T> {
80 if self.nelts > 0 {
81 self.nelts -= 1;
82 let hi = self.raw_index(self.nelts);
blake2-ppc980646a2013-07-17 21:41:5083 self.elts[hi].take()
blake2-ppc70523712013-07-10 13:27:1484 } else {
85 None
86 }
blake2-ppc5d72f3f2013-07-06 03:42:4587 }
88
blake2-ppc70523712013-07-10 13:27:1489 /// Prepend an element to the RingBuf
90 fn push_front(&mut self, t: T) {
blake2-ppc40ce0b72013-07-06 03:42:4591 if self.nelts == self.elts.len() {
blake2-ppc8a326762013-07-06 03:42:4592 grow(self.nelts, &mut self.lo, &mut self.elts);
blake2-ppc40ce0b72013-07-06 03:42:4593 }
Daniel Micayb47e1e92013-02-16 22:55:5594 if self.lo == 0u {
95 self.lo = self.elts.len() - 1u;
96 } else { self.lo -= 1u; }
Daniel Micayb47e1e92013-02-16 22:55:5597 self.elts[self.lo] = Some(t);
98 self.nelts += 1u;
Erick Tryzelaare84576b2013-01-22 16:44:2499 }
Marijn Haverbeke26610db2012-01-11 11:49:33100
blake2-ppc70523712013-07-10 13:27:14101 /// Append an element to the RingBuf
102 fn push_back(&mut self, t: T) {
blake2-ppc5d72f3f2013-07-06 03:42:45103 if self.nelts == self.elts.len() {
blake2-ppc8a326762013-07-06 03:42:45104 grow(self.nelts, &mut self.lo, &mut self.elts);
Graydon Hoare2880ecd2010-09-22 22:44:13105 }
blake2-ppc5d72f3f2013-07-06 03:42:45106 let hi = self.raw_index(self.nelts);
107 self.elts[hi] = Some(t);
Daniel Micayb47e1e92013-02-16 22:55:55108 self.nelts += 1u;
Graydon Hoarece729932011-06-15 18:19:50109 }
blake2-ppc70523712013-07-10 13:27:14110}
Tim Chevalier77de84b2013-05-27 18:47:38111
blake2-ppc70523712013-07-10 13:27:14112impl<T> RingBuf<T> {
113 /// Create an empty RingBuf
114 pub fn new() -> RingBuf<T> {
115 RingBuf::with_capacity(INITIAL_CAPACITY)
116 }
117
118 /// Create an empty RingBuf with space for at least `n` elements.
119 pub fn with_capacity(n: uint) -> RingBuf<T> {
120 RingBuf{nelts: 0, lo: 0,
121 elts: vec::from_fn(num::max(MINIMUM_CAPACITY, n), |_| None)}
122 }
123
124 /// Retrieve an element in the RingBuf by index
125 ///
126 /// Fails if there is no element with the given index
127 pub fn get<'a>(&'a self, i: uint) -> &'a T {
128 let idx = self.raw_index(i);
129 match self.elts[idx] {
130 None => fail!(),
131 Some(ref v) => v
132 }
133 }
134
135 /// Retrieve an element in the RingBuf by index
136 ///
137 /// Fails if there is no element with the given index
138 pub fn get_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
139 let idx = self.raw_index(i);
140 match self.elts[idx] {
141 None => fail!(),
142 Some(ref mut v) => v
143 }
144 }
145
146 /// Return index in underlying vec for a given logical element index
147 fn raw_index(&self, idx: uint) -> uint {
148 raw_index(self.lo, self.elts.len(), idx)
149 }
150
151 /// Reserve capacity for exactly `n` elements in the given RingBuf,
Tim Chevalier77de84b2013-05-27 18:47:38152 /// doing nothing if `self`'s capacity is already equal to or greater
153 /// than the requested capacity
154 ///
155 /// # Arguments
156 ///
157 /// * n - The number of elements to reserve space for
Patrick Walton5fb25462013-05-31 22:17:22158 pub fn reserve(&mut self, n: uint) {
Huon Wilson32d65592013-06-27 14:40:47159 self.elts.reserve(n);
Tim Chevalier77de84b2013-05-27 18:47:38160 }
161
blake2-ppc70523712013-07-10 13:27:14162 /// Reserve capacity for at least `n` elements in the given RingBuf,
Tim Chevalier77de84b2013-05-27 18:47:38163 /// over-allocating in case the caller needs to reserve additional
164 /// space.
165 ///
166 /// Do nothing if `self`'s capacity is already equal to or greater
167 /// than the requested capacity.
168 ///
169 /// # Arguments
170 ///
171 /// * n - The number of elements to reserve space for
Patrick Walton5fb25462013-05-31 22:17:22172 pub fn reserve_at_least(&mut self, n: uint) {
Huon Wilson32d65592013-06-27 14:40:47173 self.elts.reserve_at_least(n);
Tim Chevalier77de84b2013-05-27 18:47:38174 }
Jed Estep4f7a7422013-06-25 19:08:47175
176 /// Front-to-back iterator.
blake2-ppc70523712013-07-10 13:27:14177 pub fn iter<'a>(&'a self) -> RingBufIterator<'a, T> {
blake2-ppcf6862132013-07-29 18:16:26178 RingBufIterator{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts}
blake2-ppc3385e792013-07-15 23:13:26179 }
180
181 /// Back-to-front iterator.
blake2-ppc4b45f472013-07-27 21:41:20182 pub fn rev_iter<'a>(&'a self) -> Invert<RingBufIterator<'a, T>> {
blake2-ppc3385e792013-07-15 23:13:26183 self.iter().invert()
Jed Estep4f7a7422013-06-25 19:08:47184 }
Corey Richardsonf8ae9b02013-06-26 22:14:35185
Jed Estep4f7a7422013-06-25 19:08:47186 /// Front-to-back iterator which returns mutable values.
blake2-ppc70523712013-07-10 13:27:14187 pub fn mut_iter<'a>(&'a mut self) -> RingBufMutIterator<'a, T> {
blake2-ppcf6862132013-07-29 18:16:26188 RingBufMutIterator{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts}
Jed Estep4f7a7422013-06-25 19:08:47189 }
190
191 /// Back-to-front iterator which returns mutable values.
blake2-ppc4b45f472013-07-27 21:41:20192 pub fn mut_rev_iter<'a>(&'a mut self) -> Invert<RingBufMutIterator<'a, T>> {
blake2-ppc3385e792013-07-15 23:13:26193 self.mut_iter().invert()
Jed Estep4f7a7422013-06-25 19:08:47194 }
195}
196
Jed Estep35314c92013-06-26 15:38:29197macro_rules! iterator {
blake2-ppc3385e792013-07-15 23:13:26198 (impl $name:ident -> $elem:ty, $getter:ident) => {
Jed Estep35314c92013-06-26 15:38:29199 impl<'self, T> Iterator<$elem> for $name<'self, T> {
200 #[inline]
201 fn next(&mut self) -> Option<$elem> {
blake2-ppcf6862132013-07-29 18:16:26202 if self.index == self.rindex {
Jed Estep35314c92013-06-26 15:38:29203 return None;
204 }
blake2-ppc75015c32013-07-06 03:42:45205 let raw_index = raw_index(self.lo, self.elts.len(), self.index);
blake2-ppc3385e792013-07-15 23:13:26206 self.index += 1;
blake2-ppcf6862132013-07-29 18:16:26207 Some(self.elts[raw_index] . $getter ())
Jed Estep35314c92013-06-26 15:38:29208 }
blake2-ppc9ccf4432013-07-14 20:30:22209
210 #[inline]
211 fn size_hint(&self) -> (uint, Option<uint>) {
blake2-ppcf6862132013-07-29 18:16:26212 let len = self.rindex - self.index;
213 (len, Some(len))
blake2-ppc9ccf4432013-07-14 20:30:22214 }
Jed Estep35314c92013-06-26 15:38:29215 }
216 }
217}
218
blake2-ppc3385e792013-07-15 23:13:26219macro_rules! iterator_rev {
220 (impl $name:ident -> $elem:ty, $getter:ident) => {
221 impl<'self, T> DoubleEndedIterator<$elem> for $name<'self, T> {
222 #[inline]
223 fn next_back(&mut self) -> Option<$elem> {
blake2-ppcf6862132013-07-29 18:16:26224 if self.index == self.rindex {
blake2-ppc3385e792013-07-15 23:13:26225 return None;
226 }
blake2-ppc3385e792013-07-15 23:13:26227 self.rindex -= 1;
blake2-ppcf6862132013-07-29 18:16:26228 let raw_index = raw_index(self.lo, self.elts.len(), self.rindex);
229 Some(self.elts[raw_index] . $getter ())
blake2-ppc3385e792013-07-15 23:13:26230 }
231 }
232 }
233}
234
blake2-ppcf6862132013-07-29 18:16:26235
blake2-ppc70523712013-07-10 13:27:14236/// RingBuf iterator
237pub struct RingBufIterator<'self, T> {
blake2-ppc75015c32013-07-06 03:42:45238 priv lo: uint,
blake2-ppc75015c32013-07-06 03:42:45239 priv index: uint,
blake2-ppc3385e792013-07-15 23:13:26240 priv rindex: uint,
blake2-ppc75015c32013-07-06 03:42:45241 priv elts: &'self [Option<T>],
Jed Estep4f7a7422013-06-25 19:08:47242}
blake2-ppc3385e792013-07-15 23:13:26243iterator!{impl RingBufIterator -> &'self T, get_ref}
244iterator_rev!{impl RingBufIterator -> &'self T, get_ref}
Jed Estep35314c92013-06-26 15:38:29245
blake2-ppcf6862132013-07-29 18:16:26246impl<'self, T> RandomAccessIterator<&'self T> for RingBufIterator<'self, T> {
247 #[inline]
248 fn indexable(&self) -> uint { self.rindex - self.index }
249
250 #[inline]
251 fn idx(&self, j: uint) -> Option<&'self T> {
252 if j >= self.indexable() {
253 None
254 } else {
255 let raw_index = raw_index(self.lo, self.elts.len(), self.index + j);
256 Some(self.elts[raw_index].get_ref())
257 }
258 }
259}
260
blake2-ppc70523712013-07-10 13:27:14261/// RingBuf mutable iterator
262pub struct RingBufMutIterator<'self, T> {
blake2-ppc75015c32013-07-06 03:42:45263 priv lo: uint,
blake2-ppc75015c32013-07-06 03:42:45264 priv index: uint,
blake2-ppc3385e792013-07-15 23:13:26265 priv rindex: uint,
blake2-ppc75015c32013-07-06 03:42:45266 priv elts: &'self mut [Option<T>],
Jed Estep4f7a7422013-06-25 19:08:47267}
blake2-ppc3385e792013-07-15 23:13:26268iterator!{impl RingBufMutIterator -> &'self mut T, get_mut_ref}
269iterator_rev!{impl RingBufMutIterator -> &'self mut T, get_mut_ref}
Daniel Micayb47e1e92013-02-16 22:55:55270
271/// Grow is only called on full elts, so nelts is also len(elts), unlike
272/// elsewhere.
blake2-ppc8a326762013-07-06 03:42:45273fn grow<T>(nelts: uint, loptr: &mut uint, elts: &mut ~[Option<T>]) {
Corey Richardsoncc57ca02013-05-19 02:02:45274 assert_eq!(nelts, elts.len());
blake2-ppc8a326762013-07-06 03:42:45275 let lo = *loptr;
276 let newlen = nelts * 2;
blake2-ppc40ce0b72013-07-06 03:42:45277 elts.reserve(newlen);
Daniel Micayb47e1e92013-02-16 22:55:55278
blake2-ppc40ce0b72013-07-06 03:42:45279 /* fill with None */
Daniel Micay100894552013-08-03 16:45:23280 for _ in range(elts.len(), elts.capacity()) {
blake2-ppc40ce0b72013-07-06 03:42:45281 elts.push(None);
Daniel Micayb47e1e92013-02-16 22:55:55282 }
blake2-ppc8a326762013-07-06 03:42:45283
284 /*
285 Move the shortest half into the newly reserved area.
286 lo ---->|
287 nelts ----------->|
288 [o o o|o o o o o]
289 A [. . .|o o o o o o o o|. . . . .]
290 B [o o o|. . . . . . . .|o o o o o]
291 */
292
293 assert!(newlen - nelts/2 >= nelts);
294 if lo <= (nelts - lo) { // A
Daniel Micay100894552013-08-03 16:45:23295 for i in range(0u, lo) {
blake2-ppc8a326762013-07-06 03:42:45296 elts.swap(i, nelts + i);
297 }
298 } else { // B
Daniel Micay100894552013-08-03 16:45:23299 for i in range(lo, nelts) {
blake2-ppc8a326762013-07-06 03:42:45300 elts.swap(i, newlen - nelts + i);
301 }
302 *loptr += newlen - nelts;
blake2-ppc40ce0b72013-07-06 03:42:45303 }
Daniel Micayb47e1e92013-02-16 22:55:55304}
305
blake2-ppc75015c32013-07-06 03:42:45306/// Return index in underlying vec for a given logical element index
307fn raw_index(lo: uint, len: uint, index: uint) -> uint {
308 if lo >= len - index {
309 lo + index - len
310 } else {
311 lo + index
312 }
313}
314
blake2-ppc70523712013-07-10 13:27:14315impl<A: Eq> Eq for RingBuf<A> {
316 fn eq(&self, other: &RingBuf<A>) -> bool {
blake2-ppc10c76982013-07-06 13:27:32317 self.nelts == other.nelts &&
318 self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
319 }
blake2-ppc70523712013-07-10 13:27:14320 fn ne(&self, other: &RingBuf<A>) -> bool {
blake2-ppc10c76982013-07-06 13:27:32321 !self.eq(other)
322 }
323}
324
blake2-ppc70523712013-07-10 13:27:14325impl<A, T: Iterator<A>> FromIterator<A, T> for RingBuf<A> {
326 fn from_iterator(iterator: &mut T) -> RingBuf<A> {
blake2-ppcf8ae5262013-07-30 00:06:49327 let (lower, _) = iterator.size_hint();
328 let mut deq = RingBuf::with_capacity(lower);
329 deq.extend(iterator);
blake2-ppc08dc72f2013-07-06 03:42:45330 deq
331 }
332}
333
blake2-ppcf8ae5262013-07-30 00:06:49334impl<A, T: Iterator<A>> Extendable<A, T> for RingBuf<A> {
335 fn extend(&mut self, iterator: &mut T) {
Daniel Micay100894552013-08-03 16:45:23336 for elt in *iterator {
blake2-ppcf8ae5262013-07-30 00:06:49337 self.push_back(elt);
338 }
339 }
340}
341
Brian Anderson6e27b272012-01-18 03:05:07342#[cfg(test)]
343mod tests {
Daniel Micayb47e1e92013-02-16 22:55:55344 use super::*;
Patrick Walton99b33f72013-07-02 19:47:32345 use std::clone::Clone;
Corey Richardson1662bd32013-06-28 22:32:26346 use std::cmp::Eq;
blake2-ppc81933ed2013-07-06 03:42:45347 use extra::test;
Patrick Waltonfa5ee932012-12-28 02:24:18348
Brian Anderson6e27b272012-01-18 03:05:07349 #[test]
350 fn test_simple() {
blake2-ppc70523712013-07-10 13:27:14351 let mut d = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:45352 assert_eq!(d.len(), 0u);
blake2-ppc70523712013-07-10 13:27:14353 d.push_front(17);
354 d.push_front(42);
355 d.push_back(137);
Corey Richardsoncc57ca02013-05-19 02:02:45356 assert_eq!(d.len(), 3u);
blake2-ppc70523712013-07-10 13:27:14357 d.push_back(137);
Corey Richardsoncc57ca02013-05-19 02:02:45358 assert_eq!(d.len(), 4u);
blake2-ppc70523712013-07-10 13:27:14359 debug!(d.front());
360 assert_eq!(*d.front().unwrap(), 42);
361 debug!(d.back());
362 assert_eq!(*d.back().unwrap(), 137);
363 let mut i = d.pop_front();
Brian Anderson82f19032013-03-08 20:39:42364 debug!(i);
blake2-ppc70523712013-07-10 13:27:14365 assert_eq!(i, Some(42));
Brian Anderson6e27b272012-01-18 03:05:07366 i = d.pop_back();
Brian Anderson82f19032013-03-08 20:39:42367 debug!(i);
blake2-ppc70523712013-07-10 13:27:14368 assert_eq!(i, Some(137));
Brian Anderson6e27b272012-01-18 03:05:07369 i = d.pop_back();
Brian Anderson82f19032013-03-08 20:39:42370 debug!(i);
blake2-ppc70523712013-07-10 13:27:14371 assert_eq!(i, Some(137));
Brian Anderson6e27b272012-01-18 03:05:07372 i = d.pop_back();
Brian Anderson82f19032013-03-08 20:39:42373 debug!(i);
blake2-ppc70523712013-07-10 13:27:14374 assert_eq!(i, Some(17));
Corey Richardsoncc57ca02013-05-19 02:02:45375 assert_eq!(d.len(), 0u);
blake2-ppc70523712013-07-10 13:27:14376 d.push_back(3);
Corey Richardsoncc57ca02013-05-19 02:02:45377 assert_eq!(d.len(), 1u);
blake2-ppc70523712013-07-10 13:27:14378 d.push_front(2);
Corey Richardsoncc57ca02013-05-19 02:02:45379 assert_eq!(d.len(), 2u);
blake2-ppc70523712013-07-10 13:27:14380 d.push_back(4);
Corey Richardsoncc57ca02013-05-19 02:02:45381 assert_eq!(d.len(), 3u);
blake2-ppc70523712013-07-10 13:27:14382 d.push_front(1);
Corey Richardsoncc57ca02013-05-19 02:02:45383 assert_eq!(d.len(), 4u);
Brian Anderson82f19032013-03-08 20:39:42384 debug!(d.get(0));
385 debug!(d.get(1));
386 debug!(d.get(2));
387 debug!(d.get(3));
Corey Richardsoncc57ca02013-05-19 02:02:45388 assert_eq!(*d.get(0), 1);
389 assert_eq!(*d.get(1), 2);
390 assert_eq!(*d.get(2), 3);
391 assert_eq!(*d.get(3), 4);
Brian Anderson6e27b272012-01-18 03:05:07392 }
393
Kevin Cantuc43426e2012-09-13 05:09:55394 #[test]
395 fn test_boxes() {
396 let a: @int = @5;
397 let b: @int = @72;
398 let c: @int = @64;
399 let d: @int = @175;
400
blake2-ppc70523712013-07-10 13:27:14401 let mut deq = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:45402 assert_eq!(deq.len(), 0);
blake2-ppc70523712013-07-10 13:27:14403 deq.push_front(a);
404 deq.push_front(b);
405 deq.push_back(c);
Corey Richardsoncc57ca02013-05-19 02:02:45406 assert_eq!(deq.len(), 3);
blake2-ppc70523712013-07-10 13:27:14407 deq.push_back(d);
Corey Richardsoncc57ca02013-05-19 02:02:45408 assert_eq!(deq.len(), 4);
blake2-ppc70523712013-07-10 13:27:14409 assert_eq!(deq.front(), Some(&b));
410 assert_eq!(deq.back(), Some(&d));
411 assert_eq!(deq.pop_front(), Some(b));
412 assert_eq!(deq.pop_back(), Some(d));
413 assert_eq!(deq.pop_back(), Some(c));
414 assert_eq!(deq.pop_back(), Some(a));
Corey Richardsoncc57ca02013-05-19 02:02:45415 assert_eq!(deq.len(), 0);
blake2-ppc70523712013-07-10 13:27:14416 deq.push_back(c);
Corey Richardsoncc57ca02013-05-19 02:02:45417 assert_eq!(deq.len(), 1);
blake2-ppc70523712013-07-10 13:27:14418 deq.push_front(b);
Corey Richardsoncc57ca02013-05-19 02:02:45419 assert_eq!(deq.len(), 2);
blake2-ppc70523712013-07-10 13:27:14420 deq.push_back(d);
Corey Richardsoncc57ca02013-05-19 02:02:45421 assert_eq!(deq.len(), 3);
blake2-ppc70523712013-07-10 13:27:14422 deq.push_front(a);
Corey Richardsoncc57ca02013-05-19 02:02:45423 assert_eq!(deq.len(), 4);
424 assert_eq!(*deq.get(0), a);
425 assert_eq!(*deq.get(1), b);
426 assert_eq!(*deq.get(2), c);
427 assert_eq!(*deq.get(3), d);
Daniel Micay373c0722013-02-17 00:10:10428 }
429
Felix S. Klock IIa636f512013-05-01 23:32:37430 #[cfg(test)]
Patrick Walton99b33f72013-07-02 19:47:32431 fn test_parameterized<T:Clone + Eq>(a: T, b: T, c: T, d: T) {
Patrick Waltondc4bf172013-07-13 04:05:59432 let mut deq = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:45433 assert_eq!(deq.len(), 0);
Patrick Waltondc4bf172013-07-13 04:05:59434 deq.push_front(a.clone());
435 deq.push_front(b.clone());
436 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45437 assert_eq!(deq.len(), 3);
Patrick Waltondc4bf172013-07-13 04:05:59438 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45439 assert_eq!(deq.len(), 4);
Patrick Waltondc4bf172013-07-13 04:05:59440 assert_eq!((*deq.front().get()).clone(), b.clone());
441 assert_eq!((*deq.back().get()).clone(), d.clone());
442 assert_eq!(deq.pop_front().get(), b.clone());
443 assert_eq!(deq.pop_back().get(), d.clone());
444 assert_eq!(deq.pop_back().get(), c.clone());
445 assert_eq!(deq.pop_back().get(), a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45446 assert_eq!(deq.len(), 0);
Patrick Waltondc4bf172013-07-13 04:05:59447 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45448 assert_eq!(deq.len(), 1);
Patrick Waltondc4bf172013-07-13 04:05:59449 deq.push_front(b.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45450 assert_eq!(deq.len(), 2);
Patrick Waltondc4bf172013-07-13 04:05:59451 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45452 assert_eq!(deq.len(), 3);
Patrick Waltondc4bf172013-07-13 04:05:59453 deq.push_front(a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45454 assert_eq!(deq.len(), 4);
Patrick Walton99b33f72013-07-02 19:47:32455 assert_eq!((*deq.get(0)).clone(), a.clone());
456 assert_eq!((*deq.get(1)).clone(), b.clone());
457 assert_eq!((*deq.get(2)).clone(), c.clone());
458 assert_eq!((*deq.get(3)).clone(), d.clone());
Brian Anderson6e27b272012-01-18 03:05:07459 }
460
blake2-ppc81933ed2013-07-06 03:42:45461 #[test]
blake2-ppc70523712013-07-10 13:27:14462 fn test_push_front_grow() {
463 let mut deq = RingBuf::new();
Daniel Micay100894552013-08-03 16:45:23464 for i in range(0u, 66) {
blake2-ppc70523712013-07-10 13:27:14465 deq.push_front(i);
blake2-ppc81933ed2013-07-06 03:42:45466 }
467 assert_eq!(deq.len(), 66);
468
Daniel Micay100894552013-08-03 16:45:23469 for i in range(0u, 66) {
blake2-ppc81933ed2013-07-06 03:42:45470 assert_eq!(*deq.get(i), 65 - i);
471 }
472
blake2-ppc70523712013-07-10 13:27:14473 let mut deq = RingBuf::new();
Daniel Micay100894552013-08-03 16:45:23474 for i in range(0u, 66) {
blake2-ppc70523712013-07-10 13:27:14475 deq.push_back(i);
blake2-ppc81933ed2013-07-06 03:42:45476 }
477
Daniel Micay100894552013-08-03 16:45:23478 for i in range(0u, 66) {
blake2-ppc81933ed2013-07-06 03:42:45479 assert_eq!(*deq.get(i), i);
480 }
481 }
482
483 #[bench]
484 fn bench_new(b: &mut test::BenchHarness) {
485 do b.iter {
blake2-ppc70523712013-07-10 13:27:14486 let _ = RingBuf::new::<u64>();
blake2-ppc81933ed2013-07-06 03:42:45487 }
488 }
489
490 #[bench]
blake2-ppc70523712013-07-10 13:27:14491 fn bench_push_back(b: &mut test::BenchHarness) {
492 let mut deq = RingBuf::new();
blake2-ppc81933ed2013-07-06 03:42:45493 do b.iter {
blake2-ppc70523712013-07-10 13:27:14494 deq.push_back(0);
blake2-ppc81933ed2013-07-06 03:42:45495 }
496 }
497
498 #[bench]
blake2-ppc70523712013-07-10 13:27:14499 fn bench_push_front(b: &mut test::BenchHarness) {
500 let mut deq = RingBuf::new();
blake2-ppc81933ed2013-07-06 03:42:45501 do b.iter {
blake2-ppc70523712013-07-10 13:27:14502 deq.push_front(0);
blake2-ppc81933ed2013-07-06 03:42:45503 }
504 }
505
506 #[bench]
507 fn bench_grow(b: &mut test::BenchHarness) {
blake2-ppc70523712013-07-10 13:27:14508 let mut deq = RingBuf::new();
blake2-ppc81933ed2013-07-06 03:42:45509 do b.iter {
blake2-ppc78cde5b2013-08-01 02:18:19510 do 65.times {
blake2-ppc70523712013-07-10 13:27:14511 deq.push_front(1);
blake2-ppc81933ed2013-07-06 03:42:45512 }
513 }
514 }
515
Patrick Walton99b33f72013-07-02 19:47:32516 #[deriving(Clone, Eq)]
517 enum Taggy {
518 One(int),
519 Two(int, int),
520 Three(int, int, int),
Brian Anderson6e27b272012-01-18 03:05:07521 }
522
Patrick Walton99b33f72013-07-02 19:47:32523 #[deriving(Clone, Eq)]
524 enum Taggypar<T> {
525 Onepar(int),
526 Twopar(int, int),
527 Threepar(int, int, int),
528 }
529
530 #[deriving(Clone, Eq)]
Erick Tryzelaare84576b2013-01-22 16:44:24531 struct RecCy {
532 x: int,
533 y: int,
Patrick Waltoneb4d39e2013-01-26 00:57:39534 t: Taggy
Patrick Walton9117dcb2012-09-20 01:00:26535 }
Kevin Cantuc43426e2012-09-13 05:09:55536
537 #[test]
538 fn test_param_int() {
539 test_parameterized::<int>(5, 72, 64, 175);
540 }
541
542 #[test]
543 fn test_param_at_int() {
544 test_parameterized::<@int>(@5, @72, @64, @175);
545 }
546
547 #[test]
548 fn test_param_taggy() {
Corey Richardsonf8ae9b02013-06-26 22:14:35549 test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:55550 }
551
552 #[test]
553 fn test_param_taggypar() {
554 test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
Ben Striegela605fd02012-08-11 14:08:42555 Twopar::<int>(1, 2),
556 Threepar::<int>(1, 2, 3),
557 Twopar::<int>(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:55558 }
Brian Anderson6e27b272012-01-18 03:05:07559
Kevin Cantuc43426e2012-09-13 05:09:55560 #[test]
561 fn test_param_reccy() {
Erick Tryzelaare84576b2013-01-22 16:44:24562 let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
563 let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
564 let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
565 let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
Kevin Cantuc43426e2012-09-13 05:09:55566 test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
Brian Anderson6e27b272012-01-18 03:05:07567 }
Erick Tryzelaar909d8f02013-03-30 01:02:44568
569 #[test]
blake2-ppc0ff5c172013-07-06 03:42:45570 fn test_with_capacity() {
blake2-ppc70523712013-07-10 13:27:14571 let mut d = RingBuf::with_capacity(0);
572 d.push_back(1);
blake2-ppc0ff5c172013-07-06 03:42:45573 assert_eq!(d.len(), 1);
blake2-ppc70523712013-07-10 13:27:14574 let mut d = RingBuf::with_capacity(50);
575 d.push_back(1);
blake2-ppc0ff5c172013-07-06 03:42:45576 assert_eq!(d.len(), 1);
577 }
578
579 #[test]
Tim Chevalier77de84b2013-05-27 18:47:38580 fn test_reserve() {
blake2-ppc70523712013-07-10 13:27:14581 let mut d = RingBuf::new();
582 d.push_back(0u64);
Tim Chevalier77de84b2013-05-27 18:47:38583 d.reserve(50);
Huon Wilson32d65592013-06-27 14:40:47584 assert_eq!(d.elts.capacity(), 50);
blake2-ppc70523712013-07-10 13:27:14585 let mut d = RingBuf::new();
586 d.push_back(0u32);
Tim Chevalier77de84b2013-05-27 18:47:38587 d.reserve(50);
Huon Wilson32d65592013-06-27 14:40:47588 assert_eq!(d.elts.capacity(), 50);
Tim Chevalier77de84b2013-05-27 18:47:38589 }
590
591 #[test]
592 fn test_reserve_at_least() {
blake2-ppc70523712013-07-10 13:27:14593 let mut d = RingBuf::new();
594 d.push_back(0u64);
Tim Chevalier77de84b2013-05-27 18:47:38595 d.reserve_at_least(50);
Huon Wilson32d65592013-06-27 14:40:47596 assert_eq!(d.elts.capacity(), 64);
blake2-ppc70523712013-07-10 13:27:14597 let mut d = RingBuf::new();
598 d.push_back(0u32);
Tim Chevalier77de84b2013-05-27 18:47:38599 d.reserve_at_least(50);
Huon Wilson32d65592013-06-27 14:40:47600 assert_eq!(d.elts.capacity(), 64);
Tim Chevalier77de84b2013-05-27 18:47:38601 }
602
Jed Estep096fb792013-06-26 14:04:44603 #[test]
604 fn test_iter() {
blake2-ppc70523712013-07-10 13:27:14605 let mut d = RingBuf::new();
blake2-ppcf88d5322013-07-06 03:42:45606 assert_eq!(d.iter().next(), None);
blake2-ppc9ccf4432013-07-14 20:30:22607 assert_eq!(d.iter().size_hint(), (0, Some(0)));
blake2-ppcf88d5322013-07-06 03:42:45608
Daniel Micay100894552013-08-03 16:45:23609 for i in range(0, 5) {
blake2-ppc70523712013-07-10 13:27:14610 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:44611 }
Corey Richardsonf8ae9b02013-06-26 22:14:35612 assert_eq!(d.iter().collect::<~[&int]>(), ~[&0,&1,&2,&3,&4]);
613
Daniel Micay100894552013-08-03 16:45:23614 for i in range(6, 9) {
blake2-ppc70523712013-07-10 13:27:14615 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:44616 }
Corey Richardsonf8ae9b02013-06-26 22:14:35617 assert_eq!(d.iter().collect::<~[&int]>(), ~[&8,&7,&6,&0,&1,&2,&3,&4]);
blake2-ppc9ccf4432013-07-14 20:30:22618
619 let mut it = d.iter();
620 let mut len = d.len();
621 loop {
622 match it.next() {
623 None => break,
624 _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
625 }
626 }
Jed Estep096fb792013-06-26 14:04:44627 }
628
629 #[test]
630 fn test_rev_iter() {
blake2-ppc70523712013-07-10 13:27:14631 let mut d = RingBuf::new();
blake2-ppcf88d5322013-07-06 03:42:45632 assert_eq!(d.rev_iter().next(), None);
633
Daniel Micay100894552013-08-03 16:45:23634 for i in range(0, 5) {
blake2-ppc70523712013-07-10 13:27:14635 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:44636 }
Corey Richardsonf8ae9b02013-06-26 22:14:35637 assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0]);
638
Daniel Micay100894552013-08-03 16:45:23639 for i in range(6, 9) {
blake2-ppc70523712013-07-10 13:27:14640 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:44641 }
Corey Richardsonf8ae9b02013-06-26 22:14:35642 assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]);
Jed Estep096fb792013-06-26 14:04:44643 }
blake2-ppc08dc72f2013-07-06 03:42:45644
645 #[test]
blake2-ppcf88d5322013-07-06 03:42:45646 fn test_mut_iter() {
blake2-ppc70523712013-07-10 13:27:14647 let mut d = RingBuf::new();
blake2-ppcf88d5322013-07-06 03:42:45648 assert!(d.mut_iter().next().is_none());
649
Daniel Micay100894552013-08-03 16:45:23650 for i in range(0u, 3) {
blake2-ppc70523712013-07-10 13:27:14651 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:45652 }
653
Daniel Micay100894552013-08-03 16:45:23654 for (i, elt) in d.mut_iter().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:45655 assert_eq!(*elt, 2 - i);
656 *elt = i;
657 }
658
659 {
660 let mut it = d.mut_iter();
661 assert_eq!(*it.next().unwrap(), 0);
662 assert_eq!(*it.next().unwrap(), 1);
663 assert_eq!(*it.next().unwrap(), 2);
664 assert!(it.next().is_none());
665 }
666 }
667
668 #[test]
669 fn test_mut_rev_iter() {
blake2-ppc70523712013-07-10 13:27:14670 let mut d = RingBuf::new();
blake2-ppcf88d5322013-07-06 03:42:45671 assert!(d.mut_rev_iter().next().is_none());
672
Daniel Micay100894552013-08-03 16:45:23673 for i in range(0u, 3) {
blake2-ppc70523712013-07-10 13:27:14674 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:45675 }
676
Daniel Micay100894552013-08-03 16:45:23677 for (i, elt) in d.mut_rev_iter().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:45678 assert_eq!(*elt, i);
679 *elt = i;
680 }
681
682 {
683 let mut it = d.mut_rev_iter();
684 assert_eq!(*it.next().unwrap(), 0);
685 assert_eq!(*it.next().unwrap(), 1);
686 assert_eq!(*it.next().unwrap(), 2);
687 assert!(it.next().is_none());
688 }
689 }
690
691 #[test]
blake2-ppc08dc72f2013-07-06 03:42:45692 fn test_from_iterator() {
693 use std::iterator;
694 let v = ~[1,2,3,4,5,6,7];
blake2-ppc70523712013-07-10 13:27:14695 let deq: RingBuf<int> = v.iter().transform(|&x| x).collect();
blake2-ppc08dc72f2013-07-06 03:42:45696 let u: ~[int] = deq.iter().transform(|&x| x).collect();
697 assert_eq!(u, v);
698
699 let mut seq = iterator::Counter::new(0u, 2).take_(256);
blake2-ppc70523712013-07-10 13:27:14700 let deq: RingBuf<uint> = seq.collect();
Daniel Micay100894552013-08-03 16:45:23701 for (i, &x) in deq.iter().enumerate() {
blake2-ppc08dc72f2013-07-06 03:42:45702 assert_eq!(2*i, x);
703 }
704 assert_eq!(deq.len(), 256);
705 }
blake2-ppc10c76982013-07-06 13:27:32706
707 #[test]
708 fn test_clone() {
blake2-ppc70523712013-07-10 13:27:14709 let mut d = RingBuf::new();
710 d.push_front(17);
711 d.push_front(42);
712 d.push_back(137);
713 d.push_back(137);
blake2-ppc10c76982013-07-06 13:27:32714 assert_eq!(d.len(), 4u);
715 let mut e = d.clone();
716 assert_eq!(e.len(), 4u);
717 while !d.is_empty() {
718 assert_eq!(d.pop_back(), e.pop_back());
719 }
720 assert_eq!(d.len(), 0u);
721 assert_eq!(e.len(), 0u);
722 }
723
724 #[test]
725 fn test_eq() {
blake2-ppc70523712013-07-10 13:27:14726 let mut d = RingBuf::new();
727 assert_eq!(&d, &RingBuf::with_capacity(0));
728 d.push_front(137);
729 d.push_front(17);
730 d.push_front(42);
731 d.push_back(137);
732 let mut e = RingBuf::with_capacity(0);
733 e.push_back(42);
734 e.push_back(17);
735 e.push_back(137);
736 e.push_back(137);
blake2-ppc10c76982013-07-06 13:27:32737 assert_eq!(&e, &d);
738 e.pop_back();
blake2-ppc70523712013-07-10 13:27:14739 e.push_back(0);
blake2-ppc10c76982013-07-06 13:27:32740 assert!(e != d);
741 e.clear();
blake2-ppc70523712013-07-10 13:27:14742 assert_eq!(e, RingBuf::new());
blake2-ppc10c76982013-07-06 13:27:32743 }
Michael Sullivanc854d6e2012-07-03 17:52:32744}