blob: 6aa083d67f578268d3556aaa5ffdf334b3295021 [file] [log] [blame]
Jonathan S03609e52014-04-21 04:59:121// Copyright 2012-2014 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
Steve Klabnik84030fd2014-08-30 21:11:2211//! This crate implements a double-ended queue with `O(1)` amortized inserts and removals from both
12//! ends of the container. It also has `O(1)` indexing like a vector. The contained elements are
13//! not required to be copyable, and the queue will be sendable if the contained type is sendable.
Patrick Waltonf3723cf2013-05-17 22:28:4414
Alex Crichton6a585372014-05-30 01:50:1215use core::prelude::*;
16
Tom Jakubowskid6a39412014-06-09 07:30:0417use core::default::Default;
Alex Crichton6a585372014-05-30 01:50:1218use core::fmt;
nham63615772014-07-27 03:18:5619use core::iter;
Colin Sherratt7a666df2014-10-19 20:19:0720use core::raw::Slice as RawSlice;
21use core::ptr;
22use core::kinds::marker;
23use core::mem;
Colin Sherratt6277e3b2014-11-14 09:21:4424use core::num::{Int, UnsignedInt};
Alex Crichton998fece2013-05-06 04:42:5425
Colin Sherratt7a666df2014-10-19 20:19:0726use std::hash::{Writer, Hash};
27use std::cmp;
28
29use alloc::heap;
blake2-ppc70523712013-07-10 13:27:1430
blake2-ppc0ff5c172013-07-06 03:42:4531static INITIAL_CAPACITY: uint = 8u; // 2^3
32static MINIMUM_CAPACITY: uint = 2u;
Daniel Micayb47e1e92013-02-16 22:55:5533
Alexis Beingessnercf3b2e42014-11-06 17:24:4734// FIXME(conventions): implement shrink_to_fit. Awkward with the current design, but it should
35// be scrapped anyway. Defer to rewrite?
Alexis Beingessnercf3b2e42014-11-06 17:24:4736
Tobias Bucher4a46f5e2014-12-09 22:05:1637/// `RingBuf` is a circular buffer, which can be used as a double-ended queue efficiently.
blake2-ppc70523712013-07-10 13:27:1438pub struct RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:0739 // tail and head are pointers into the buffer. Tail always points
40 // to the first element that could be read, Head always points
41 // to where data should be written.
42 // If tail == head the buffer is empty. The length of the ringbuf
43 // is defined as the distance between the two.
44
45 tail: uint,
46 head: uint,
47 cap: uint,
48 ptr: *mut T
49}
50
51impl<T: Clone> Clone for RingBuf<T> {
52 fn clone(&self) -> RingBuf<T> {
53 self.iter().map(|t| t.clone()).collect()
54 }
55}
56
57#[unsafe_destructor]
58impl<T> Drop for RingBuf<T> {
59 fn drop(&mut self) {
60 self.clear();
61 unsafe {
62 if mem::size_of::<T>() != 0 {
63 heap::deallocate(self.ptr as *mut u8,
64 self.cap * mem::size_of::<T>(),
65 mem::min_align_of::<T>())
66 }
67 }
68 }
Marijn Haverbeke26610db2012-01-11 11:49:3369}
Roy Frostig9c818892010-07-21 01:03:0970
Tom Jakubowskid6a39412014-06-09 07:30:0471impl<T> Default for RingBuf<T> {
72 #[inline]
73 fn default() -> RingBuf<T> { RingBuf::new() }
74}
75
blake2-ppc70523712013-07-10 13:27:1476impl<T> RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:0777 /// Turn ptr into a slice
78 #[inline]
79 unsafe fn buffer_as_slice(&self) -> &[T] {
80 mem::transmute(RawSlice { data: self.ptr as *const T, len: self.cap })
81 }
82
83 /// Moves an element out of the buffer
84 #[inline]
85 unsafe fn buffer_read(&mut self, off: uint) -> T {
86 ptr::read(self.ptr.offset(off as int) as *const T)
87 }
88
89 /// Writes an element into the buffer, moving it.
90 #[inline]
91 unsafe fn buffer_write(&mut self, off: uint, t: T) {
92 ptr::write(self.ptr.offset(off as int), t);
93 }
94
95 /// Returns true iff the buffer is at capacity
96 #[inline]
97 fn is_full(&self) -> bool { self.cap - self.len() == 1 }
Colin Sherratt40191182014-11-12 01:22:0798
99 /// Returns the index in the underlying buffer for a given logical element index.
100 #[inline]
101 fn wrap_index(&self, idx: uint) -> uint { wrap_index(idx, self.cap) }
Colin Sherratt7a666df2014-10-19 20:19:07102}
103
104impl<T> RingBuf<T> {
P1startf2aa88c2014-08-04 10:48:39105 /// Creates an empty `RingBuf`.
Alexis Beingessnercf3b2e42014-11-06 17:24:47106 #[unstable = "matches collection reform specification, waiting for dust to settle"]
blake2-ppc70523712013-07-10 13:27:14107 pub fn new() -> RingBuf<T> {
108 RingBuf::with_capacity(INITIAL_CAPACITY)
109 }
110
P1startf2aa88c2014-08-04 10:48:39111 /// Creates an empty `RingBuf` with space for at least `n` elements.
Alexis Beingessnercf3b2e42014-11-06 17:24:47112 #[unstable = "matches collection reform specification, waiting for dust to settle"]
blake2-ppc70523712013-07-10 13:27:14113 pub fn with_capacity(n: uint) -> RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:07114 // +1 since the ringbuffer always leaves one space empty
Colin Sherratt6277e3b2014-11-14 09:21:44115 let cap = cmp::max(n + 1, MINIMUM_CAPACITY).next_power_of_two();
116 let size = cap.checked_mul(mem::size_of::<T>())
Colin Sherratt7a666df2014-10-19 20:19:07117 .expect("capacity overflow");
118
Colin Sherrattba24e332014-11-10 03:34:53119 let ptr = if mem::size_of::<T>() != 0 {
120 unsafe {
121 let ptr = heap::allocate(size, mem::min_align_of::<T>()) as *mut T;;
122 if ptr.is_null() { ::alloc::oom() }
123 ptr
124 }
125 } else {
126 heap::EMPTY as *mut T
127 };
128
Colin Sherratt7a666df2014-10-19 20:19:07129 RingBuf {
130 tail: 0,
131 head: 0,
132 cap: cap,
Colin Sherrattba24e332014-11-10 03:34:53133 ptr: ptr
Colin Sherratt7a666df2014-10-19 20:19:07134 }
blake2-ppc70523712013-07-10 13:27:14135 }
136
P1startf2aa88c2014-08-04 10:48:39137 /// Retrieves an element in the `RingBuf` by index.
blake2-ppc70523712013-07-10 13:27:14138 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47139 /// # Example
140 ///
141 /// ```rust
142 /// use std::collections::RingBuf;
143 ///
144 /// let mut buf = RingBuf::new();
145 /// buf.push_back(3i);
146 /// buf.push_back(4);
147 /// buf.push_back(5);
148 /// assert_eq!(buf.get(1).unwrap(), &4);
149 /// ```
150 #[unstable = "matches collection reform specification, waiting for dust to settle"]
151 pub fn get(&self, i: uint) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07152 if i < self.len() {
Colin Sherratt40191182014-11-12 01:22:07153 let idx = self.wrap_index(self.tail + i);
Colin Sherratt7a666df2014-10-19 20:19:07154 unsafe { Some(&*self.ptr.offset(idx as int)) }
155 } else {
156 None
Alexis Beingessnercf3b2e42014-11-06 17:24:47157 }
158 }
159
160 /// Retrieves an element in the `RingBuf` mutably by index.
nhamebe80972014-07-17 23:19:51161 ///
162 /// # Example
163 ///
164 /// ```rust
165 /// use std::collections::RingBuf;
166 ///
167 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47168 /// buf.push_back(3i);
169 /// buf.push_back(4);
170 /// buf.push_back(5);
171 /// match buf.get_mut(1) {
172 /// None => {}
173 /// Some(elem) => {
174 /// *elem = 7;
175 /// }
176 /// }
177 ///
P1startfd10d202014-08-02 06:39:39178 /// assert_eq!(buf[1], 7);
nhamebe80972014-07-17 23:19:51179 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47180 #[unstable = "matches collection reform specification, waiting for dust to settle"]
181 pub fn get_mut(&mut self, i: uint) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07182 if i < self.len() {
Colin Sherratt40191182014-11-12 01:22:07183 let idx = self.wrap_index(self.tail + i);
Colin Sherratt7a666df2014-10-19 20:19:07184 unsafe { Some(&mut *self.ptr.offset(idx as int)) }
185 } else {
186 None
Alexis Beingessnercf3b2e42014-11-06 17:24:47187 }
blake2-ppc70523712013-07-10 13:27:14188 }
189
P1startf2aa88c2014-08-04 10:48:39190 /// Swaps elements at indices `i` and `j`.
blake2-ppc57757a82013-09-26 07:19:26191 ///
192 /// `i` and `j` may be equal.
193 ///
P1startf2aa88c2014-08-04 10:48:39194 /// Fails if there is no element with either index.
nhamebe80972014-07-17 23:19:51195 ///
196 /// # Example
197 ///
198 /// ```rust
199 /// use std::collections::RingBuf;
200 ///
201 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47202 /// buf.push_back(3i);
203 /// buf.push_back(4);
204 /// buf.push_back(5);
nhamebe80972014-07-17 23:19:51205 /// buf.swap(0, 2);
P1startfd10d202014-08-02 06:39:39206 /// assert_eq!(buf[0], 5);
207 /// assert_eq!(buf[2], 3);
nhamebe80972014-07-17 23:19:51208 /// ```
blake2-ppc57757a82013-09-26 07:19:26209 pub fn swap(&mut self, i: uint, j: uint) {
210 assert!(i < self.len());
211 assert!(j < self.len());
Colin Sherratt40191182014-11-12 01:22:07212 let ri = self.wrap_index(self.tail + i);
213 let rj = self.wrap_index(self.tail + j);
Colin Sherratt7a666df2014-10-19 20:19:07214 unsafe {
215 ptr::swap(self.ptr.offset(ri as int), self.ptr.offset(rj as int))
216 }
blake2-ppc70523712013-07-10 13:27:14217 }
218
Alexis Beingessnercf3b2e42014-11-06 17:24:47219 /// Returns the number of elements the `RingBuf` can hold without
220 /// reallocating.
221 ///
222 /// # Example
223 ///
224 /// ```
225 /// use std::collections::RingBuf;
226 ///
227 /// let buf: RingBuf<int> = RingBuf::with_capacity(10);
Colin Sherratt7a666df2014-10-19 20:19:07228 /// assert!(buf.capacity() >= 10);
Alexis Beingessnercf3b2e42014-11-06 17:24:47229 /// ```
230 #[inline]
231 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Colin Sherratt7a666df2014-10-19 20:19:07232 pub fn capacity(&self) -> uint { self.cap - 1 }
Tim Chevalier77de84b2013-05-27 18:47:38233
Alexis Beingessnercf3b2e42014-11-06 17:24:47234 /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
235 /// given `RingBuf`. Does nothing if the capacity is already sufficient.
Tim Chevalier77de84b2013-05-27 18:47:38236 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47237 /// Note that the allocator may give the collection more space than it requests. Therefore
238 /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
239 /// insertions are expected.
240 ///
241 /// # Panics
242 ///
243 /// Panics if the new capacity overflows `uint`.
244 ///
245 /// # Example
246 ///
247 /// ```
248 /// use std::collections::RingBuf;
249 ///
250 /// let mut buf: RingBuf<int> = vec![1].into_iter().collect();
251 /// buf.reserve_exact(10);
252 /// assert!(buf.capacity() >= 11);
253 /// ```
254 #[unstable = "matches collection reform specification, waiting for dust to settle"]
255 pub fn reserve_exact(&mut self, additional: uint) {
Colin Sherratt7a666df2014-10-19 20:19:07256 self.reserve(additional);
Alexis Beingessnercf3b2e42014-11-06 17:24:47257 }
258
259 /// Reserves capacity for at least `additional` more elements to be inserted in the given
260 /// `Ringbuf`. The collection may reserve more space to avoid frequent reallocations.
261 ///
262 /// # Panics
263 ///
264 /// Panics if the new capacity overflows `uint`.
265 ///
266 /// # Example
267 ///
268 /// ```
269 /// use std::collections::RingBuf;
270 ///
271 /// let mut buf: RingBuf<int> = vec![1].into_iter().collect();
272 /// buf.reserve(10);
273 /// assert!(buf.capacity() >= 11);
274 /// ```
275 #[unstable = "matches collection reform specification, waiting for dust to settle"]
276 pub fn reserve(&mut self, additional: uint) {
Colin Sherratt7a666df2014-10-19 20:19:07277 let new_len = self.len() + additional;
278 assert!(new_len + 1 > self.len(), "capacity overflow");
279 if new_len > self.capacity() {
Colin Sherratt6277e3b2014-11-14 09:21:44280 let count = (new_len + 1).next_power_of_two();
Colin Sherratt7a666df2014-10-19 20:19:07281 assert!(count >= new_len + 1);
282
283 if mem::size_of::<T>() != 0 {
284 let old = self.cap * mem::size_of::<T>();
Colin Sherratt6277e3b2014-11-14 09:21:44285 let new = count.checked_mul(mem::size_of::<T>())
Colin Sherratt7a666df2014-10-19 20:19:07286 .expect("capacity overflow");
287 unsafe {
288 self.ptr = heap::reallocate(self.ptr as *mut u8,
289 old,
290 new,
291 mem::min_align_of::<T>()) as *mut T;
Colin Sherrattba24e332014-11-10 03:34:53292 if self.ptr.is_null() { ::alloc::oom() }
Colin Sherratt7a666df2014-10-19 20:19:07293 }
294 }
295
296 // Move the shortest contiguous section of the ring buffer
297 // T H
298 // [o o o o o o o . ]
299 // T H
300 // A [o o o o o o o . . . . . . . . . ]
301 // H T
302 // [o o . o o o o o ]
303 // T H
304 // B [. . . o o o o o o o . . . . . . ]
305 // H T
306 // [o o o o o . o o ]
307 // H T
308 // C [o o o o o . . . . . . . . . o o ]
309
310 let oldcap = self.cap;
311 self.cap = count;
312
313 if self.tail <= self.head { // A
314 // Nop
315 } else if self.head < oldcap - self.tail { // B
316 unsafe {
317 ptr::copy_nonoverlapping_memory(
318 self.ptr.offset(oldcap as int),
319 self.ptr as *const T,
320 self.head
321 );
322 }
323 self.head += oldcap;
Colin Sherratt4cae9ad2014-11-11 02:16:29324 debug_assert!(self.head > self.tail);
Colin Sherratt7a666df2014-10-19 20:19:07325 } else { // C
326 unsafe {
327 ptr::copy_nonoverlapping_memory(
328 self.ptr.offset((count - (oldcap - self.tail)) as int),
329 self.ptr.offset(self.tail as int) as *const T,
330 oldcap - self.tail
331 );
332 }
333 self.tail = count - (oldcap - self.tail);
Colin Sherratt4cae9ad2014-11-11 02:16:29334 debug_assert!(self.head < self.tail);
Colin Sherratt7a666df2014-10-19 20:19:07335 }
Colin Sherratt4cae9ad2014-11-11 02:16:29336 debug_assert!(self.head < self.cap);
337 debug_assert!(self.tail < self.cap);
Colin Sherratt40191182014-11-12 01:22:07338 debug_assert!(self.cap.count_ones() == 1);
Colin Sherratt7a666df2014-10-19 20:19:07339 }
Tim Chevalier77de84b2013-05-27 18:47:38340 }
Jed Estep4f7a7422013-06-25 19:08:47341
P1startf2aa88c2014-08-04 10:48:39342 /// Returns a front-to-back iterator.
nhamebe80972014-07-17 23:19:51343 ///
344 /// # Example
345 ///
346 /// ```rust
347 /// use std::collections::RingBuf;
348 ///
349 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47350 /// buf.push_back(5i);
351 /// buf.push_back(3);
352 /// buf.push_back(4);
Nick Cameron52ef4622014-08-06 09:59:40353 /// let b: &[_] = &[&5, &3, &4];
354 /// assert_eq!(buf.iter().collect::<Vec<&int>>().as_slice(), b);
nhamebe80972014-07-17 23:19:51355 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47356 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24357 pub fn iter(&self) -> Items<T> {
Colin Sherratt7a666df2014-10-19 20:19:07358 Items {
359 tail: self.tail,
360 head: self.head,
361 ring: unsafe { self.buffer_as_slice() }
362 }
blake2-ppc3385e792013-07-15 23:13:26363 }
364
P1startf2aa88c2014-08-04 10:48:39365 /// Returns a front-to-back iterator which returns mutable references.
nhamebe80972014-07-17 23:19:51366 ///
367 /// # Example
368 ///
369 /// ```rust
370 /// use std::collections::RingBuf;
371 ///
372 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47373 /// buf.push_back(5i);
374 /// buf.push_back(3);
375 /// buf.push_back(4);
Aaron Turonfc525ee2014-09-15 03:27:36376 /// for num in buf.iter_mut() {
nhamebe80972014-07-17 23:19:51377 /// *num = *num - 2;
378 /// }
Nick Cameron52ef4622014-08-06 09:59:40379 /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
Nick Cameron59976942014-09-24 11:41:09380 /// assert_eq!(buf.iter_mut().collect::<Vec<&mut int>>()[], b);
nhamebe80972014-07-17 23:19:51381 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47382 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Colin Sherratt7a666df2014-10-19 20:19:07383 pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {
384 MutItems {
385 tail: self.tail,
386 head: self.head,
387 cap: self.cap,
388 ptr: self.ptr,
389 marker: marker::ContravariantLifetime::<'a>,
390 marker2: marker::NoCopy
Niko Matsakisbc4164d2013-11-16 22:29:39391 }
Jed Estep4f7a7422013-06-25 19:08:47392 }
Alex Crichton21ac9852014-10-30 20:43:24393
Alexis Beingessner865c2db2014-11-23 02:34:11394 /// Consumes the list into an iterator yielding elements by value.
395 #[unstable = "matches collection reform specification, waiting for dust to settle"]
396 pub fn into_iter(self) -> MoveItems<T> {
397 MoveItems {
398 inner: self,
399 }
400 }
401
Alex Crichton21ac9852014-10-30 20:43:24402 /// Returns the number of elements in the `RingBuf`.
403 ///
404 /// # Example
405 ///
406 /// ```
407 /// use std::collections::RingBuf;
408 ///
409 /// let mut v = RingBuf::new();
410 /// assert_eq!(v.len(), 0);
Alexis Beingessnercf3b2e42014-11-06 17:24:47411 /// v.push_back(1i);
Alex Crichton21ac9852014-10-30 20:43:24412 /// assert_eq!(v.len(), 1);
413 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47414 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Colin Sherratt7a666df2014-10-19 20:19:07415 pub fn len(&self) -> uint { count(self.tail, self.head, self.cap) }
Alex Crichton21ac9852014-10-30 20:43:24416
417 /// Returns true if the buffer contains no elements
418 ///
419 /// # Example
420 ///
421 /// ```
422 /// use std::collections::RingBuf;
423 ///
424 /// let mut v = RingBuf::new();
425 /// assert!(v.is_empty());
426 /// v.push_front(1i);
427 /// assert!(!v.is_empty());
428 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47429 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24430 pub fn is_empty(&self) -> bool { self.len() == 0 }
431
432 /// Clears the buffer, removing all values.
433 ///
434 /// # Example
435 ///
436 /// ```
437 /// use std::collections::RingBuf;
438 ///
439 /// let mut v = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47440 /// v.push_back(1i);
Alex Crichton21ac9852014-10-30 20:43:24441 /// v.clear();
442 /// assert!(v.is_empty());
443 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47444 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24445 pub fn clear(&mut self) {
Colin Sherrattba24e332014-11-10 03:34:53446 while self.pop_front().is_some() {}
Colin Sherratt7a666df2014-10-19 20:19:07447 self.head = 0;
448 self.tail = 0;
Alex Crichton21ac9852014-10-30 20:43:24449 }
450
451 /// Provides a reference to the front element, or `None` if the sequence is
452 /// empty.
453 ///
454 /// # Example
455 ///
456 /// ```
457 /// use std::collections::RingBuf;
458 ///
459 /// let mut d = RingBuf::new();
460 /// assert_eq!(d.front(), None);
461 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47462 /// d.push_back(1i);
463 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24464 /// assert_eq!(d.front(), Some(&1i));
465 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47466 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24467 pub fn front(&self) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07468 if !self.is_empty() { Some(&self[0]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24469 }
470
471 /// Provides a mutable reference to the front element, or `None` if the
472 /// sequence is empty.
473 ///
474 /// # Example
475 ///
476 /// ```
477 /// use std::collections::RingBuf;
478 ///
479 /// let mut d = RingBuf::new();
480 /// assert_eq!(d.front_mut(), None);
481 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47482 /// d.push_back(1i);
483 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24484 /// match d.front_mut() {
485 /// Some(x) => *x = 9i,
486 /// None => (),
487 /// }
488 /// assert_eq!(d.front(), Some(&9i));
489 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47490 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24491 pub fn front_mut(&mut self) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07492 if !self.is_empty() { Some(&mut self[0]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24493 }
494
495 /// Provides a reference to the back element, or `None` if the sequence is
496 /// empty.
497 ///
498 /// # Example
499 ///
500 /// ```
501 /// use std::collections::RingBuf;
502 ///
503 /// let mut d = RingBuf::new();
504 /// assert_eq!(d.back(), None);
505 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47506 /// d.push_back(1i);
507 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24508 /// assert_eq!(d.back(), Some(&2i));
509 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47510 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24511 pub fn back(&self) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07512 if !self.is_empty() { Some(&self[self.len() - 1]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24513 }
514
515 /// Provides a mutable reference to the back element, or `None` if the
516 /// sequence is empty.
517 ///
518 /// # Example
519 ///
520 /// ```
521 /// use std::collections::RingBuf;
522 ///
523 /// let mut d = RingBuf::new();
524 /// assert_eq!(d.back(), None);
525 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47526 /// d.push_back(1i);
527 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24528 /// match d.back_mut() {
529 /// Some(x) => *x = 9i,
530 /// None => (),
531 /// }
532 /// assert_eq!(d.back(), Some(&9i));
533 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47534 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24535 pub fn back_mut(&mut self) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07536 let len = self.len();
537 if !self.is_empty() { Some(&mut self[len - 1]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24538 }
539
540 /// Removes the first element and returns it, or `None` if the sequence is
541 /// empty.
542 ///
543 /// # Example
544 ///
545 /// ```
546 /// use std::collections::RingBuf;
547 ///
548 /// let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47549 /// d.push_back(1i);
550 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24551 ///
552 /// assert_eq!(d.pop_front(), Some(1i));
553 /// assert_eq!(d.pop_front(), Some(2i));
554 /// assert_eq!(d.pop_front(), None);
555 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47556 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24557 pub fn pop_front(&mut self) -> Option<T> {
Colin Sherratt7a666df2014-10-19 20:19:07558 if self.is_empty() {
559 None
560 } else {
561 let tail = self.tail;
Colin Sherratt40191182014-11-12 01:22:07562 self.tail = self.wrap_index(self.tail + 1);
Colin Sherratt7a666df2014-10-19 20:19:07563 unsafe { Some(self.buffer_read(tail)) }
Alex Crichton21ac9852014-10-30 20:43:24564 }
Alex Crichton21ac9852014-10-30 20:43:24565 }
566
567 /// Inserts an element first in the sequence.
568 ///
569 /// # Example
570 ///
571 /// ```
572 /// use std::collections::RingBuf;
573 ///
574 /// let mut d = RingBuf::new();
575 /// d.push_front(1i);
576 /// d.push_front(2i);
577 /// assert_eq!(d.front(), Some(&2i));
578 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47579 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24580 pub fn push_front(&mut self, t: T) {
Colin Sherratt4cae9ad2014-11-11 02:16:29581 if self.is_full() {
582 self.reserve(1);
583 debug_assert!(!self.is_full());
584 }
Colin Sherratt7a666df2014-10-19 20:19:07585
Colin Sherratt40191182014-11-12 01:22:07586 self.tail = self.wrap_index(self.tail - 1);
Colin Sherratt7a666df2014-10-19 20:19:07587 let tail = self.tail;
588 unsafe { self.buffer_write(tail, t); }
Alex Crichton21ac9852014-10-30 20:43:24589 }
590
Alexis Beingessnercf3b2e42014-11-06 17:24:47591 /// Deprecated: Renamed to `push_back`.
592 #[deprecated = "Renamed to `push_back`"]
593 pub fn push(&mut self, t: T) {
594 self.push_back(t)
595 }
596
Alex Crichton21ac9852014-10-30 20:43:24597 /// Appends an element to the back of a buffer
598 ///
599 /// # Example
600 ///
601 /// ```rust
602 /// use std::collections::RingBuf;
603 ///
604 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47605 /// buf.push_back(1i);
606 /// buf.push_back(3);
Alex Crichton21ac9852014-10-30 20:43:24607 /// assert_eq!(3, *buf.back().unwrap());
608 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47609 #[unstable = "matches collection reform specification, waiting for dust to settle"]
610 pub fn push_back(&mut self, t: T) {
Colin Sherratt4cae9ad2014-11-11 02:16:29611 if self.is_full() {
612 self.reserve(1);
613 debug_assert!(!self.is_full());
614 }
Colin Sherratt7a666df2014-10-19 20:19:07615
616 let head = self.head;
Colin Sherratt40191182014-11-12 01:22:07617 self.head = self.wrap_index(self.head + 1);
Colin Sherratt7a666df2014-10-19 20:19:07618 unsafe { self.buffer_write(head, t) }
Alex Crichton21ac9852014-10-30 20:43:24619 }
620
Alexis Beingessnercf3b2e42014-11-06 17:24:47621 /// Deprecated: Renamed to `pop_back`.
622 #[deprecated = "Renamed to `pop_back`"]
623 pub fn pop(&mut self) -> Option<T> {
624 self.pop_back()
625 }
626
Alex Crichton21ac9852014-10-30 20:43:24627 /// Removes the last element from a buffer and returns it, or `None` if
628 /// it is empty.
629 ///
630 /// # Example
631 ///
632 /// ```rust
633 /// use std::collections::RingBuf;
634 ///
635 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47636 /// assert_eq!(buf.pop_back(), None);
637 /// buf.push_back(1i);
638 /// buf.push_back(3);
639 /// assert_eq!(buf.pop_back(), Some(3));
Alex Crichton21ac9852014-10-30 20:43:24640 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47641 #[unstable = "matches collection reform specification, waiting for dust to settle"]
642 pub fn pop_back(&mut self) -> Option<T> {
Colin Sherratt7a666df2014-10-19 20:19:07643 if self.is_empty() {
Alex Crichton21ac9852014-10-30 20:43:24644 None
Colin Sherratt7a666df2014-10-19 20:19:07645 } else {
Colin Sherratt40191182014-11-12 01:22:07646 self.head = self.wrap_index(self.head - 1);
Colin Sherratt7a666df2014-10-19 20:19:07647 let head = self.head;
648 unsafe { Some(self.buffer_read(head)) }
Alex Crichton21ac9852014-10-30 20:43:24649 }
650 }
Jed Estep4f7a7422013-06-25 19:08:47651}
652
Colin Sherratt7a666df2014-10-19 20:19:07653/// Returns the index in the underlying buffer for a given logical element index.
654#[inline]
655fn wrap_index(index: uint, size: uint) -> uint {
656 // size is always a power of 2
Colin Sherratt40191182014-11-12 01:22:07657 index & (size - 1)
Colin Sherratt7a666df2014-10-19 20:19:07658}
659
660/// Calculate the number of elements left to be read in the buffer
661#[inline]
662fn count(tail: uint, head: uint, size: uint) -> uint {
663 // size is always a power of 2
664 (head - tail) & (size - 1)
665}
666
Niko Matsakis1b487a82014-08-28 01:46:52667/// `RingBuf` iterator.
Niko Matsakis1b487a82014-08-28 01:46:52668pub struct Items<'a, T:'a> {
Colin Sherratt7a666df2014-10-19 20:19:07669 ring: &'a [T],
670 tail: uint,
671 head: uint
Niko Matsakis1b487a82014-08-28 01:46:52672}
673
Palmer Cox3fd8c8b2014-01-15 03:32:24674impl<'a, T> Iterator<&'a T> for Items<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:39675 #[inline]
Erik Price5731ca32013-12-10 07:16:18676 fn next(&mut self) -> Option<&'a T> {
Colin Sherratt7a666df2014-10-19 20:19:07677 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:39678 return None;
679 }
Colin Sherratt7a666df2014-10-19 20:19:07680 let tail = self.tail;
681 self.tail = wrap_index(self.tail + 1, self.ring.len());
682 unsafe { Some(self.ring.unsafe_get(tail)) }
Niko Matsakisbc4164d2013-11-16 22:29:39683 }
684
685 #[inline]
686 fn size_hint(&self) -> (uint, Option<uint>) {
Colin Sherratt7a666df2014-10-19 20:19:07687 let len = count(self.tail, self.head, self.ring.len());
Niko Matsakisbc4164d2013-11-16 22:29:39688 (len, Some(len))
689 }
690}
691
Palmer Cox3fd8c8b2014-01-15 03:32:24692impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:39693 #[inline]
Erik Price5731ca32013-12-10 07:16:18694 fn next_back(&mut self) -> Option<&'a T> {
Colin Sherratt7a666df2014-10-19 20:19:07695 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:39696 return None;
697 }
Colin Sherratt7a666df2014-10-19 20:19:07698 self.head = wrap_index(self.head - 1, self.ring.len());
699 unsafe { Some(self.ring.unsafe_get(self.head)) }
Niko Matsakisbc4164d2013-11-16 22:29:39700 }
701}
Jed Estep35314c92013-06-26 15:38:29702
Aaron Turonb299c2b2014-11-06 17:32:37703impl<'a, T> ExactSizeIterator<&'a T> for Items<'a, T> {}
blake2-ppc7c369ee72013-09-01 16:20:24704
Palmer Cox3fd8c8b2014-01-15 03:32:24705impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
blake2-ppcf6862132013-07-29 18:16:26706 #[inline]
Colin Sherratt7a666df2014-10-19 20:19:07707 fn indexable(&self) -> uint {
708 let (len, _) = self.size_hint();
709 len
710 }
blake2-ppcf6862132013-07-29 18:16:26711
712 #[inline]
Alex Crichtonf4083a22014-04-22 05:15:42713 fn idx(&mut self, j: uint) -> Option<&'a T> {
blake2-ppcf6862132013-07-29 18:16:26714 if j >= self.indexable() {
715 None
716 } else {
Colin Sherratt7a666df2014-10-19 20:19:07717 let idx = wrap_index(self.tail + j, self.ring.len());
718 unsafe { Some(self.ring.unsafe_get(idx)) }
blake2-ppcf6862132013-07-29 18:16:26719 }
720 }
721}
722
Colin Sherratt7a666df2014-10-19 20:19:07723// FIXME This was implemented differently from Items because of a problem
724// with returning the mutable reference. I couldn't find a way to
725// make the lifetime checker happy so, but there should be a way.
Niko Matsakis1b487a82014-08-28 01:46:52726/// `RingBuf` mutable iterator.
Niko Matsakis1b487a82014-08-28 01:46:52727pub struct MutItems<'a, T:'a> {
Colin Sherratt7a666df2014-10-19 20:19:07728 ptr: *mut T,
729 tail: uint,
730 head: uint,
731 cap: uint,
732 marker: marker::ContravariantLifetime<'a>,
733 marker2: marker::NoCopy
Niko Matsakis1b487a82014-08-28 01:46:52734}
735
Palmer Cox3fd8c8b2014-01-15 03:32:24736impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:39737 #[inline]
Erik Price5731ca32013-12-10 07:16:18738 fn next(&mut self) -> Option<&'a mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07739 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:39740 return None;
741 }
Colin Sherratt7a666df2014-10-19 20:19:07742 let tail = self.tail;
743 self.tail = wrap_index(self.tail + 1, self.cap);
Alexis Beingessner865c2db2014-11-23 02:34:11744
745 unsafe {
746 Some(&mut *self.ptr.offset(tail as int))
Alex Crichton9d5d97b2014-10-15 06:05:01747 }
Niko Matsakisbc4164d2013-11-16 22:29:39748 }
749
750 #[inline]
751 fn size_hint(&self) -> (uint, Option<uint>) {
Colin Sherratt7a666df2014-10-19 20:19:07752 let len = count(self.tail, self.head, self.cap);
753 (len, Some(len))
Niko Matsakisbc4164d2013-11-16 22:29:39754 }
755}
756
Palmer Cox3fd8c8b2014-01-15 03:32:24757impl<'a, T> DoubleEndedIterator<&'a mut T> for MutItems<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:39758 #[inline]
Erik Price5731ca32013-12-10 07:16:18759 fn next_back(&mut self) -> Option<&'a mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07760 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:39761 return None;
762 }
Colin Sherratt7a666df2014-10-19 20:19:07763 self.head = wrap_index(self.head - 1, self.cap);
Alexis Beingessner865c2db2014-11-23 02:34:11764
765 unsafe {
766 Some(&mut *self.ptr.offset(self.head as int))
767 }
Niko Matsakisbc4164d2013-11-16 22:29:39768 }
769}
Daniel Micayb47e1e92013-02-16 22:55:55770
Aaron Turonb299c2b2014-11-06 17:32:37771impl<'a, T> ExactSizeIterator<&'a mut T> for MutItems<'a, T> {}
blake2-ppc7c369ee72013-09-01 16:20:24772
Alexis Beingessner865c2db2014-11-23 02:34:11773// A by-value RingBuf iterator
774pub struct MoveItems<T> {
775 inner: RingBuf<T>,
776}
777
778impl<T> Iterator<T> for MoveItems<T> {
779 #[inline]
780 fn next(&mut self) -> Option<T> {
781 self.inner.pop_front()
782 }
783
784 #[inline]
785 fn size_hint(&self) -> (uint, Option<uint>) {
786 let len = self.inner.len();
787 (len, Some(len))
788 }
789}
790
791impl<T> DoubleEndedIterator<T> for MoveItems<T> {
792 #[inline]
793 fn next_back(&mut self) -> Option<T> {
794 self.inner.pop_back()
795 }
796}
797
798
Alex Crichton5816d7f2014-11-26 19:17:23799impl<T> ExactSizeIterator<T> for MoveItems<T> {}
Alexis Beingessner865c2db2014-11-23 02:34:11800
Alex Crichton748bc3c2014-05-30 00:45:07801impl<A: PartialEq> PartialEq for RingBuf<A> {
blake2-ppc70523712013-07-10 13:27:14802 fn eq(&self, other: &RingBuf<A>) -> bool {
Colin Sherratt7a666df2014-10-19 20:19:07803 self.len() == other.len() &&
blake2-ppc10c76982013-07-06 13:27:32804 self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
805 }
blake2-ppc70523712013-07-10 13:27:14806 fn ne(&self, other: &RingBuf<A>) -> bool {
blake2-ppc10c76982013-07-06 13:27:32807 !self.eq(other)
808 }
809}
810
nham25acfde2014-08-01 20:05:03811impl<A: Eq> Eq for RingBuf<A> {}
812
nham63615772014-07-27 03:18:56813impl<A: PartialOrd> PartialOrd for RingBuf<A> {
814 fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
815 iter::order::partial_cmp(self.iter(), other.iter())
816 }
817}
818
nham3737c532014-08-01 20:22:48819impl<A: Ord> Ord for RingBuf<A> {
820 #[inline]
821 fn cmp(&self, other: &RingBuf<A>) -> Ordering {
822 iter::order::cmp(self.iter(), other.iter())
823 }
824}
825
nham1cfa6562014-07-27 02:33:47826impl<S: Writer, A: Hash<S>> Hash<S> for RingBuf<A> {
827 fn hash(&self, state: &mut S) {
nham9fa44242014-07-27 16:37:32828 self.len().hash(state);
nham1cfa6562014-07-27 02:33:47829 for elt in self.iter() {
830 elt.hash(state);
831 }
832 }
833}
834
P1startfd10d202014-08-02 06:39:39835impl<A> Index<uint, A> for RingBuf<A> {
836 #[inline]
837 fn index<'a>(&'a self, i: &uint) -> &'a A {
Colin Sherratt7a666df2014-10-19 20:19:07838 self.get(*i).expect("Out of bounds access")
P1startfd10d202014-08-02 06:39:39839 }
840}
841
Alex Crichton1d356622014-10-23 15:42:21842impl<A> IndexMut<uint, A> for RingBuf<A> {
P1startfd10d202014-08-02 06:39:39843 #[inline]
Alex Crichton1d356622014-10-23 15:42:21844 fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut A {
Colin Sherratt7a666df2014-10-19 20:19:07845 self.get_mut(*i).expect("Out of bounds access")
P1startfd10d202014-08-02 06:39:39846 }
Alex Crichton1d356622014-10-23 15:42:21847}
P1startfd10d202014-08-02 06:39:39848
Huon Wilson53487a02013-08-13 13:08:14849impl<A> FromIterator<A> for RingBuf<A> {
Brian Andersonee052192014-03-31 04:45:55850 fn from_iter<T: Iterator<A>>(iterator: T) -> RingBuf<A> {
blake2-ppcf8ae5262013-07-30 00:06:49851 let (lower, _) = iterator.size_hint();
852 let mut deq = RingBuf::with_capacity(lower);
853 deq.extend(iterator);
blake2-ppc08dc72f2013-07-06 03:42:45854 deq
855 }
856}
857
gamazeps16c8cd92014-11-08 00:39:39858impl<A> Extend<A> for RingBuf<A> {
Marvin Löbel6200e762014-03-20 13:12:56859 fn extend<T: Iterator<A>>(&mut self, mut iterator: T) {
860 for elt in iterator {
Alexis Beingessnercf3b2e42014-11-06 17:24:47861 self.push_back(elt);
blake2-ppcf8ae5262013-07-30 00:06:49862 }
863 }
864}
865
Alex Crichton6a585372014-05-30 01:50:12866impl<T: fmt::Show> fmt::Show for RingBuf<T> {
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:04867 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
868 try!(write!(f, "["));
869
870 for (i, e) in self.iter().enumerate() {
871 if i != 0 { try!(write!(f, ", ")); }
872 try!(write!(f, "{}", *e));
873 }
874
875 write!(f, "]")
876 }
877}
878
Brian Anderson6e27b272012-01-18 03:05:07879#[cfg(test)]
880mod tests {
Steven Fackler3dcd2152014-11-06 08:05:53881 use self::Taggy::*;
882 use self::Taggypar::*;
Alex Crichton02882fb2014-02-28 09:23:06883 use std::fmt::Show;
Alex Crichton760b93a2014-05-30 02:03:06884 use std::prelude::*;
nham1cfa6562014-07-27 02:33:47885 use std::hash;
Alex Crichton760b93a2014-05-30 02:03:06886 use test::Bencher;
887 use test;
888
Alex Crichtonf47e4b22014-01-07 06:33:50889 use super::RingBuf;
Alex Crichton760b93a2014-05-30 02:03:06890 use vec::Vec;
Patrick Waltonfa5ee932012-12-28 02:24:18891
Brian Anderson6e27b272012-01-18 03:05:07892 #[test]
Victor Berger52ea83d2014-09-22 17:30:06893 #[allow(deprecated)]
Brian Anderson6e27b272012-01-18 03:05:07894 fn test_simple() {
blake2-ppc70523712013-07-10 13:27:14895 let mut d = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:45896 assert_eq!(d.len(), 0u);
Niko Matsakis9e3d0b02014-04-21 21:58:52897 d.push_front(17i);
898 d.push_front(42i);
Alexis Beingessnercf3b2e42014-11-06 17:24:47899 d.push_back(137);
Corey Richardsoncc57ca02013-05-19 02:02:45900 assert_eq!(d.len(), 3u);
Alexis Beingessnercf3b2e42014-11-06 17:24:47901 d.push_back(137);
Corey Richardsoncc57ca02013-05-19 02:02:45902 assert_eq!(d.len(), 4u);
Luqman Aden3ef9aa02014-10-15 07:22:55903 debug!("{}", d.front());
blake2-ppc70523712013-07-10 13:27:14904 assert_eq!(*d.front().unwrap(), 42);
Luqman Aden3ef9aa02014-10-15 07:22:55905 debug!("{}", d.back());
blake2-ppc70523712013-07-10 13:27:14906 assert_eq!(*d.back().unwrap(), 137);
907 let mut i = d.pop_front();
Luqman Aden3ef9aa02014-10-15 07:22:55908 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:14909 assert_eq!(i, Some(42));
Alexis Beingessnercf3b2e42014-11-06 17:24:47910 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:55911 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:14912 assert_eq!(i, Some(137));
Alexis Beingessnercf3b2e42014-11-06 17:24:47913 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:55914 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:14915 assert_eq!(i, Some(137));
Alexis Beingessnercf3b2e42014-11-06 17:24:47916 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:55917 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:14918 assert_eq!(i, Some(17));
Corey Richardsoncc57ca02013-05-19 02:02:45919 assert_eq!(d.len(), 0u);
Alexis Beingessnercf3b2e42014-11-06 17:24:47920 d.push_back(3);
Corey Richardsoncc57ca02013-05-19 02:02:45921 assert_eq!(d.len(), 1u);
blake2-ppc70523712013-07-10 13:27:14922 d.push_front(2);
Corey Richardsoncc57ca02013-05-19 02:02:45923 assert_eq!(d.len(), 2u);
Alexis Beingessnercf3b2e42014-11-06 17:24:47924 d.push_back(4);
Corey Richardsoncc57ca02013-05-19 02:02:45925 assert_eq!(d.len(), 3u);
blake2-ppc70523712013-07-10 13:27:14926 d.push_front(1);
Corey Richardsoncc57ca02013-05-19 02:02:45927 assert_eq!(d.len(), 4u);
Alex Crichton9d5d97b2014-10-15 06:05:01928 debug!("{}", d[0]);
929 debug!("{}", d[1]);
930 debug!("{}", d[2]);
931 debug!("{}", d[3]);
932 assert_eq!(d[0], 1);
933 assert_eq!(d[1], 2);
934 assert_eq!(d[2], 3);
935 assert_eq!(d[3], 4);
Brian Anderson6e27b272012-01-18 03:05:07936 }
937
Felix S. Klock IIa636f512013-05-01 23:32:37938 #[cfg(test)]
Alex Crichton748bc3c2014-05-30 00:45:07939 fn test_parameterized<T:Clone + PartialEq + Show>(a: T, b: T, c: T, d: T) {
Patrick Waltondc4bf172013-07-13 04:05:59940 let mut deq = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:45941 assert_eq!(deq.len(), 0);
Patrick Waltondc4bf172013-07-13 04:05:59942 deq.push_front(a.clone());
943 deq.push_front(b.clone());
Alexis Beingessnercf3b2e42014-11-06 17:24:47944 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45945 assert_eq!(deq.len(), 3);
Alexis Beingessnercf3b2e42014-11-06 17:24:47946 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45947 assert_eq!(deq.len(), 4);
Marvin Löbel0ac7a212013-08-03 23:59:24948 assert_eq!((*deq.front().unwrap()).clone(), b.clone());
949 assert_eq!((*deq.back().unwrap()).clone(), d.clone());
950 assert_eq!(deq.pop_front().unwrap(), b.clone());
Alexis Beingessnercf3b2e42014-11-06 17:24:47951 assert_eq!(deq.pop_back().unwrap(), d.clone());
952 assert_eq!(deq.pop_back().unwrap(), c.clone());
953 assert_eq!(deq.pop_back().unwrap(), a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45954 assert_eq!(deq.len(), 0);
Alexis Beingessnercf3b2e42014-11-06 17:24:47955 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45956 assert_eq!(deq.len(), 1);
Patrick Waltondc4bf172013-07-13 04:05:59957 deq.push_front(b.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45958 assert_eq!(deq.len(), 2);
Alexis Beingessnercf3b2e42014-11-06 17:24:47959 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45960 assert_eq!(deq.len(), 3);
Patrick Waltondc4bf172013-07-13 04:05:59961 deq.push_front(a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45962 assert_eq!(deq.len(), 4);
NODA, Kaif27ad3d2014-10-05 10:11:17963 assert_eq!(deq[0].clone(), a.clone());
964 assert_eq!(deq[1].clone(), b.clone());
965 assert_eq!(deq[2].clone(), c.clone());
966 assert_eq!(deq[3].clone(), d.clone());
Brian Anderson6e27b272012-01-18 03:05:07967 }
968
blake2-ppc81933ed2013-07-06 03:42:45969 #[test]
blake2-ppc70523712013-07-10 13:27:14970 fn test_push_front_grow() {
971 let mut deq = RingBuf::new();
Daniel Micay100894552013-08-03 16:45:23972 for i in range(0u, 66) {
blake2-ppc70523712013-07-10 13:27:14973 deq.push_front(i);
blake2-ppc81933ed2013-07-06 03:42:45974 }
975 assert_eq!(deq.len(), 66);
976
Daniel Micay100894552013-08-03 16:45:23977 for i in range(0u, 66) {
NODA, Kaif27ad3d2014-10-05 10:11:17978 assert_eq!(deq[i], 65 - i);
blake2-ppc81933ed2013-07-06 03:42:45979 }
980
blake2-ppc70523712013-07-10 13:27:14981 let mut deq = RingBuf::new();
Daniel Micay100894552013-08-03 16:45:23982 for i in range(0u, 66) {
Alexis Beingessnercf3b2e42014-11-06 17:24:47983 deq.push_back(i);
blake2-ppc81933ed2013-07-06 03:42:45984 }
985
Daniel Micay100894552013-08-03 16:45:23986 for i in range(0u, 66) {
NODA, Kaif27ad3d2014-10-05 10:11:17987 assert_eq!(deq[i], i);
blake2-ppc81933ed2013-07-06 03:42:45988 }
989 }
990
P1startfd10d202014-08-02 06:39:39991 #[test]
992 fn test_index() {
993 let mut deq = RingBuf::new();
994 for i in range(1u, 4) {
995 deq.push_front(i);
996 }
997 assert_eq!(deq[1], 2);
998 }
999
1000 #[test]
1001 #[should_fail]
1002 fn test_index_out_of_bounds() {
1003 let mut deq = RingBuf::new();
1004 for i in range(1u, 4) {
1005 deq.push_front(i);
1006 }
1007 deq[3];
1008 }
1009
blake2-ppc81933ed2013-07-06 03:42:451010 #[bench]
Liigo Zhuang408f4842014-04-01 01:16:351011 fn bench_new(b: &mut test::Bencher) {
Patrick Walton38efa172013-11-22 03:20:481012 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521013 let ring: RingBuf<u64> = RingBuf::new();
1014 test::black_box(ring);
Patrick Walton38efa172013-11-22 03:20:481015 })
blake2-ppc81933ed2013-07-06 03:42:451016 }
1017
1018 #[bench]
Colin Sherratt7a666df2014-10-19 20:19:071019 fn bench_push_back_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521020 let mut deq = RingBuf::with_capacity(101);
Patrick Walton38efa172013-11-22 03:20:481021 b.iter(|| {
Colin Sherratt7a666df2014-10-19 20:19:071022 for i in range(0i, 100) {
1023 deq.push_back(i);
1024 }
Colin Sherratt5e549d82014-11-11 02:57:521025 deq.head = 0;
1026 deq.tail = 0;
Patrick Walton38efa172013-11-22 03:20:481027 })
blake2-ppc81933ed2013-07-06 03:42:451028 }
1029
1030 #[bench]
Colin Sherratt7a666df2014-10-19 20:19:071031 fn bench_push_front_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521032 let mut deq = RingBuf::with_capacity(101);
Patrick Walton38efa172013-11-22 03:20:481033 b.iter(|| {
Colin Sherratt7a666df2014-10-19 20:19:071034 for i in range(0i, 100) {
1035 deq.push_front(i);
1036 }
Colin Sherratt5e549d82014-11-11 02:57:521037 deq.head = 0;
1038 deq.tail = 0;
Patrick Walton38efa172013-11-22 03:20:481039 })
blake2-ppc81933ed2013-07-06 03:42:451040 }
1041
1042 #[bench]
Colin Sherratt5e549d82014-11-11 02:57:521043 fn bench_pop_back_100(b: &mut test::Bencher) {
1044 let mut deq: RingBuf<int> = RingBuf::with_capacity(101);
Colin Sherratt7a666df2014-10-19 20:19:071045
Patrick Walton38efa172013-11-22 03:20:481046 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521047 deq.head = 100;
1048 deq.tail = 0;
1049 while !deq.is_empty() {
1050 test::black_box(deq.pop_back());
Colin Sherratt7a666df2014-10-19 20:19:071051 }
Colin Sherratt7a666df2014-10-19 20:19:071052 })
1053 }
1054
1055 #[bench]
1056 fn bench_pop_front_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521057 let mut deq: RingBuf<int> = RingBuf::with_capacity(101);
Colin Sherratt7a666df2014-10-19 20:19:071058
1059 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521060 deq.head = 100;
1061 deq.tail = 0;
1062 while !deq.is_empty() {
1063 test::black_box(deq.pop_front());
Colin Sherratt7a666df2014-10-19 20:19:071064 }
Colin Sherratt7a666df2014-10-19 20:19:071065 })
1066 }
1067
1068 #[bench]
1069 fn bench_grow_1025(b: &mut test::Bencher) {
1070 b.iter(|| {
1071 let mut deq = RingBuf::new();
1072 for i in range(0i, 1025) {
1073 deq.push_front(i);
Brendan Zabarauskas729060d2014-01-30 00:20:341074 }
Colin Sherratt5e549d82014-11-11 02:57:521075 test::black_box(deq);
Patrick Walton38efa172013-11-22 03:20:481076 })
blake2-ppc81933ed2013-07-06 03:42:451077 }
1078
Colin Sherratt7a666df2014-10-19 20:19:071079 #[bench]
1080 fn bench_iter_1000(b: &mut test::Bencher) {
1081 let ring: RingBuf<int> = range(0i, 1000).collect();
1082
1083 b.iter(|| {
1084 let mut sum = 0;
1085 for &i in ring.iter() {
1086 sum += i;
1087 }
Colin Sherratt5e549d82014-11-11 02:57:521088 test::black_box(sum);
Colin Sherratt7a666df2014-10-19 20:19:071089 })
1090 }
1091
1092 #[bench]
1093 fn bench_mut_iter_1000(b: &mut test::Bencher) {
1094 let mut ring: RingBuf<int> = range(0i, 1000).collect();
1095
1096 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521097 let mut sum = 0;
Colin Sherratt7a666df2014-10-19 20:19:071098 for i in ring.iter_mut() {
Colin Sherratt5e549d82014-11-11 02:57:521099 sum += *i;
Colin Sherratt7a666df2014-10-19 20:19:071100 }
Colin Sherratt5e549d82014-11-11 02:57:521101 test::black_box(sum);
Colin Sherratt7a666df2014-10-19 20:19:071102 })
1103 }
1104
1105
Alex Crichton748bc3c2014-05-30 00:45:071106 #[deriving(Clone, PartialEq, Show)]
Patrick Walton99b33f72013-07-02 19:47:321107 enum Taggy {
1108 One(int),
1109 Two(int, int),
1110 Three(int, int, int),
Brian Anderson6e27b272012-01-18 03:05:071111 }
1112
Alex Crichton748bc3c2014-05-30 00:45:071113 #[deriving(Clone, PartialEq, Show)]
Patrick Walton99b33f72013-07-02 19:47:321114 enum Taggypar<T> {
1115 Onepar(int),
1116 Twopar(int, int),
1117 Threepar(int, int, int),
1118 }
1119
Alex Crichton748bc3c2014-05-30 00:45:071120 #[deriving(Clone, PartialEq, Show)]
Erick Tryzelaare84576b2013-01-22 16:44:241121 struct RecCy {
1122 x: int,
1123 y: int,
Patrick Waltoneb4d39e2013-01-26 00:57:391124 t: Taggy
Patrick Walton9117dcb2012-09-20 01:00:261125 }
Kevin Cantuc43426e2012-09-13 05:09:551126
1127 #[test]
1128 fn test_param_int() {
1129 test_parameterized::<int>(5, 72, 64, 175);
1130 }
1131
1132 #[test]
Kevin Cantuc43426e2012-09-13 05:09:551133 fn test_param_taggy() {
Corey Richardsonf8ae9b02013-06-26 22:14:351134 test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:551135 }
1136
1137 #[test]
1138 fn test_param_taggypar() {
1139 test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
Ben Striegela605fd02012-08-11 14:08:421140 Twopar::<int>(1, 2),
1141 Threepar::<int>(1, 2, 3),
1142 Twopar::<int>(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:551143 }
Brian Anderson6e27b272012-01-18 03:05:071144
Kevin Cantuc43426e2012-09-13 05:09:551145 #[test]
1146 fn test_param_reccy() {
Erick Tryzelaare84576b2013-01-22 16:44:241147 let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
1148 let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
1149 let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
1150 let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
Kevin Cantuc43426e2012-09-13 05:09:551151 test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
Brian Anderson6e27b272012-01-18 03:05:071152 }
Erick Tryzelaar909d8f02013-03-30 01:02:441153
1154 #[test]
blake2-ppc0ff5c172013-07-06 03:42:451155 fn test_with_capacity() {
blake2-ppc70523712013-07-10 13:27:141156 let mut d = RingBuf::with_capacity(0);
Alexis Beingessnercf3b2e42014-11-06 17:24:471157 d.push_back(1i);
blake2-ppc0ff5c172013-07-06 03:42:451158 assert_eq!(d.len(), 1);
blake2-ppc70523712013-07-10 13:27:141159 let mut d = RingBuf::with_capacity(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471160 d.push_back(1i);
blake2-ppc0ff5c172013-07-06 03:42:451161 assert_eq!(d.len(), 1);
1162 }
1163
1164 #[test]
Kevin Butler64896d62014-08-07 01:11:131165 fn test_with_capacity_non_power_two() {
1166 let mut d3 = RingBuf::with_capacity(3);
Alexis Beingessnercf3b2e42014-11-06 17:24:471167 d3.push_back(1i);
Kevin Butler64896d62014-08-07 01:11:131168
1169 // X = None, | = lo
1170 // [|1, X, X]
1171 assert_eq!(d3.pop_front(), Some(1));
1172 // [X, |X, X]
1173 assert_eq!(d3.front(), None);
1174
1175 // [X, |3, X]
Alexis Beingessnercf3b2e42014-11-06 17:24:471176 d3.push_back(3);
Kevin Butler64896d62014-08-07 01:11:131177 // [X, |3, 6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471178 d3.push_back(6);
Kevin Butler64896d62014-08-07 01:11:131179 // [X, X, |6]
1180 assert_eq!(d3.pop_front(), Some(3));
1181
1182 // Pushing the lo past half way point to trigger
1183 // the 'B' scenario for growth
1184 // [9, X, |6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471185 d3.push_back(9);
Kevin Butler64896d62014-08-07 01:11:131186 // [9, 12, |6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471187 d3.push_back(12);
Kevin Butler64896d62014-08-07 01:11:131188
Alexis Beingessnercf3b2e42014-11-06 17:24:471189 d3.push_back(15);
Kevin Butler64896d62014-08-07 01:11:131190 // There used to be a bug here about how the
1191 // RingBuf made growth assumptions about the
1192 // underlying Vec which didn't hold and lead
1193 // to corruption.
1194 // (Vec grows to next power of two)
1195 //good- [9, 12, 15, X, X, X, X, |6]
1196 //bug- [15, 12, X, X, X, |6, X, X]
1197 assert_eq!(d3.pop_front(), Some(6));
1198
1199 // Which leads us to the following state which
1200 // would be a failure case.
1201 //bug- [15, 12, X, X, X, X, |X, X]
1202 assert_eq!(d3.front(), Some(&9));
1203 }
1204
1205 #[test]
David Manescu65f35782014-01-31 13:03:201206 fn test_reserve_exact() {
blake2-ppc70523712013-07-10 13:27:141207 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471208 d.push_back(0u64);
David Manescu65f35782014-01-31 13:03:201209 d.reserve_exact(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471210 assert!(d.capacity() >= 51);
blake2-ppc70523712013-07-10 13:27:141211 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471212 d.push_back(0u32);
David Manescu65f35782014-01-31 13:03:201213 d.reserve_exact(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471214 assert!(d.capacity() >= 51);
Tim Chevalier77de84b2013-05-27 18:47:381215 }
1216
1217 #[test]
David Manescu65f35782014-01-31 13:03:201218 fn test_reserve() {
blake2-ppc70523712013-07-10 13:27:141219 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471220 d.push_back(0u64);
David Manescu65f35782014-01-31 13:03:201221 d.reserve(50);
Colin Sherratt7a666df2014-10-19 20:19:071222 assert!(d.capacity() >= 51);
blake2-ppc70523712013-07-10 13:27:141223 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471224 d.push_back(0u32);
David Manescu65f35782014-01-31 13:03:201225 d.reserve(50);
Colin Sherratt7a666df2014-10-19 20:19:071226 assert!(d.capacity() >= 51);
Tim Chevalier77de84b2013-05-27 18:47:381227 }
1228
Jed Estep096fb792013-06-26 14:04:441229 #[test]
blake2-ppc57757a82013-09-26 07:19:261230 fn test_swap() {
Niko Matsakis9e3d0b02014-04-21 21:58:521231 let mut d: RingBuf<int> = range(0i, 5).collect();
blake2-ppc57757a82013-09-26 07:19:261232 d.pop_front();
1233 d.swap(0, 3);
Huon Wilson4b9a7a22014-04-05 05:45:421234 assert_eq!(d.iter().map(|&x|x).collect::<Vec<int>>(), vec!(4, 2, 3, 1));
blake2-ppc57757a82013-09-26 07:19:261235 }
1236
1237 #[test]
Jed Estep096fb792013-06-26 14:04:441238 fn test_iter() {
blake2-ppc70523712013-07-10 13:27:141239 let mut d = RingBuf::new();
blake2-ppcf88d5322013-07-06 03:42:451240 assert_eq!(d.iter().next(), None);
blake2-ppc9ccf4432013-07-14 20:30:221241 assert_eq!(d.iter().size_hint(), (0, Some(0)));
blake2-ppcf88d5322013-07-06 03:42:451242
Niko Matsakis9e3d0b02014-04-21 21:58:521243 for i in range(0i, 5) {
Alexis Beingessnercf3b2e42014-11-06 17:24:471244 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:441245 }
Nick Cameron37a94b82014-08-04 12:19:021246 {
1247 let b: &[_] = &[&0,&1,&2,&3,&4];
Jorge Apariciof2af07e2014-11-27 16:45:501248 assert_eq!(d.iter().collect::<Vec<&int>>(), b);
Nick Cameron37a94b82014-08-04 12:19:021249 }
Corey Richardsonf8ae9b02013-06-26 22:14:351250
Niko Matsakis9e3d0b02014-04-21 21:58:521251 for i in range(6i, 9) {
blake2-ppc70523712013-07-10 13:27:141252 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:441253 }
Nick Cameron37a94b82014-08-04 12:19:021254 {
1255 let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
Jorge Apariciof2af07e2014-11-27 16:45:501256 assert_eq!(d.iter().collect::<Vec<&int>>(), b);
Nick Cameron37a94b82014-08-04 12:19:021257 }
blake2-ppc9ccf4432013-07-14 20:30:221258
1259 let mut it = d.iter();
1260 let mut len = d.len();
1261 loop {
1262 match it.next() {
1263 None => break,
1264 _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
1265 }
1266 }
Jed Estep096fb792013-06-26 14:04:441267 }
1268
1269 #[test]
1270 fn test_rev_iter() {
blake2-ppc70523712013-07-10 13:27:141271 let mut d = RingBuf::new();
Jonathan S03609e52014-04-21 04:59:121272 assert_eq!(d.iter().rev().next(), None);
blake2-ppcf88d5322013-07-06 03:42:451273
Niko Matsakis9e3d0b02014-04-21 21:58:521274 for i in range(0i, 5) {
Alexis Beingessnercf3b2e42014-11-06 17:24:471275 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:441276 }
Nick Cameron37a94b82014-08-04 12:19:021277 {
1278 let b: &[_] = &[&4,&3,&2,&1,&0];
Jorge Apariciof2af07e2014-11-27 16:45:501279 assert_eq!(d.iter().rev().collect::<Vec<&int>>(), b);
Nick Cameron37a94b82014-08-04 12:19:021280 }
Corey Richardsonf8ae9b02013-06-26 22:14:351281
Niko Matsakis9e3d0b02014-04-21 21:58:521282 for i in range(6i, 9) {
blake2-ppc70523712013-07-10 13:27:141283 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:441284 }
Nick Cameron37a94b82014-08-04 12:19:021285 let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
Jorge Apariciof2af07e2014-11-27 16:45:501286 assert_eq!(d.iter().rev().collect::<Vec<&int>>(), b);
Jed Estep096fb792013-06-26 14:04:441287 }
blake2-ppc08dc72f2013-07-06 03:42:451288
1289 #[test]
Niko Matsakisbc4164d2013-11-16 22:29:391290 fn test_mut_rev_iter_wrap() {
1291 let mut d = RingBuf::with_capacity(3);
Aaron Turonfc525ee2014-09-15 03:27:361292 assert!(d.iter_mut().rev().next().is_none());
Niko Matsakisbc4164d2013-11-16 22:29:391293
Alexis Beingessnercf3b2e42014-11-06 17:24:471294 d.push_back(1i);
1295 d.push_back(2);
1296 d.push_back(3);
Niko Matsakisbc4164d2013-11-16 22:29:391297 assert_eq!(d.pop_front(), Some(1));
Alexis Beingessnercf3b2e42014-11-06 17:24:471298 d.push_back(4);
Niko Matsakisbc4164d2013-11-16 22:29:391299
Aaron Turonfc525ee2014-09-15 03:27:361300 assert_eq!(d.iter_mut().rev().map(|x| *x).collect::<Vec<int>>(),
Huon Wilson4b9a7a22014-04-05 05:45:421301 vec!(4, 3, 2));
Niko Matsakisbc4164d2013-11-16 22:29:391302 }
1303
1304 #[test]
blake2-ppcf88d5322013-07-06 03:42:451305 fn test_mut_iter() {
blake2-ppc70523712013-07-10 13:27:141306 let mut d = RingBuf::new();
Aaron Turonfc525ee2014-09-15 03:27:361307 assert!(d.iter_mut().next().is_none());
blake2-ppcf88d5322013-07-06 03:42:451308
Daniel Micay100894552013-08-03 16:45:231309 for i in range(0u, 3) {
blake2-ppc70523712013-07-10 13:27:141310 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:451311 }
1312
Aaron Turonfc525ee2014-09-15 03:27:361313 for (i, elt) in d.iter_mut().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:451314 assert_eq!(*elt, 2 - i);
1315 *elt = i;
1316 }
1317
1318 {
Aaron Turonfc525ee2014-09-15 03:27:361319 let mut it = d.iter_mut();
blake2-ppcf88d5322013-07-06 03:42:451320 assert_eq!(*it.next().unwrap(), 0);
1321 assert_eq!(*it.next().unwrap(), 1);
1322 assert_eq!(*it.next().unwrap(), 2);
1323 assert!(it.next().is_none());
1324 }
1325 }
1326
1327 #[test]
1328 fn test_mut_rev_iter() {
blake2-ppc70523712013-07-10 13:27:141329 let mut d = RingBuf::new();
Aaron Turonfc525ee2014-09-15 03:27:361330 assert!(d.iter_mut().rev().next().is_none());
blake2-ppcf88d5322013-07-06 03:42:451331
Daniel Micay100894552013-08-03 16:45:231332 for i in range(0u, 3) {
blake2-ppc70523712013-07-10 13:27:141333 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:451334 }
1335
Aaron Turonfc525ee2014-09-15 03:27:361336 for (i, elt) in d.iter_mut().rev().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:451337 assert_eq!(*elt, i);
1338 *elt = i;
1339 }
1340
1341 {
Aaron Turonfc525ee2014-09-15 03:27:361342 let mut it = d.iter_mut().rev();
blake2-ppcf88d5322013-07-06 03:42:451343 assert_eq!(*it.next().unwrap(), 0);
1344 assert_eq!(*it.next().unwrap(), 1);
1345 assert_eq!(*it.next().unwrap(), 2);
1346 assert!(it.next().is_none());
1347 }
1348 }
1349
1350 #[test]
Alexis Beingessner865c2db2014-11-23 02:34:111351 fn test_into_iter() {
1352
1353 // Empty iter
1354 {
1355 let d: RingBuf<int> = RingBuf::new();
1356 let mut iter = d.into_iter();
1357
1358 assert_eq!(iter.size_hint(), (0, Some(0)));
1359 assert_eq!(iter.next(), None);
1360 assert_eq!(iter.size_hint(), (0, Some(0)));
1361 }
1362
1363 // simple iter
1364 {
1365 let mut d = RingBuf::new();
1366 for i in range(0i, 5) {
1367 d.push_back(i);
1368 }
1369
1370 let b = vec![0,1,2,3,4];
1371 assert_eq!(d.into_iter().collect::<Vec<int>>(), b);
1372 }
1373
1374 // wrapped iter
1375 {
1376 let mut d = RingBuf::new();
1377 for i in range(0i, 5) {
1378 d.push_back(i);
1379 }
1380 for i in range(6, 9) {
1381 d.push_front(i);
1382 }
1383
1384 let b = vec![8,7,6,0,1,2,3,4];
1385 assert_eq!(d.into_iter().collect::<Vec<int>>(), b);
1386 }
1387
1388 // partially used
1389 {
1390 let mut d = RingBuf::new();
1391 for i in range(0i, 5) {
1392 d.push_back(i);
1393 }
1394 for i in range(6, 9) {
1395 d.push_front(i);
1396 }
1397
1398 let mut it = d.into_iter();
1399 assert_eq!(it.size_hint(), (8, Some(8)));
1400 assert_eq!(it.next(), Some(8));
1401 assert_eq!(it.size_hint(), (7, Some(7)));
1402 assert_eq!(it.next_back(), Some(4));
1403 assert_eq!(it.size_hint(), (6, Some(6)));
1404 assert_eq!(it.next(), Some(7));
1405 assert_eq!(it.size_hint(), (5, Some(5)));
1406 }
1407 }
1408
1409 #[test]
Brian Andersonee052192014-03-31 04:45:551410 fn test_from_iter() {
Daniel Micay6919cf52013-09-08 15:01:161411 use std::iter;
Niko Matsakis9e3d0b02014-04-21 21:58:521412 let v = vec!(1i,2,3,4,5,6,7);
Erick Tryzelaar68f40d22013-08-10 03:09:471413 let deq: RingBuf<int> = v.iter().map(|&x| x).collect();
Huon Wilson4b9a7a22014-04-05 05:45:421414 let u: Vec<int> = deq.iter().map(|&x| x).collect();
blake2-ppc08dc72f2013-07-06 03:42:451415 assert_eq!(u, v);
1416
Aaron Turonb299c2b2014-11-06 17:32:371417 let seq = iter::count(0u, 2).take(256);
blake2-ppc70523712013-07-10 13:27:141418 let deq: RingBuf<uint> = seq.collect();
Daniel Micay100894552013-08-03 16:45:231419 for (i, &x) in deq.iter().enumerate() {
blake2-ppc08dc72f2013-07-06 03:42:451420 assert_eq!(2*i, x);
1421 }
1422 assert_eq!(deq.len(), 256);
1423 }
blake2-ppc10c76982013-07-06 13:27:321424
1425 #[test]
1426 fn test_clone() {
blake2-ppc70523712013-07-10 13:27:141427 let mut d = RingBuf::new();
Niko Matsakis9e3d0b02014-04-21 21:58:521428 d.push_front(17i);
blake2-ppc70523712013-07-10 13:27:141429 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:471430 d.push_back(137);
1431 d.push_back(137);
blake2-ppc10c76982013-07-06 13:27:321432 assert_eq!(d.len(), 4u);
1433 let mut e = d.clone();
1434 assert_eq!(e.len(), 4u);
1435 while !d.is_empty() {
Alexis Beingessnercf3b2e42014-11-06 17:24:471436 assert_eq!(d.pop_back(), e.pop_back());
blake2-ppc10c76982013-07-06 13:27:321437 }
1438 assert_eq!(d.len(), 0u);
1439 assert_eq!(e.len(), 0u);
1440 }
1441
1442 #[test]
1443 fn test_eq() {
blake2-ppc70523712013-07-10 13:27:141444 let mut d = RingBuf::new();
Alex Crichton02882fb2014-02-28 09:23:061445 assert!(d == RingBuf::with_capacity(0));
Niko Matsakis9e3d0b02014-04-21 21:58:521446 d.push_front(137i);
blake2-ppc70523712013-07-10 13:27:141447 d.push_front(17);
1448 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:471449 d.push_back(137);
blake2-ppc70523712013-07-10 13:27:141450 let mut e = RingBuf::with_capacity(0);
Alexis Beingessnercf3b2e42014-11-06 17:24:471451 e.push_back(42);
1452 e.push_back(17);
1453 e.push_back(137);
1454 e.push_back(137);
Alex Crichton02882fb2014-02-28 09:23:061455 assert!(&e == &d);
Alexis Beingessnercf3b2e42014-11-06 17:24:471456 e.pop_back();
1457 e.push_back(0);
blake2-ppc10c76982013-07-06 13:27:321458 assert!(e != d);
1459 e.clear();
Alex Crichton02882fb2014-02-28 09:23:061460 assert!(e == RingBuf::new());
blake2-ppc10c76982013-07-06 13:27:321461 }
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041462
1463 #[test]
nham1cfa6562014-07-27 02:33:471464 fn test_hash() {
1465 let mut x = RingBuf::new();
1466 let mut y = RingBuf::new();
1467
Alexis Beingessnercf3b2e42014-11-06 17:24:471468 x.push_back(1i);
1469 x.push_back(2);
1470 x.push_back(3);
nham1cfa6562014-07-27 02:33:471471
Alexis Beingessnercf3b2e42014-11-06 17:24:471472 y.push_back(0i);
1473 y.push_back(1i);
nham1cfa6562014-07-27 02:33:471474 y.pop_front();
Alexis Beingessnercf3b2e42014-11-06 17:24:471475 y.push_back(2);
1476 y.push_back(3);
nham1cfa6562014-07-27 02:33:471477
1478 assert!(hash::hash(&x) == hash::hash(&y));
1479 }
1480
1481 #[test]
nham63615772014-07-27 03:18:561482 fn test_ord() {
1483 let x = RingBuf::new();
1484 let mut y = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471485 y.push_back(1i);
1486 y.push_back(2);
1487 y.push_back(3);
nham63615772014-07-27 03:18:561488 assert!(x < y);
1489 assert!(y > x);
1490 assert!(x <= x);
1491 assert!(x >= x);
1492 }
1493
1494 #[test]
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041495 fn test_show() {
Niko Matsakis9e3d0b02014-04-21 21:58:521496 let ringbuf: RingBuf<int> = range(0i, 10).collect();
Jorge Apariciof2af07e2014-11-27 16:45:501497 assert!(format!("{}", ringbuf) == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041498
1499 let ringbuf: RingBuf<&str> = vec!["just", "one", "test", "more"].iter()
1500 .map(|&s| s)
1501 .collect();
Jorge Apariciof2af07e2014-11-27 16:45:501502 assert!(format!("{}", ringbuf) == "[just, one, test, more]");
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041503 }
Colin Sherratt7a666df2014-10-19 20:19:071504
1505 #[test]
1506 fn test_drop() {
1507 static mut drops: uint = 0;
1508 struct Elem;
1509 impl Drop for Elem {
1510 fn drop(&mut self) {
1511 unsafe { drops += 1; }
1512 }
1513 }
1514
1515 let mut ring = RingBuf::new();
1516 ring.push_back(Elem);
1517 ring.push_front(Elem);
1518 ring.push_back(Elem);
1519 ring.push_front(Elem);
1520 drop(ring);
1521
1522 assert_eq!(unsafe {drops}, 4);
1523 }
1524
1525 #[test]
1526 fn test_drop_with_pop() {
1527 static mut drops: uint = 0;
1528 struct Elem;
1529 impl Drop for Elem {
1530 fn drop(&mut self) {
1531 unsafe { drops += 1; }
1532 }
1533 }
1534
1535 let mut ring = RingBuf::new();
1536 ring.push_back(Elem);
1537 ring.push_front(Elem);
1538 ring.push_back(Elem);
1539 ring.push_front(Elem);
1540
1541 drop(ring.pop_back());
1542 drop(ring.pop_front());
1543 assert_eq!(unsafe {drops}, 2);
1544
1545 drop(ring);
1546 assert_eq!(unsafe {drops}, 4);
1547 }
1548
1549 #[test]
1550 fn test_drop_clear() {
1551 static mut drops: uint = 0;
1552 struct Elem;
1553 impl Drop for Elem {
1554 fn drop(&mut self) {
1555 unsafe { drops += 1; }
1556 }
1557 }
1558
1559 let mut ring = RingBuf::new();
1560 ring.push_back(Elem);
1561 ring.push_front(Elem);
1562 ring.push_back(Elem);
1563 ring.push_front(Elem);
1564 ring.clear();
1565 assert_eq!(unsafe {drops}, 4);
1566
1567 drop(ring);
1568 assert_eq!(unsafe {drops}, 4);
1569 }
1570
1571 #[test]
1572 fn test_reserve_grow() {
1573 // test growth path A
1574 // [T o o H] -> [T o o H . . . . ]
1575 let mut ring = RingBuf::with_capacity(4);
1576 for i in range(0i, 3) {
1577 ring.push_back(i);
1578 }
1579 ring.reserve(7);
1580 for i in range(0i, 3) {
1581 assert_eq!(ring.pop_front(), Some(i));
1582 }
1583
1584 // test growth path B
1585 // [H T o o] -> [. T o o H . . . ]
1586 let mut ring = RingBuf::with_capacity(4);
1587 for i in range(0i, 1) {
1588 ring.push_back(i);
1589 assert_eq!(ring.pop_front(), Some(i));
1590 }
1591 for i in range(0i, 3) {
1592 ring.push_back(i);
1593 }
1594 ring.reserve(7);
1595 for i in range(0i, 3) {
1596 assert_eq!(ring.pop_front(), Some(i));
1597 }
1598
1599 // test growth path C
1600 // [o o H T] -> [o o H . . . . T ]
1601 let mut ring = RingBuf::with_capacity(4);
1602 for i in range(0i, 3) {
1603 ring.push_back(i);
1604 assert_eq!(ring.pop_front(), Some(i));
1605 }
1606 for i in range(0i, 3) {
1607 ring.push_back(i);
1608 }
1609 ring.reserve(7);
1610 for i in range(0i, 3) {
1611 assert_eq!(ring.pop_front(), Some(i));
1612 }
1613 }
1614
1615 #[test]
1616 fn test_get() {
1617 let mut ring = RingBuf::new();
1618 ring.push_back(0i);
1619 assert_eq!(ring.get(0), Some(&0));
1620 assert_eq!(ring.get(1), None);
1621
1622 ring.push_back(1);
1623 assert_eq!(ring.get(0), Some(&0));
1624 assert_eq!(ring.get(1), Some(&1));
1625 assert_eq!(ring.get(2), None);
1626
1627 ring.push_back(2);
1628 assert_eq!(ring.get(0), Some(&0));
1629 assert_eq!(ring.get(1), Some(&1));
1630 assert_eq!(ring.get(2), Some(&2));
1631 assert_eq!(ring.get(3), None);
1632
1633 assert_eq!(ring.pop_front(), Some(0));
1634 assert_eq!(ring.get(0), Some(&1));
1635 assert_eq!(ring.get(1), Some(&2));
1636 assert_eq!(ring.get(2), None);
1637
1638 assert_eq!(ring.pop_front(), Some(1));
1639 assert_eq!(ring.get(0), Some(&2));
1640 assert_eq!(ring.get(1), None);
1641
1642 assert_eq!(ring.pop_front(), Some(2));
1643 assert_eq!(ring.get(0), None);
1644 assert_eq!(ring.get(1), None);
1645 }
1646
1647 #[test]
1648 fn test_get_mut() {
1649 let mut ring = RingBuf::new();
1650 for i in range(0i, 3) {
1651 ring.push_back(i);
1652 }
1653
1654 match ring.get_mut(1) {
1655 Some(x) => *x = -1,
1656 None => ()
1657 };
1658
1659 assert_eq!(ring.get_mut(0), Some(&mut 0));
1660 assert_eq!(ring.get_mut(1), Some(&mut -1));
1661 assert_eq!(ring.get_mut(2), Some(&mut 2));
1662 assert_eq!(ring.get_mut(3), None);
1663
1664 assert_eq!(ring.pop_front(), Some(0));
1665 assert_eq!(ring.get_mut(0), Some(&mut -1));
1666 assert_eq!(ring.get_mut(1), Some(&mut 2));
1667 assert_eq!(ring.get_mut(2), None);
1668 }
Michael Sullivanc854d6e2012-07-03 17:52:321669}