blob: d9e5dde96ceee7693be941db311b068b517dc98b [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.
14//! Its interface `Deque` is defined in `collections`.
Patrick Waltonf3723cf2013-05-17 22:28:4415
Alex Crichton6a585372014-05-30 01:50:1216use core::prelude::*;
17
Tom Jakubowskid6a39412014-06-09 07:30:0418use core::default::Default;
Alex Crichton6a585372014-05-30 01:50:1219use core::fmt;
nham63615772014-07-27 03:18:5620use core::iter;
Colin Sherratt7a666df2014-10-19 20:19:0721use core::raw::Slice as RawSlice;
22use core::ptr;
23use core::kinds::marker;
24use core::mem;
Colin Sherratt6277e3b2014-11-14 09:21:4425use core::num::{Int, UnsignedInt};
Alex Crichton998fece2013-05-06 04:42:5426
Colin Sherratt7a666df2014-10-19 20:19:0727use std::hash::{Writer, Hash};
28use std::cmp;
29
30use alloc::heap;
blake2-ppc70523712013-07-10 13:27:1431
blake2-ppc0ff5c172013-07-06 03:42:4532static INITIAL_CAPACITY: uint = 8u; // 2^3
33static MINIMUM_CAPACITY: uint = 2u;
Daniel Micayb47e1e92013-02-16 22:55:5534
Alexis Beingessnercf3b2e42014-11-06 17:24:4735// FIXME(conventions): implement shrink_to_fit. Awkward with the current design, but it should
36// be scrapped anyway. Defer to rewrite?
Alexis Beingessnercf3b2e42014-11-06 17:24:4737
P1startf2aa88c2014-08-04 10:48:3938/// `RingBuf` is a circular buffer that implements `Deque`.
blake2-ppc70523712013-07-10 13:27:1439pub struct RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:0740 // tail and head are pointers into the buffer. Tail always points
41 // to the first element that could be read, Head always points
42 // to where data should be written.
43 // If tail == head the buffer is empty. The length of the ringbuf
44 // is defined as the distance between the two.
45
46 tail: uint,
47 head: uint,
48 cap: uint,
49 ptr: *mut T
50}
51
52impl<T: Clone> Clone for RingBuf<T> {
53 fn clone(&self) -> RingBuf<T> {
54 self.iter().map(|t| t.clone()).collect()
55 }
56}
57
58#[unsafe_destructor]
59impl<T> Drop for RingBuf<T> {
60 fn drop(&mut self) {
61 self.clear();
62 unsafe {
63 if mem::size_of::<T>() != 0 {
64 heap::deallocate(self.ptr as *mut u8,
65 self.cap * mem::size_of::<T>(),
66 mem::min_align_of::<T>())
67 }
68 }
69 }
Marijn Haverbeke26610db2012-01-11 11:49:3370}
Roy Frostig9c818892010-07-21 01:03:0971
Tom Jakubowskid6a39412014-06-09 07:30:0472impl<T> Default for RingBuf<T> {
73 #[inline]
74 fn default() -> RingBuf<T> { RingBuf::new() }
75}
76
blake2-ppc70523712013-07-10 13:27:1477impl<T> RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:0778 /// Turn ptr into a slice
79 #[inline]
80 unsafe fn buffer_as_slice(&self) -> &[T] {
81 mem::transmute(RawSlice { data: self.ptr as *const T, len: self.cap })
82 }
83
84 /// Moves an element out of the buffer
85 #[inline]
86 unsafe fn buffer_read(&mut self, off: uint) -> T {
87 ptr::read(self.ptr.offset(off as int) as *const T)
88 }
89
90 /// Writes an element into the buffer, moving it.
91 #[inline]
92 unsafe fn buffer_write(&mut self, off: uint, t: T) {
93 ptr::write(self.ptr.offset(off as int), t);
94 }
95
96 /// Returns true iff the buffer is at capacity
97 #[inline]
98 fn is_full(&self) -> bool { self.cap - self.len() == 1 }
Colin Sherratt40191182014-11-12 01:22:0799
100 /// Returns the index in the underlying buffer for a given logical element index.
101 #[inline]
102 fn wrap_index(&self, idx: uint) -> uint { wrap_index(idx, self.cap) }
Colin Sherratt7a666df2014-10-19 20:19:07103}
104
105impl<T> RingBuf<T> {
P1startf2aa88c2014-08-04 10:48:39106 /// Creates an empty `RingBuf`.
Alexis Beingessnercf3b2e42014-11-06 17:24:47107 #[unstable = "matches collection reform specification, waiting for dust to settle"]
blake2-ppc70523712013-07-10 13:27:14108 pub fn new() -> RingBuf<T> {
109 RingBuf::with_capacity(INITIAL_CAPACITY)
110 }
111
P1startf2aa88c2014-08-04 10:48:39112 /// Creates an empty `RingBuf` with space for at least `n` elements.
Alexis Beingessnercf3b2e42014-11-06 17:24:47113 #[unstable = "matches collection reform specification, waiting for dust to settle"]
blake2-ppc70523712013-07-10 13:27:14114 pub fn with_capacity(n: uint) -> RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:07115 // +1 since the ringbuffer always leaves one space empty
Colin Sherratt6277e3b2014-11-14 09:21:44116 let cap = cmp::max(n + 1, MINIMUM_CAPACITY).next_power_of_two();
117 let size = cap.checked_mul(mem::size_of::<T>())
Colin Sherratt7a666df2014-10-19 20:19:07118 .expect("capacity overflow");
119
Colin Sherrattba24e332014-11-10 03:34:53120 let ptr = if mem::size_of::<T>() != 0 {
121 unsafe {
122 let ptr = heap::allocate(size, mem::min_align_of::<T>()) as *mut T;;
123 if ptr.is_null() { ::alloc::oom() }
124 ptr
125 }
126 } else {
127 heap::EMPTY as *mut T
128 };
129
Colin Sherratt7a666df2014-10-19 20:19:07130 RingBuf {
131 tail: 0,
132 head: 0,
133 cap: cap,
Colin Sherrattba24e332014-11-10 03:34:53134 ptr: ptr
Colin Sherratt7a666df2014-10-19 20:19:07135 }
blake2-ppc70523712013-07-10 13:27:14136 }
137
P1startf2aa88c2014-08-04 10:48:39138 /// Retrieves an element in the `RingBuf` by index.
blake2-ppc70523712013-07-10 13:27:14139 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47140 /// # Example
141 ///
142 /// ```rust
143 /// use std::collections::RingBuf;
144 ///
145 /// let mut buf = RingBuf::new();
146 /// buf.push_back(3i);
147 /// buf.push_back(4);
148 /// buf.push_back(5);
149 /// assert_eq!(buf.get(1).unwrap(), &4);
150 /// ```
151 #[unstable = "matches collection reform specification, waiting for dust to settle"]
152 pub fn get(&self, i: uint) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07153 if i < self.len() {
Colin Sherratt40191182014-11-12 01:22:07154 let idx = self.wrap_index(self.tail + i);
Colin Sherratt7a666df2014-10-19 20:19:07155 unsafe { Some(&*self.ptr.offset(idx as int)) }
156 } else {
157 None
Alexis Beingessnercf3b2e42014-11-06 17:24:47158 }
159 }
160
161 /// Retrieves an element in the `RingBuf` mutably by index.
nhamebe80972014-07-17 23:19:51162 ///
163 /// # Example
164 ///
165 /// ```rust
166 /// use std::collections::RingBuf;
167 ///
168 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47169 /// buf.push_back(3i);
170 /// buf.push_back(4);
171 /// buf.push_back(5);
172 /// match buf.get_mut(1) {
173 /// None => {}
174 /// Some(elem) => {
175 /// *elem = 7;
176 /// }
177 /// }
178 ///
P1startfd10d202014-08-02 06:39:39179 /// assert_eq!(buf[1], 7);
nhamebe80972014-07-17 23:19:51180 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47181 #[unstable = "matches collection reform specification, waiting for dust to settle"]
182 pub fn get_mut(&mut self, i: uint) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07183 if i < self.len() {
Colin Sherratt40191182014-11-12 01:22:07184 let idx = self.wrap_index(self.tail + i);
Colin Sherratt7a666df2014-10-19 20:19:07185 unsafe { Some(&mut *self.ptr.offset(idx as int)) }
186 } else {
187 None
Alexis Beingessnercf3b2e42014-11-06 17:24:47188 }
blake2-ppc70523712013-07-10 13:27:14189 }
190
P1startf2aa88c2014-08-04 10:48:39191 /// Swaps elements at indices `i` and `j`.
blake2-ppc57757a82013-09-26 07:19:26192 ///
193 /// `i` and `j` may be equal.
194 ///
P1startf2aa88c2014-08-04 10:48:39195 /// Fails if there is no element with either index.
nhamebe80972014-07-17 23:19:51196 ///
197 /// # Example
198 ///
199 /// ```rust
200 /// use std::collections::RingBuf;
201 ///
202 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47203 /// buf.push_back(3i);
204 /// buf.push_back(4);
205 /// buf.push_back(5);
nhamebe80972014-07-17 23:19:51206 /// buf.swap(0, 2);
P1startfd10d202014-08-02 06:39:39207 /// assert_eq!(buf[0], 5);
208 /// assert_eq!(buf[2], 3);
nhamebe80972014-07-17 23:19:51209 /// ```
blake2-ppc57757a82013-09-26 07:19:26210 pub fn swap(&mut self, i: uint, j: uint) {
211 assert!(i < self.len());
212 assert!(j < self.len());
Colin Sherratt40191182014-11-12 01:22:07213 let ri = self.wrap_index(self.tail + i);
214 let rj = self.wrap_index(self.tail + j);
Colin Sherratt7a666df2014-10-19 20:19:07215 unsafe {
216 ptr::swap(self.ptr.offset(ri as int), self.ptr.offset(rj as int))
217 }
blake2-ppc70523712013-07-10 13:27:14218 }
219
Alexis Beingessnercf3b2e42014-11-06 17:24:47220 /// Returns the number of elements the `RingBuf` can hold without
221 /// reallocating.
222 ///
223 /// # Example
224 ///
225 /// ```
226 /// use std::collections::RingBuf;
227 ///
228 /// let buf: RingBuf<int> = RingBuf::with_capacity(10);
Colin Sherratt7a666df2014-10-19 20:19:07229 /// assert!(buf.capacity() >= 10);
Alexis Beingessnercf3b2e42014-11-06 17:24:47230 /// ```
231 #[inline]
232 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Colin Sherratt7a666df2014-10-19 20:19:07233 pub fn capacity(&self) -> uint { self.cap - 1 }
Tim Chevalier77de84b2013-05-27 18:47:38234
Alexis Beingessnercf3b2e42014-11-06 17:24:47235 /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
236 /// given `RingBuf`. Does nothing if the capacity is already sufficient.
Tim Chevalier77de84b2013-05-27 18:47:38237 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47238 /// Note that the allocator may give the collection more space than it requests. Therefore
239 /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
240 /// insertions are expected.
241 ///
242 /// # Panics
243 ///
244 /// Panics if the new capacity overflows `uint`.
245 ///
246 /// # Example
247 ///
248 /// ```
249 /// use std::collections::RingBuf;
250 ///
251 /// let mut buf: RingBuf<int> = vec![1].into_iter().collect();
252 /// buf.reserve_exact(10);
253 /// assert!(buf.capacity() >= 11);
254 /// ```
255 #[unstable = "matches collection reform specification, waiting for dust to settle"]
256 pub fn reserve_exact(&mut self, additional: uint) {
Colin Sherratt7a666df2014-10-19 20:19:07257 self.reserve(additional);
Alexis Beingessnercf3b2e42014-11-06 17:24:47258 }
259
260 /// Reserves capacity for at least `additional` more elements to be inserted in the given
261 /// `Ringbuf`. The collection may reserve more space to avoid frequent reallocations.
262 ///
263 /// # Panics
264 ///
265 /// Panics if the new capacity overflows `uint`.
266 ///
267 /// # Example
268 ///
269 /// ```
270 /// use std::collections::RingBuf;
271 ///
272 /// let mut buf: RingBuf<int> = vec![1].into_iter().collect();
273 /// buf.reserve(10);
274 /// assert!(buf.capacity() >= 11);
275 /// ```
276 #[unstable = "matches collection reform specification, waiting for dust to settle"]
277 pub fn reserve(&mut self, additional: uint) {
Colin Sherratt7a666df2014-10-19 20:19:07278 let new_len = self.len() + additional;
279 assert!(new_len + 1 > self.len(), "capacity overflow");
280 if new_len > self.capacity() {
Colin Sherratt6277e3b2014-11-14 09:21:44281 let count = (new_len + 1).next_power_of_two();
Colin Sherratt7a666df2014-10-19 20:19:07282 assert!(count >= new_len + 1);
283
284 if mem::size_of::<T>() != 0 {
285 let old = self.cap * mem::size_of::<T>();
Colin Sherratt6277e3b2014-11-14 09:21:44286 let new = count.checked_mul(mem::size_of::<T>())
Colin Sherratt7a666df2014-10-19 20:19:07287 .expect("capacity overflow");
288 unsafe {
289 self.ptr = heap::reallocate(self.ptr as *mut u8,
290 old,
291 new,
292 mem::min_align_of::<T>()) as *mut T;
Colin Sherrattba24e332014-11-10 03:34:53293 if self.ptr.is_null() { ::alloc::oom() }
Colin Sherratt7a666df2014-10-19 20:19:07294 }
295 }
296
297 // Move the shortest contiguous section of the ring buffer
298 // T H
299 // [o o o o o o o . ]
300 // T H
301 // A [o o o o o o o . . . . . . . . . ]
302 // H T
303 // [o o . o o o o o ]
304 // T H
305 // B [. . . o o o o o o o . . . . . . ]
306 // H T
307 // [o o o o o . o o ]
308 // H T
309 // C [o o o o o . . . . . . . . . o o ]
310
311 let oldcap = self.cap;
312 self.cap = count;
313
314 if self.tail <= self.head { // A
315 // Nop
316 } else if self.head < oldcap - self.tail { // B
317 unsafe {
318 ptr::copy_nonoverlapping_memory(
319 self.ptr.offset(oldcap as int),
320 self.ptr as *const T,
321 self.head
322 );
323 }
324 self.head += oldcap;
Colin Sherratt4cae9ad2014-11-11 02:16:29325 debug_assert!(self.head > self.tail);
Colin Sherratt7a666df2014-10-19 20:19:07326 } else { // C
327 unsafe {
328 ptr::copy_nonoverlapping_memory(
329 self.ptr.offset((count - (oldcap - self.tail)) as int),
330 self.ptr.offset(self.tail as int) as *const T,
331 oldcap - self.tail
332 );
333 }
334 self.tail = count - (oldcap - self.tail);
Colin Sherratt4cae9ad2014-11-11 02:16:29335 debug_assert!(self.head < self.tail);
Colin Sherratt7a666df2014-10-19 20:19:07336 }
Colin Sherratt4cae9ad2014-11-11 02:16:29337 debug_assert!(self.head < self.cap);
338 debug_assert!(self.tail < self.cap);
Colin Sherratt40191182014-11-12 01:22:07339 debug_assert!(self.cap.count_ones() == 1);
Colin Sherratt7a666df2014-10-19 20:19:07340 }
Tim Chevalier77de84b2013-05-27 18:47:38341 }
Jed Estep4f7a7422013-06-25 19:08:47342
P1startf2aa88c2014-08-04 10:48:39343 /// Returns a front-to-back iterator.
nhamebe80972014-07-17 23:19:51344 ///
345 /// # Example
346 ///
347 /// ```rust
348 /// use std::collections::RingBuf;
349 ///
350 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47351 /// buf.push_back(5i);
352 /// buf.push_back(3);
353 /// buf.push_back(4);
Nick Cameron52ef4622014-08-06 09:59:40354 /// let b: &[_] = &[&5, &3, &4];
355 /// assert_eq!(buf.iter().collect::<Vec<&int>>().as_slice(), b);
nhamebe80972014-07-17 23:19:51356 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47357 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24358 pub fn iter(&self) -> Items<T> {
Colin Sherratt7a666df2014-10-19 20:19:07359 Items {
360 tail: self.tail,
361 head: self.head,
362 ring: unsafe { self.buffer_as_slice() }
363 }
blake2-ppc3385e792013-07-15 23:13:26364 }
365
P1startf2aa88c2014-08-04 10:48:39366 /// Returns a front-to-back iterator which returns mutable references.
nhamebe80972014-07-17 23:19:51367 ///
368 /// # Example
369 ///
370 /// ```rust
371 /// use std::collections::RingBuf;
372 ///
373 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47374 /// buf.push_back(5i);
375 /// buf.push_back(3);
376 /// buf.push_back(4);
Aaron Turonfc525ee2014-09-15 03:27:36377 /// for num in buf.iter_mut() {
nhamebe80972014-07-17 23:19:51378 /// *num = *num - 2;
379 /// }
Nick Cameron52ef4622014-08-06 09:59:40380 /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
Nick Cameron59976942014-09-24 11:41:09381 /// assert_eq!(buf.iter_mut().collect::<Vec<&mut int>>()[], b);
nhamebe80972014-07-17 23:19:51382 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47383 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Colin Sherratt7a666df2014-10-19 20:19:07384 pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {
385 MutItems {
386 tail: self.tail,
387 head: self.head,
388 cap: self.cap,
389 ptr: self.ptr,
390 marker: marker::ContravariantLifetime::<'a>,
391 marker2: marker::NoCopy
Niko Matsakisbc4164d2013-11-16 22:29:39392 }
Jed Estep4f7a7422013-06-25 19:08:47393 }
Alex Crichton21ac9852014-10-30 20:43:24394
Alexis Beingessner865c2db2014-11-23 02:34:11395 /// Consumes the list into an iterator yielding elements by value.
396 #[unstable = "matches collection reform specification, waiting for dust to settle"]
397 pub fn into_iter(self) -> MoveItems<T> {
398 MoveItems {
399 inner: self,
400 }
401 }
402
Alex Crichton21ac9852014-10-30 20:43:24403 /// Returns the number of elements in the `RingBuf`.
404 ///
405 /// # Example
406 ///
407 /// ```
408 /// use std::collections::RingBuf;
409 ///
410 /// let mut v = RingBuf::new();
411 /// assert_eq!(v.len(), 0);
Alexis Beingessnercf3b2e42014-11-06 17:24:47412 /// v.push_back(1i);
Alex Crichton21ac9852014-10-30 20:43:24413 /// assert_eq!(v.len(), 1);
414 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47415 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Colin Sherratt7a666df2014-10-19 20:19:07416 pub fn len(&self) -> uint { count(self.tail, self.head, self.cap) }
Alex Crichton21ac9852014-10-30 20:43:24417
418 /// Returns true if the buffer contains no elements
419 ///
420 /// # Example
421 ///
422 /// ```
423 /// use std::collections::RingBuf;
424 ///
425 /// let mut v = RingBuf::new();
426 /// assert!(v.is_empty());
427 /// v.push_front(1i);
428 /// assert!(!v.is_empty());
429 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47430 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24431 pub fn is_empty(&self) -> bool { self.len() == 0 }
432
433 /// Clears the buffer, removing all values.
434 ///
435 /// # Example
436 ///
437 /// ```
438 /// use std::collections::RingBuf;
439 ///
440 /// let mut v = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47441 /// v.push_back(1i);
Alex Crichton21ac9852014-10-30 20:43:24442 /// v.clear();
443 /// assert!(v.is_empty());
444 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47445 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24446 pub fn clear(&mut self) {
Colin Sherrattba24e332014-11-10 03:34:53447 while self.pop_front().is_some() {}
Colin Sherratt7a666df2014-10-19 20:19:07448 self.head = 0;
449 self.tail = 0;
Alex Crichton21ac9852014-10-30 20:43:24450 }
451
452 /// Provides a reference to the front element, or `None` if the sequence is
453 /// empty.
454 ///
455 /// # Example
456 ///
457 /// ```
458 /// use std::collections::RingBuf;
459 ///
460 /// let mut d = RingBuf::new();
461 /// assert_eq!(d.front(), None);
462 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47463 /// d.push_back(1i);
464 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24465 /// assert_eq!(d.front(), Some(&1i));
466 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47467 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24468 pub fn front(&self) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07469 if !self.is_empty() { Some(&self[0]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24470 }
471
472 /// Provides a mutable reference to the front element, or `None` if the
473 /// sequence is empty.
474 ///
475 /// # Example
476 ///
477 /// ```
478 /// use std::collections::RingBuf;
479 ///
480 /// let mut d = RingBuf::new();
481 /// assert_eq!(d.front_mut(), None);
482 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47483 /// d.push_back(1i);
484 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24485 /// match d.front_mut() {
486 /// Some(x) => *x = 9i,
487 /// None => (),
488 /// }
489 /// assert_eq!(d.front(), Some(&9i));
490 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47491 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24492 pub fn front_mut(&mut self) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07493 if !self.is_empty() { Some(&mut self[0]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24494 }
495
496 /// Provides a reference to the back element, or `None` if the sequence is
497 /// empty.
498 ///
499 /// # Example
500 ///
501 /// ```
502 /// use std::collections::RingBuf;
503 ///
504 /// let mut d = RingBuf::new();
505 /// assert_eq!(d.back(), None);
506 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47507 /// d.push_back(1i);
508 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24509 /// assert_eq!(d.back(), Some(&2i));
510 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47511 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24512 pub fn back(&self) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07513 if !self.is_empty() { Some(&self[self.len() - 1]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24514 }
515
516 /// Provides a mutable reference to the back element, or `None` if the
517 /// sequence is empty.
518 ///
519 /// # Example
520 ///
521 /// ```
522 /// use std::collections::RingBuf;
523 ///
524 /// let mut d = RingBuf::new();
525 /// assert_eq!(d.back(), None);
526 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47527 /// d.push_back(1i);
528 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24529 /// match d.back_mut() {
530 /// Some(x) => *x = 9i,
531 /// None => (),
532 /// }
533 /// assert_eq!(d.back(), Some(&9i));
534 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47535 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24536 pub fn back_mut(&mut self) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07537 let len = self.len();
538 if !self.is_empty() { Some(&mut self[len - 1]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24539 }
540
541 /// Removes the first element and returns it, or `None` if the sequence is
542 /// empty.
543 ///
544 /// # Example
545 ///
546 /// ```
547 /// use std::collections::RingBuf;
548 ///
549 /// let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47550 /// d.push_back(1i);
551 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24552 ///
553 /// assert_eq!(d.pop_front(), Some(1i));
554 /// assert_eq!(d.pop_front(), Some(2i));
555 /// assert_eq!(d.pop_front(), None);
556 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47557 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24558 pub fn pop_front(&mut self) -> Option<T> {
Colin Sherratt7a666df2014-10-19 20:19:07559 if self.is_empty() {
560 None
561 } else {
562 let tail = self.tail;
Colin Sherratt40191182014-11-12 01:22:07563 self.tail = self.wrap_index(self.tail + 1);
Colin Sherratt7a666df2014-10-19 20:19:07564 unsafe { Some(self.buffer_read(tail)) }
Alex Crichton21ac9852014-10-30 20:43:24565 }
Alex Crichton21ac9852014-10-30 20:43:24566 }
567
568 /// Inserts an element first in the sequence.
569 ///
570 /// # Example
571 ///
572 /// ```
573 /// use std::collections::RingBuf;
574 ///
575 /// let mut d = RingBuf::new();
576 /// d.push_front(1i);
577 /// d.push_front(2i);
578 /// assert_eq!(d.front(), Some(&2i));
579 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47580 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24581 pub fn push_front(&mut self, t: T) {
Colin Sherratt4cae9ad2014-11-11 02:16:29582 if self.is_full() {
583 self.reserve(1);
584 debug_assert!(!self.is_full());
585 }
Colin Sherratt7a666df2014-10-19 20:19:07586
Colin Sherratt40191182014-11-12 01:22:07587 self.tail = self.wrap_index(self.tail - 1);
Colin Sherratt7a666df2014-10-19 20:19:07588 let tail = self.tail;
589 unsafe { self.buffer_write(tail, t); }
Alex Crichton21ac9852014-10-30 20:43:24590 }
591
Alexis Beingessnercf3b2e42014-11-06 17:24:47592 /// Deprecated: Renamed to `push_back`.
593 #[deprecated = "Renamed to `push_back`"]
594 pub fn push(&mut self, t: T) {
595 self.push_back(t)
596 }
597
Alex Crichton21ac9852014-10-30 20:43:24598 /// Appends an element to the back of a buffer
599 ///
600 /// # Example
601 ///
602 /// ```rust
603 /// use std::collections::RingBuf;
604 ///
605 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47606 /// buf.push_back(1i);
607 /// buf.push_back(3);
Alex Crichton21ac9852014-10-30 20:43:24608 /// assert_eq!(3, *buf.back().unwrap());
609 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47610 #[unstable = "matches collection reform specification, waiting for dust to settle"]
611 pub fn push_back(&mut self, t: T) {
Colin Sherratt4cae9ad2014-11-11 02:16:29612 if self.is_full() {
613 self.reserve(1);
614 debug_assert!(!self.is_full());
615 }
Colin Sherratt7a666df2014-10-19 20:19:07616
617 let head = self.head;
Colin Sherratt40191182014-11-12 01:22:07618 self.head = self.wrap_index(self.head + 1);
Colin Sherratt7a666df2014-10-19 20:19:07619 unsafe { self.buffer_write(head, t) }
Alex Crichton21ac9852014-10-30 20:43:24620 }
621
Alexis Beingessnercf3b2e42014-11-06 17:24:47622 /// Deprecated: Renamed to `pop_back`.
623 #[deprecated = "Renamed to `pop_back`"]
624 pub fn pop(&mut self) -> Option<T> {
625 self.pop_back()
626 }
627
Alex Crichton21ac9852014-10-30 20:43:24628 /// Removes the last element from a buffer and returns it, or `None` if
629 /// it is empty.
630 ///
631 /// # Example
632 ///
633 /// ```rust
634 /// use std::collections::RingBuf;
635 ///
636 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47637 /// assert_eq!(buf.pop_back(), None);
638 /// buf.push_back(1i);
639 /// buf.push_back(3);
640 /// assert_eq!(buf.pop_back(), Some(3));
Alex Crichton21ac9852014-10-30 20:43:24641 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47642 #[unstable = "matches collection reform specification, waiting for dust to settle"]
643 pub fn pop_back(&mut self) -> Option<T> {
Colin Sherratt7a666df2014-10-19 20:19:07644 if self.is_empty() {
Alex Crichton21ac9852014-10-30 20:43:24645 None
Colin Sherratt7a666df2014-10-19 20:19:07646 } else {
Colin Sherratt40191182014-11-12 01:22:07647 self.head = self.wrap_index(self.head - 1);
Colin Sherratt7a666df2014-10-19 20:19:07648 let head = self.head;
649 unsafe { Some(self.buffer_read(head)) }
Alex Crichton21ac9852014-10-30 20:43:24650 }
651 }
Jed Estep4f7a7422013-06-25 19:08:47652}
653
Colin Sherratt7a666df2014-10-19 20:19:07654/// Returns the index in the underlying buffer for a given logical element index.
655#[inline]
656fn wrap_index(index: uint, size: uint) -> uint {
657 // size is always a power of 2
Colin Sherratt40191182014-11-12 01:22:07658 index & (size - 1)
Colin Sherratt7a666df2014-10-19 20:19:07659}
660
661/// Calculate the number of elements left to be read in the buffer
662#[inline]
663fn count(tail: uint, head: uint, size: uint) -> uint {
664 // size is always a power of 2
665 (head - tail) & (size - 1)
666}
667
Niko Matsakis1b487a82014-08-28 01:46:52668/// `RingBuf` iterator.
Niko Matsakis1b487a82014-08-28 01:46:52669pub struct Items<'a, T:'a> {
Colin Sherratt7a666df2014-10-19 20:19:07670 ring: &'a [T],
671 tail: uint,
672 head: uint
Niko Matsakis1b487a82014-08-28 01:46:52673}
674
Palmer Cox3fd8c8b2014-01-15 03:32:24675impl<'a, T> Iterator<&'a T> for Items<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:39676 #[inline]
Erik Price5731ca32013-12-10 07:16:18677 fn next(&mut self) -> Option<&'a T> {
Colin Sherratt7a666df2014-10-19 20:19:07678 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:39679 return None;
680 }
Colin Sherratt7a666df2014-10-19 20:19:07681 let tail = self.tail;
682 self.tail = wrap_index(self.tail + 1, self.ring.len());
683 unsafe { Some(self.ring.unsafe_get(tail)) }
Niko Matsakisbc4164d2013-11-16 22:29:39684 }
685
686 #[inline]
687 fn size_hint(&self) -> (uint, Option<uint>) {
Colin Sherratt7a666df2014-10-19 20:19:07688 let len = count(self.tail, self.head, self.ring.len());
Niko Matsakisbc4164d2013-11-16 22:29:39689 (len, Some(len))
690 }
691}
692
Palmer Cox3fd8c8b2014-01-15 03:32:24693impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:39694 #[inline]
Erik Price5731ca32013-12-10 07:16:18695 fn next_back(&mut self) -> Option<&'a T> {
Colin Sherratt7a666df2014-10-19 20:19:07696 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:39697 return None;
698 }
Colin Sherratt7a666df2014-10-19 20:19:07699 self.head = wrap_index(self.head - 1, self.ring.len());
700 unsafe { Some(self.ring.unsafe_get(self.head)) }
Niko Matsakisbc4164d2013-11-16 22:29:39701 }
702}
Jed Estep35314c92013-06-26 15:38:29703
Aaron Turonb299c2b2014-11-06 17:32:37704impl<'a, T> ExactSizeIterator<&'a T> for Items<'a, T> {}
blake2-ppc7c369ee72013-09-01 16:20:24705
Palmer Cox3fd8c8b2014-01-15 03:32:24706impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
blake2-ppcf6862132013-07-29 18:16:26707 #[inline]
Colin Sherratt7a666df2014-10-19 20:19:07708 fn indexable(&self) -> uint {
709 let (len, _) = self.size_hint();
710 len
711 }
blake2-ppcf6862132013-07-29 18:16:26712
713 #[inline]
Alex Crichtonf4083a22014-04-22 05:15:42714 fn idx(&mut self, j: uint) -> Option<&'a T> {
blake2-ppcf6862132013-07-29 18:16:26715 if j >= self.indexable() {
716 None
717 } else {
Colin Sherratt7a666df2014-10-19 20:19:07718 let idx = wrap_index(self.tail + j, self.ring.len());
719 unsafe { Some(self.ring.unsafe_get(idx)) }
blake2-ppcf6862132013-07-29 18:16:26720 }
721 }
722}
723
Colin Sherratt7a666df2014-10-19 20:19:07724// FIXME This was implemented differently from Items because of a problem
725// with returning the mutable reference. I couldn't find a way to
726// make the lifetime checker happy so, but there should be a way.
Niko Matsakis1b487a82014-08-28 01:46:52727/// `RingBuf` mutable iterator.
Niko Matsakis1b487a82014-08-28 01:46:52728pub struct MutItems<'a, T:'a> {
Colin Sherratt7a666df2014-10-19 20:19:07729 ptr: *mut T,
730 tail: uint,
731 head: uint,
732 cap: uint,
733 marker: marker::ContravariantLifetime<'a>,
734 marker2: marker::NoCopy
Niko Matsakis1b487a82014-08-28 01:46:52735}
736
Palmer Cox3fd8c8b2014-01-15 03:32:24737impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:39738 #[inline]
Erik Price5731ca32013-12-10 07:16:18739 fn next(&mut self) -> Option<&'a mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07740 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:39741 return None;
742 }
Colin Sherratt7a666df2014-10-19 20:19:07743 let tail = self.tail;
744 self.tail = wrap_index(self.tail + 1, self.cap);
Alexis Beingessner865c2db2014-11-23 02:34:11745
746 unsafe {
747 Some(&mut *self.ptr.offset(tail as int))
Alex Crichton9d5d97b2014-10-15 06:05:01748 }
Niko Matsakisbc4164d2013-11-16 22:29:39749 }
750
751 #[inline]
752 fn size_hint(&self) -> (uint, Option<uint>) {
Colin Sherratt7a666df2014-10-19 20:19:07753 let len = count(self.tail, self.head, self.cap);
754 (len, Some(len))
Niko Matsakisbc4164d2013-11-16 22:29:39755 }
756}
757
Palmer Cox3fd8c8b2014-01-15 03:32:24758impl<'a, T> DoubleEndedIterator<&'a mut T> for MutItems<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:39759 #[inline]
Erik Price5731ca32013-12-10 07:16:18760 fn next_back(&mut self) -> Option<&'a mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07761 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:39762 return None;
763 }
Colin Sherratt7a666df2014-10-19 20:19:07764 self.head = wrap_index(self.head - 1, self.cap);
Alexis Beingessner865c2db2014-11-23 02:34:11765
766 unsafe {
767 Some(&mut *self.ptr.offset(self.head as int))
768 }
Niko Matsakisbc4164d2013-11-16 22:29:39769 }
770}
Daniel Micayb47e1e92013-02-16 22:55:55771
Aaron Turonb299c2b2014-11-06 17:32:37772impl<'a, T> ExactSizeIterator<&'a mut T> for MutItems<'a, T> {}
blake2-ppc7c369ee72013-09-01 16:20:24773
Alexis Beingessner865c2db2014-11-23 02:34:11774// A by-value RingBuf iterator
775pub struct MoveItems<T> {
776 inner: RingBuf<T>,
777}
778
779impl<T> Iterator<T> for MoveItems<T> {
780 #[inline]
781 fn next(&mut self) -> Option<T> {
782 self.inner.pop_front()
783 }
784
785 #[inline]
786 fn size_hint(&self) -> (uint, Option<uint>) {
787 let len = self.inner.len();
788 (len, Some(len))
789 }
790}
791
792impl<T> DoubleEndedIterator<T> for MoveItems<T> {
793 #[inline]
794 fn next_back(&mut self) -> Option<T> {
795 self.inner.pop_back()
796 }
797}
798
799
Alex Crichton5816d7f2014-11-26 19:17:23800impl<T> ExactSizeIterator<T> for MoveItems<T> {}
Alexis Beingessner865c2db2014-11-23 02:34:11801
Alex Crichton748bc3c2014-05-30 00:45:07802impl<A: PartialEq> PartialEq for RingBuf<A> {
blake2-ppc70523712013-07-10 13:27:14803 fn eq(&self, other: &RingBuf<A>) -> bool {
Colin Sherratt7a666df2014-10-19 20:19:07804 self.len() == other.len() &&
blake2-ppc10c76982013-07-06 13:27:32805 self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
806 }
blake2-ppc70523712013-07-10 13:27:14807 fn ne(&self, other: &RingBuf<A>) -> bool {
blake2-ppc10c76982013-07-06 13:27:32808 !self.eq(other)
809 }
810}
811
nham25acfde2014-08-01 20:05:03812impl<A: Eq> Eq for RingBuf<A> {}
813
nham63615772014-07-27 03:18:56814impl<A: PartialOrd> PartialOrd for RingBuf<A> {
815 fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
816 iter::order::partial_cmp(self.iter(), other.iter())
817 }
818}
819
nham3737c532014-08-01 20:22:48820impl<A: Ord> Ord for RingBuf<A> {
821 #[inline]
822 fn cmp(&self, other: &RingBuf<A>) -> Ordering {
823 iter::order::cmp(self.iter(), other.iter())
824 }
825}
826
nham1cfa6562014-07-27 02:33:47827impl<S: Writer, A: Hash<S>> Hash<S> for RingBuf<A> {
828 fn hash(&self, state: &mut S) {
nham9fa44242014-07-27 16:37:32829 self.len().hash(state);
nham1cfa6562014-07-27 02:33:47830 for elt in self.iter() {
831 elt.hash(state);
832 }
833 }
834}
835
P1startfd10d202014-08-02 06:39:39836impl<A> Index<uint, A> for RingBuf<A> {
837 #[inline]
838 fn index<'a>(&'a self, i: &uint) -> &'a A {
Colin Sherratt7a666df2014-10-19 20:19:07839 self.get(*i).expect("Out of bounds access")
P1startfd10d202014-08-02 06:39:39840 }
841}
842
Alex Crichton1d356622014-10-23 15:42:21843impl<A> IndexMut<uint, A> for RingBuf<A> {
P1startfd10d202014-08-02 06:39:39844 #[inline]
Alex Crichton1d356622014-10-23 15:42:21845 fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut A {
Colin Sherratt7a666df2014-10-19 20:19:07846 self.get_mut(*i).expect("Out of bounds access")
P1startfd10d202014-08-02 06:39:39847 }
Alex Crichton1d356622014-10-23 15:42:21848}
P1startfd10d202014-08-02 06:39:39849
Huon Wilson53487a02013-08-13 13:08:14850impl<A> FromIterator<A> for RingBuf<A> {
Brian Andersonee052192014-03-31 04:45:55851 fn from_iter<T: Iterator<A>>(iterator: T) -> RingBuf<A> {
blake2-ppcf8ae5262013-07-30 00:06:49852 let (lower, _) = iterator.size_hint();
853 let mut deq = RingBuf::with_capacity(lower);
854 deq.extend(iterator);
blake2-ppc08dc72f2013-07-06 03:42:45855 deq
856 }
857}
858
gamazeps16c8cd92014-11-08 00:39:39859impl<A> Extend<A> for RingBuf<A> {
Marvin Löbel6200e762014-03-20 13:12:56860 fn extend<T: Iterator<A>>(&mut self, mut iterator: T) {
861 for elt in iterator {
Alexis Beingessnercf3b2e42014-11-06 17:24:47862 self.push_back(elt);
blake2-ppcf8ae5262013-07-30 00:06:49863 }
864 }
865}
866
Alex Crichton6a585372014-05-30 01:50:12867impl<T: fmt::Show> fmt::Show for RingBuf<T> {
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:04868 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
869 try!(write!(f, "["));
870
871 for (i, e) in self.iter().enumerate() {
872 if i != 0 { try!(write!(f, ", ")); }
873 try!(write!(f, "{}", *e));
874 }
875
876 write!(f, "]")
877 }
878}
879
Brian Anderson6e27b272012-01-18 03:05:07880#[cfg(test)]
881mod tests {
Steven Fackler3dcd2152014-11-06 08:05:53882 use self::Taggy::*;
883 use self::Taggypar::*;
Alex Crichton02882fb2014-02-28 09:23:06884 use std::fmt::Show;
Alex Crichton760b93a2014-05-30 02:03:06885 use std::prelude::*;
nham1cfa6562014-07-27 02:33:47886 use std::hash;
Alex Crichton760b93a2014-05-30 02:03:06887 use test::Bencher;
888 use test;
889
Alex Crichtonf47e4b22014-01-07 06:33:50890 use super::RingBuf;
Alex Crichton760b93a2014-05-30 02:03:06891 use vec::Vec;
Patrick Waltonfa5ee932012-12-28 02:24:18892
Brian Anderson6e27b272012-01-18 03:05:07893 #[test]
Victor Berger52ea83d2014-09-22 17:30:06894 #[allow(deprecated)]
Brian Anderson6e27b272012-01-18 03:05:07895 fn test_simple() {
blake2-ppc70523712013-07-10 13:27:14896 let mut d = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:45897 assert_eq!(d.len(), 0u);
Niko Matsakis9e3d0b02014-04-21 21:58:52898 d.push_front(17i);
899 d.push_front(42i);
Alexis Beingessnercf3b2e42014-11-06 17:24:47900 d.push_back(137);
Corey Richardsoncc57ca02013-05-19 02:02:45901 assert_eq!(d.len(), 3u);
Alexis Beingessnercf3b2e42014-11-06 17:24:47902 d.push_back(137);
Corey Richardsoncc57ca02013-05-19 02:02:45903 assert_eq!(d.len(), 4u);
Luqman Aden3ef9aa02014-10-15 07:22:55904 debug!("{}", d.front());
blake2-ppc70523712013-07-10 13:27:14905 assert_eq!(*d.front().unwrap(), 42);
Luqman Aden3ef9aa02014-10-15 07:22:55906 debug!("{}", d.back());
blake2-ppc70523712013-07-10 13:27:14907 assert_eq!(*d.back().unwrap(), 137);
908 let mut i = d.pop_front();
Luqman Aden3ef9aa02014-10-15 07:22:55909 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:14910 assert_eq!(i, Some(42));
Alexis Beingessnercf3b2e42014-11-06 17:24:47911 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:55912 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:14913 assert_eq!(i, Some(137));
Alexis Beingessnercf3b2e42014-11-06 17:24:47914 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:55915 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:14916 assert_eq!(i, Some(137));
Alexis Beingessnercf3b2e42014-11-06 17:24:47917 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:55918 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:14919 assert_eq!(i, Some(17));
Corey Richardsoncc57ca02013-05-19 02:02:45920 assert_eq!(d.len(), 0u);
Alexis Beingessnercf3b2e42014-11-06 17:24:47921 d.push_back(3);
Corey Richardsoncc57ca02013-05-19 02:02:45922 assert_eq!(d.len(), 1u);
blake2-ppc70523712013-07-10 13:27:14923 d.push_front(2);
Corey Richardsoncc57ca02013-05-19 02:02:45924 assert_eq!(d.len(), 2u);
Alexis Beingessnercf3b2e42014-11-06 17:24:47925 d.push_back(4);
Corey Richardsoncc57ca02013-05-19 02:02:45926 assert_eq!(d.len(), 3u);
blake2-ppc70523712013-07-10 13:27:14927 d.push_front(1);
Corey Richardsoncc57ca02013-05-19 02:02:45928 assert_eq!(d.len(), 4u);
Alex Crichton9d5d97b2014-10-15 06:05:01929 debug!("{}", d[0]);
930 debug!("{}", d[1]);
931 debug!("{}", d[2]);
932 debug!("{}", d[3]);
933 assert_eq!(d[0], 1);
934 assert_eq!(d[1], 2);
935 assert_eq!(d[2], 3);
936 assert_eq!(d[3], 4);
Brian Anderson6e27b272012-01-18 03:05:07937 }
938
Felix S. Klock IIa636f512013-05-01 23:32:37939 #[cfg(test)]
Alex Crichton748bc3c2014-05-30 00:45:07940 fn test_parameterized<T:Clone + PartialEq + Show>(a: T, b: T, c: T, d: T) {
Patrick Waltondc4bf172013-07-13 04:05:59941 let mut deq = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:45942 assert_eq!(deq.len(), 0);
Patrick Waltondc4bf172013-07-13 04:05:59943 deq.push_front(a.clone());
944 deq.push_front(b.clone());
Alexis Beingessnercf3b2e42014-11-06 17:24:47945 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45946 assert_eq!(deq.len(), 3);
Alexis Beingessnercf3b2e42014-11-06 17:24:47947 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45948 assert_eq!(deq.len(), 4);
Marvin Löbel0ac7a212013-08-03 23:59:24949 assert_eq!((*deq.front().unwrap()).clone(), b.clone());
950 assert_eq!((*deq.back().unwrap()).clone(), d.clone());
951 assert_eq!(deq.pop_front().unwrap(), b.clone());
Alexis Beingessnercf3b2e42014-11-06 17:24:47952 assert_eq!(deq.pop_back().unwrap(), d.clone());
953 assert_eq!(deq.pop_back().unwrap(), c.clone());
954 assert_eq!(deq.pop_back().unwrap(), a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45955 assert_eq!(deq.len(), 0);
Alexis Beingessnercf3b2e42014-11-06 17:24:47956 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45957 assert_eq!(deq.len(), 1);
Patrick Waltondc4bf172013-07-13 04:05:59958 deq.push_front(b.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45959 assert_eq!(deq.len(), 2);
Alexis Beingessnercf3b2e42014-11-06 17:24:47960 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45961 assert_eq!(deq.len(), 3);
Patrick Waltondc4bf172013-07-13 04:05:59962 deq.push_front(a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45963 assert_eq!(deq.len(), 4);
NODA, Kaif27ad3d2014-10-05 10:11:17964 assert_eq!(deq[0].clone(), a.clone());
965 assert_eq!(deq[1].clone(), b.clone());
966 assert_eq!(deq[2].clone(), c.clone());
967 assert_eq!(deq[3].clone(), d.clone());
Brian Anderson6e27b272012-01-18 03:05:07968 }
969
blake2-ppc81933ed2013-07-06 03:42:45970 #[test]
blake2-ppc70523712013-07-10 13:27:14971 fn test_push_front_grow() {
972 let mut deq = RingBuf::new();
Daniel Micay100894552013-08-03 16:45:23973 for i in range(0u, 66) {
blake2-ppc70523712013-07-10 13:27:14974 deq.push_front(i);
blake2-ppc81933ed2013-07-06 03:42:45975 }
976 assert_eq!(deq.len(), 66);
977
Daniel Micay100894552013-08-03 16:45:23978 for i in range(0u, 66) {
NODA, Kaif27ad3d2014-10-05 10:11:17979 assert_eq!(deq[i], 65 - i);
blake2-ppc81933ed2013-07-06 03:42:45980 }
981
blake2-ppc70523712013-07-10 13:27:14982 let mut deq = RingBuf::new();
Daniel Micay100894552013-08-03 16:45:23983 for i in range(0u, 66) {
Alexis Beingessnercf3b2e42014-11-06 17:24:47984 deq.push_back(i);
blake2-ppc81933ed2013-07-06 03:42:45985 }
986
Daniel Micay100894552013-08-03 16:45:23987 for i in range(0u, 66) {
NODA, Kaif27ad3d2014-10-05 10:11:17988 assert_eq!(deq[i], i);
blake2-ppc81933ed2013-07-06 03:42:45989 }
990 }
991
P1startfd10d202014-08-02 06:39:39992 #[test]
993 fn test_index() {
994 let mut deq = RingBuf::new();
995 for i in range(1u, 4) {
996 deq.push_front(i);
997 }
998 assert_eq!(deq[1], 2);
999 }
1000
1001 #[test]
1002 #[should_fail]
1003 fn test_index_out_of_bounds() {
1004 let mut deq = RingBuf::new();
1005 for i in range(1u, 4) {
1006 deq.push_front(i);
1007 }
1008 deq[3];
1009 }
1010
blake2-ppc81933ed2013-07-06 03:42:451011 #[bench]
Liigo Zhuang408f4842014-04-01 01:16:351012 fn bench_new(b: &mut test::Bencher) {
Patrick Walton38efa172013-11-22 03:20:481013 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521014 let ring: RingBuf<u64> = RingBuf::new();
1015 test::black_box(ring);
Patrick Walton38efa172013-11-22 03:20:481016 })
blake2-ppc81933ed2013-07-06 03:42:451017 }
1018
1019 #[bench]
Colin Sherratt7a666df2014-10-19 20:19:071020 fn bench_push_back_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521021 let mut deq = RingBuf::with_capacity(101);
Patrick Walton38efa172013-11-22 03:20:481022 b.iter(|| {
Colin Sherratt7a666df2014-10-19 20:19:071023 for i in range(0i, 100) {
1024 deq.push_back(i);
1025 }
Colin Sherratt5e549d82014-11-11 02:57:521026 deq.head = 0;
1027 deq.tail = 0;
Patrick Walton38efa172013-11-22 03:20:481028 })
blake2-ppc81933ed2013-07-06 03:42:451029 }
1030
1031 #[bench]
Colin Sherratt7a666df2014-10-19 20:19:071032 fn bench_push_front_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521033 let mut deq = RingBuf::with_capacity(101);
Patrick Walton38efa172013-11-22 03:20:481034 b.iter(|| {
Colin Sherratt7a666df2014-10-19 20:19:071035 for i in range(0i, 100) {
1036 deq.push_front(i);
1037 }
Colin Sherratt5e549d82014-11-11 02:57:521038 deq.head = 0;
1039 deq.tail = 0;
Patrick Walton38efa172013-11-22 03:20:481040 })
blake2-ppc81933ed2013-07-06 03:42:451041 }
1042
1043 #[bench]
Colin Sherratt5e549d82014-11-11 02:57:521044 fn bench_pop_back_100(b: &mut test::Bencher) {
1045 let mut deq: RingBuf<int> = RingBuf::with_capacity(101);
Colin Sherratt7a666df2014-10-19 20:19:071046
Patrick Walton38efa172013-11-22 03:20:481047 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521048 deq.head = 100;
1049 deq.tail = 0;
1050 while !deq.is_empty() {
1051 test::black_box(deq.pop_back());
Colin Sherratt7a666df2014-10-19 20:19:071052 }
Colin Sherratt7a666df2014-10-19 20:19:071053 })
1054 }
1055
1056 #[bench]
1057 fn bench_pop_front_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521058 let mut deq: RingBuf<int> = RingBuf::with_capacity(101);
Colin Sherratt7a666df2014-10-19 20:19:071059
1060 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521061 deq.head = 100;
1062 deq.tail = 0;
1063 while !deq.is_empty() {
1064 test::black_box(deq.pop_front());
Colin Sherratt7a666df2014-10-19 20:19:071065 }
Colin Sherratt7a666df2014-10-19 20:19:071066 })
1067 }
1068
1069 #[bench]
1070 fn bench_grow_1025(b: &mut test::Bencher) {
1071 b.iter(|| {
1072 let mut deq = RingBuf::new();
1073 for i in range(0i, 1025) {
1074 deq.push_front(i);
Brendan Zabarauskas729060d2014-01-30 00:20:341075 }
Colin Sherratt5e549d82014-11-11 02:57:521076 test::black_box(deq);
Patrick Walton38efa172013-11-22 03:20:481077 })
blake2-ppc81933ed2013-07-06 03:42:451078 }
1079
Colin Sherratt7a666df2014-10-19 20:19:071080 #[bench]
1081 fn bench_iter_1000(b: &mut test::Bencher) {
1082 let ring: RingBuf<int> = range(0i, 1000).collect();
1083
1084 b.iter(|| {
1085 let mut sum = 0;
1086 for &i in ring.iter() {
1087 sum += i;
1088 }
Colin Sherratt5e549d82014-11-11 02:57:521089 test::black_box(sum);
Colin Sherratt7a666df2014-10-19 20:19:071090 })
1091 }
1092
1093 #[bench]
1094 fn bench_mut_iter_1000(b: &mut test::Bencher) {
1095 let mut ring: RingBuf<int> = range(0i, 1000).collect();
1096
1097 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521098 let mut sum = 0;
Colin Sherratt7a666df2014-10-19 20:19:071099 for i in ring.iter_mut() {
Colin Sherratt5e549d82014-11-11 02:57:521100 sum += *i;
Colin Sherratt7a666df2014-10-19 20:19:071101 }
Colin Sherratt5e549d82014-11-11 02:57:521102 test::black_box(sum);
Colin Sherratt7a666df2014-10-19 20:19:071103 })
1104 }
1105
1106
Alex Crichton748bc3c2014-05-30 00:45:071107 #[deriving(Clone, PartialEq, Show)]
Patrick Walton99b33f72013-07-02 19:47:321108 enum Taggy {
1109 One(int),
1110 Two(int, int),
1111 Three(int, int, int),
Brian Anderson6e27b272012-01-18 03:05:071112 }
1113
Alex Crichton748bc3c2014-05-30 00:45:071114 #[deriving(Clone, PartialEq, Show)]
Patrick Walton99b33f72013-07-02 19:47:321115 enum Taggypar<T> {
1116 Onepar(int),
1117 Twopar(int, int),
1118 Threepar(int, int, int),
1119 }
1120
Alex Crichton748bc3c2014-05-30 00:45:071121 #[deriving(Clone, PartialEq, Show)]
Erick Tryzelaare84576b2013-01-22 16:44:241122 struct RecCy {
1123 x: int,
1124 y: int,
Patrick Waltoneb4d39e2013-01-26 00:57:391125 t: Taggy
Patrick Walton9117dcb2012-09-20 01:00:261126 }
Kevin Cantuc43426e2012-09-13 05:09:551127
1128 #[test]
1129 fn test_param_int() {
1130 test_parameterized::<int>(5, 72, 64, 175);
1131 }
1132
1133 #[test]
Kevin Cantuc43426e2012-09-13 05:09:551134 fn test_param_taggy() {
Corey Richardsonf8ae9b02013-06-26 22:14:351135 test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:551136 }
1137
1138 #[test]
1139 fn test_param_taggypar() {
1140 test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
Ben Striegela605fd02012-08-11 14:08:421141 Twopar::<int>(1, 2),
1142 Threepar::<int>(1, 2, 3),
1143 Twopar::<int>(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:551144 }
Brian Anderson6e27b272012-01-18 03:05:071145
Kevin Cantuc43426e2012-09-13 05:09:551146 #[test]
1147 fn test_param_reccy() {
Erick Tryzelaare84576b2013-01-22 16:44:241148 let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
1149 let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
1150 let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
1151 let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
Kevin Cantuc43426e2012-09-13 05:09:551152 test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
Brian Anderson6e27b272012-01-18 03:05:071153 }
Erick Tryzelaar909d8f02013-03-30 01:02:441154
1155 #[test]
blake2-ppc0ff5c172013-07-06 03:42:451156 fn test_with_capacity() {
blake2-ppc70523712013-07-10 13:27:141157 let mut d = RingBuf::with_capacity(0);
Alexis Beingessnercf3b2e42014-11-06 17:24:471158 d.push_back(1i);
blake2-ppc0ff5c172013-07-06 03:42:451159 assert_eq!(d.len(), 1);
blake2-ppc70523712013-07-10 13:27:141160 let mut d = RingBuf::with_capacity(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471161 d.push_back(1i);
blake2-ppc0ff5c172013-07-06 03:42:451162 assert_eq!(d.len(), 1);
1163 }
1164
1165 #[test]
Kevin Butler64896d62014-08-07 01:11:131166 fn test_with_capacity_non_power_two() {
1167 let mut d3 = RingBuf::with_capacity(3);
Alexis Beingessnercf3b2e42014-11-06 17:24:471168 d3.push_back(1i);
Kevin Butler64896d62014-08-07 01:11:131169
1170 // X = None, | = lo
1171 // [|1, X, X]
1172 assert_eq!(d3.pop_front(), Some(1));
1173 // [X, |X, X]
1174 assert_eq!(d3.front(), None);
1175
1176 // [X, |3, X]
Alexis Beingessnercf3b2e42014-11-06 17:24:471177 d3.push_back(3);
Kevin Butler64896d62014-08-07 01:11:131178 // [X, |3, 6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471179 d3.push_back(6);
Kevin Butler64896d62014-08-07 01:11:131180 // [X, X, |6]
1181 assert_eq!(d3.pop_front(), Some(3));
1182
1183 // Pushing the lo past half way point to trigger
1184 // the 'B' scenario for growth
1185 // [9, X, |6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471186 d3.push_back(9);
Kevin Butler64896d62014-08-07 01:11:131187 // [9, 12, |6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471188 d3.push_back(12);
Kevin Butler64896d62014-08-07 01:11:131189
Alexis Beingessnercf3b2e42014-11-06 17:24:471190 d3.push_back(15);
Kevin Butler64896d62014-08-07 01:11:131191 // There used to be a bug here about how the
1192 // RingBuf made growth assumptions about the
1193 // underlying Vec which didn't hold and lead
1194 // to corruption.
1195 // (Vec grows to next power of two)
1196 //good- [9, 12, 15, X, X, X, X, |6]
1197 //bug- [15, 12, X, X, X, |6, X, X]
1198 assert_eq!(d3.pop_front(), Some(6));
1199
1200 // Which leads us to the following state which
1201 // would be a failure case.
1202 //bug- [15, 12, X, X, X, X, |X, X]
1203 assert_eq!(d3.front(), Some(&9));
1204 }
1205
1206 #[test]
David Manescu65f35782014-01-31 13:03:201207 fn test_reserve_exact() {
blake2-ppc70523712013-07-10 13:27:141208 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471209 d.push_back(0u64);
David Manescu65f35782014-01-31 13:03:201210 d.reserve_exact(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471211 assert!(d.capacity() >= 51);
blake2-ppc70523712013-07-10 13:27:141212 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471213 d.push_back(0u32);
David Manescu65f35782014-01-31 13:03:201214 d.reserve_exact(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471215 assert!(d.capacity() >= 51);
Tim Chevalier77de84b2013-05-27 18:47:381216 }
1217
1218 #[test]
David Manescu65f35782014-01-31 13:03:201219 fn test_reserve() {
blake2-ppc70523712013-07-10 13:27:141220 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471221 d.push_back(0u64);
David Manescu65f35782014-01-31 13:03:201222 d.reserve(50);
Colin Sherratt7a666df2014-10-19 20:19:071223 assert!(d.capacity() >= 51);
blake2-ppc70523712013-07-10 13:27:141224 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471225 d.push_back(0u32);
David Manescu65f35782014-01-31 13:03:201226 d.reserve(50);
Colin Sherratt7a666df2014-10-19 20:19:071227 assert!(d.capacity() >= 51);
Tim Chevalier77de84b2013-05-27 18:47:381228 }
1229
Jed Estep096fb792013-06-26 14:04:441230 #[test]
blake2-ppc57757a82013-09-26 07:19:261231 fn test_swap() {
Niko Matsakis9e3d0b02014-04-21 21:58:521232 let mut d: RingBuf<int> = range(0i, 5).collect();
blake2-ppc57757a82013-09-26 07:19:261233 d.pop_front();
1234 d.swap(0, 3);
Huon Wilson4b9a7a22014-04-05 05:45:421235 assert_eq!(d.iter().map(|&x|x).collect::<Vec<int>>(), vec!(4, 2, 3, 1));
blake2-ppc57757a82013-09-26 07:19:261236 }
1237
1238 #[test]
Jed Estep096fb792013-06-26 14:04:441239 fn test_iter() {
blake2-ppc70523712013-07-10 13:27:141240 let mut d = RingBuf::new();
blake2-ppcf88d5322013-07-06 03:42:451241 assert_eq!(d.iter().next(), None);
blake2-ppc9ccf4432013-07-14 20:30:221242 assert_eq!(d.iter().size_hint(), (0, Some(0)));
blake2-ppcf88d5322013-07-06 03:42:451243
Niko Matsakis9e3d0b02014-04-21 21:58:521244 for i in range(0i, 5) {
Alexis Beingessnercf3b2e42014-11-06 17:24:471245 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:441246 }
Nick Cameron37a94b82014-08-04 12:19:021247 {
1248 let b: &[_] = &[&0,&1,&2,&3,&4];
Jorge Apariciof2af07e2014-11-27 16:45:501249 assert_eq!(d.iter().collect::<Vec<&int>>(), b);
Nick Cameron37a94b82014-08-04 12:19:021250 }
Corey Richardsonf8ae9b02013-06-26 22:14:351251
Niko Matsakis9e3d0b02014-04-21 21:58:521252 for i in range(6i, 9) {
blake2-ppc70523712013-07-10 13:27:141253 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:441254 }
Nick Cameron37a94b82014-08-04 12:19:021255 {
1256 let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
Jorge Apariciof2af07e2014-11-27 16:45:501257 assert_eq!(d.iter().collect::<Vec<&int>>(), b);
Nick Cameron37a94b82014-08-04 12:19:021258 }
blake2-ppc9ccf4432013-07-14 20:30:221259
1260 let mut it = d.iter();
1261 let mut len = d.len();
1262 loop {
1263 match it.next() {
1264 None => break,
1265 _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
1266 }
1267 }
Jed Estep096fb792013-06-26 14:04:441268 }
1269
1270 #[test]
1271 fn test_rev_iter() {
blake2-ppc70523712013-07-10 13:27:141272 let mut d = RingBuf::new();
Jonathan S03609e52014-04-21 04:59:121273 assert_eq!(d.iter().rev().next(), None);
blake2-ppcf88d5322013-07-06 03:42:451274
Niko Matsakis9e3d0b02014-04-21 21:58:521275 for i in range(0i, 5) {
Alexis Beingessnercf3b2e42014-11-06 17:24:471276 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:441277 }
Nick Cameron37a94b82014-08-04 12:19:021278 {
1279 let b: &[_] = &[&4,&3,&2,&1,&0];
Jorge Apariciof2af07e2014-11-27 16:45:501280 assert_eq!(d.iter().rev().collect::<Vec<&int>>(), b);
Nick Cameron37a94b82014-08-04 12:19:021281 }
Corey Richardsonf8ae9b02013-06-26 22:14:351282
Niko Matsakis9e3d0b02014-04-21 21:58:521283 for i in range(6i, 9) {
blake2-ppc70523712013-07-10 13:27:141284 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:441285 }
Nick Cameron37a94b82014-08-04 12:19:021286 let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
Jorge Apariciof2af07e2014-11-27 16:45:501287 assert_eq!(d.iter().rev().collect::<Vec<&int>>(), b);
Jed Estep096fb792013-06-26 14:04:441288 }
blake2-ppc08dc72f2013-07-06 03:42:451289
1290 #[test]
Niko Matsakisbc4164d2013-11-16 22:29:391291 fn test_mut_rev_iter_wrap() {
1292 let mut d = RingBuf::with_capacity(3);
Aaron Turonfc525ee2014-09-15 03:27:361293 assert!(d.iter_mut().rev().next().is_none());
Niko Matsakisbc4164d2013-11-16 22:29:391294
Alexis Beingessnercf3b2e42014-11-06 17:24:471295 d.push_back(1i);
1296 d.push_back(2);
1297 d.push_back(3);
Niko Matsakisbc4164d2013-11-16 22:29:391298 assert_eq!(d.pop_front(), Some(1));
Alexis Beingessnercf3b2e42014-11-06 17:24:471299 d.push_back(4);
Niko Matsakisbc4164d2013-11-16 22:29:391300
Aaron Turonfc525ee2014-09-15 03:27:361301 assert_eq!(d.iter_mut().rev().map(|x| *x).collect::<Vec<int>>(),
Huon Wilson4b9a7a22014-04-05 05:45:421302 vec!(4, 3, 2));
Niko Matsakisbc4164d2013-11-16 22:29:391303 }
1304
1305 #[test]
blake2-ppcf88d5322013-07-06 03:42:451306 fn test_mut_iter() {
blake2-ppc70523712013-07-10 13:27:141307 let mut d = RingBuf::new();
Aaron Turonfc525ee2014-09-15 03:27:361308 assert!(d.iter_mut().next().is_none());
blake2-ppcf88d5322013-07-06 03:42:451309
Daniel Micay100894552013-08-03 16:45:231310 for i in range(0u, 3) {
blake2-ppc70523712013-07-10 13:27:141311 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:451312 }
1313
Aaron Turonfc525ee2014-09-15 03:27:361314 for (i, elt) in d.iter_mut().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:451315 assert_eq!(*elt, 2 - i);
1316 *elt = i;
1317 }
1318
1319 {
Aaron Turonfc525ee2014-09-15 03:27:361320 let mut it = d.iter_mut();
blake2-ppcf88d5322013-07-06 03:42:451321 assert_eq!(*it.next().unwrap(), 0);
1322 assert_eq!(*it.next().unwrap(), 1);
1323 assert_eq!(*it.next().unwrap(), 2);
1324 assert!(it.next().is_none());
1325 }
1326 }
1327
1328 #[test]
1329 fn test_mut_rev_iter() {
blake2-ppc70523712013-07-10 13:27:141330 let mut d = RingBuf::new();
Aaron Turonfc525ee2014-09-15 03:27:361331 assert!(d.iter_mut().rev().next().is_none());
blake2-ppcf88d5322013-07-06 03:42:451332
Daniel Micay100894552013-08-03 16:45:231333 for i in range(0u, 3) {
blake2-ppc70523712013-07-10 13:27:141334 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:451335 }
1336
Aaron Turonfc525ee2014-09-15 03:27:361337 for (i, elt) in d.iter_mut().rev().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:451338 assert_eq!(*elt, i);
1339 *elt = i;
1340 }
1341
1342 {
Aaron Turonfc525ee2014-09-15 03:27:361343 let mut it = d.iter_mut().rev();
blake2-ppcf88d5322013-07-06 03:42:451344 assert_eq!(*it.next().unwrap(), 0);
1345 assert_eq!(*it.next().unwrap(), 1);
1346 assert_eq!(*it.next().unwrap(), 2);
1347 assert!(it.next().is_none());
1348 }
1349 }
1350
1351 #[test]
Alexis Beingessner865c2db2014-11-23 02:34:111352 fn test_into_iter() {
1353
1354 // Empty iter
1355 {
1356 let d: RingBuf<int> = RingBuf::new();
1357 let mut iter = d.into_iter();
1358
1359 assert_eq!(iter.size_hint(), (0, Some(0)));
1360 assert_eq!(iter.next(), None);
1361 assert_eq!(iter.size_hint(), (0, Some(0)));
1362 }
1363
1364 // simple iter
1365 {
1366 let mut d = RingBuf::new();
1367 for i in range(0i, 5) {
1368 d.push_back(i);
1369 }
1370
1371 let b = vec![0,1,2,3,4];
1372 assert_eq!(d.into_iter().collect::<Vec<int>>(), b);
1373 }
1374
1375 // wrapped iter
1376 {
1377 let mut d = RingBuf::new();
1378 for i in range(0i, 5) {
1379 d.push_back(i);
1380 }
1381 for i in range(6, 9) {
1382 d.push_front(i);
1383 }
1384
1385 let b = vec![8,7,6,0,1,2,3,4];
1386 assert_eq!(d.into_iter().collect::<Vec<int>>(), b);
1387 }
1388
1389 // partially used
1390 {
1391 let mut d = RingBuf::new();
1392 for i in range(0i, 5) {
1393 d.push_back(i);
1394 }
1395 for i in range(6, 9) {
1396 d.push_front(i);
1397 }
1398
1399 let mut it = d.into_iter();
1400 assert_eq!(it.size_hint(), (8, Some(8)));
1401 assert_eq!(it.next(), Some(8));
1402 assert_eq!(it.size_hint(), (7, Some(7)));
1403 assert_eq!(it.next_back(), Some(4));
1404 assert_eq!(it.size_hint(), (6, Some(6)));
1405 assert_eq!(it.next(), Some(7));
1406 assert_eq!(it.size_hint(), (5, Some(5)));
1407 }
1408 }
1409
1410 #[test]
Brian Andersonee052192014-03-31 04:45:551411 fn test_from_iter() {
Daniel Micay6919cf52013-09-08 15:01:161412 use std::iter;
Niko Matsakis9e3d0b02014-04-21 21:58:521413 let v = vec!(1i,2,3,4,5,6,7);
Erick Tryzelaar68f40d22013-08-10 03:09:471414 let deq: RingBuf<int> = v.iter().map(|&x| x).collect();
Huon Wilson4b9a7a22014-04-05 05:45:421415 let u: Vec<int> = deq.iter().map(|&x| x).collect();
blake2-ppc08dc72f2013-07-06 03:42:451416 assert_eq!(u, v);
1417
Aaron Turonb299c2b2014-11-06 17:32:371418 let seq = iter::count(0u, 2).take(256);
blake2-ppc70523712013-07-10 13:27:141419 let deq: RingBuf<uint> = seq.collect();
Daniel Micay100894552013-08-03 16:45:231420 for (i, &x) in deq.iter().enumerate() {
blake2-ppc08dc72f2013-07-06 03:42:451421 assert_eq!(2*i, x);
1422 }
1423 assert_eq!(deq.len(), 256);
1424 }
blake2-ppc10c76982013-07-06 13:27:321425
1426 #[test]
1427 fn test_clone() {
blake2-ppc70523712013-07-10 13:27:141428 let mut d = RingBuf::new();
Niko Matsakis9e3d0b02014-04-21 21:58:521429 d.push_front(17i);
blake2-ppc70523712013-07-10 13:27:141430 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:471431 d.push_back(137);
1432 d.push_back(137);
blake2-ppc10c76982013-07-06 13:27:321433 assert_eq!(d.len(), 4u);
1434 let mut e = d.clone();
1435 assert_eq!(e.len(), 4u);
1436 while !d.is_empty() {
Alexis Beingessnercf3b2e42014-11-06 17:24:471437 assert_eq!(d.pop_back(), e.pop_back());
blake2-ppc10c76982013-07-06 13:27:321438 }
1439 assert_eq!(d.len(), 0u);
1440 assert_eq!(e.len(), 0u);
1441 }
1442
1443 #[test]
1444 fn test_eq() {
blake2-ppc70523712013-07-10 13:27:141445 let mut d = RingBuf::new();
Alex Crichton02882fb2014-02-28 09:23:061446 assert!(d == RingBuf::with_capacity(0));
Niko Matsakis9e3d0b02014-04-21 21:58:521447 d.push_front(137i);
blake2-ppc70523712013-07-10 13:27:141448 d.push_front(17);
1449 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:471450 d.push_back(137);
blake2-ppc70523712013-07-10 13:27:141451 let mut e = RingBuf::with_capacity(0);
Alexis Beingessnercf3b2e42014-11-06 17:24:471452 e.push_back(42);
1453 e.push_back(17);
1454 e.push_back(137);
1455 e.push_back(137);
Alex Crichton02882fb2014-02-28 09:23:061456 assert!(&e == &d);
Alexis Beingessnercf3b2e42014-11-06 17:24:471457 e.pop_back();
1458 e.push_back(0);
blake2-ppc10c76982013-07-06 13:27:321459 assert!(e != d);
1460 e.clear();
Alex Crichton02882fb2014-02-28 09:23:061461 assert!(e == RingBuf::new());
blake2-ppc10c76982013-07-06 13:27:321462 }
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041463
1464 #[test]
nham1cfa6562014-07-27 02:33:471465 fn test_hash() {
1466 let mut x = RingBuf::new();
1467 let mut y = RingBuf::new();
1468
Alexis Beingessnercf3b2e42014-11-06 17:24:471469 x.push_back(1i);
1470 x.push_back(2);
1471 x.push_back(3);
nham1cfa6562014-07-27 02:33:471472
Alexis Beingessnercf3b2e42014-11-06 17:24:471473 y.push_back(0i);
1474 y.push_back(1i);
nham1cfa6562014-07-27 02:33:471475 y.pop_front();
Alexis Beingessnercf3b2e42014-11-06 17:24:471476 y.push_back(2);
1477 y.push_back(3);
nham1cfa6562014-07-27 02:33:471478
1479 assert!(hash::hash(&x) == hash::hash(&y));
1480 }
1481
1482 #[test]
nham63615772014-07-27 03:18:561483 fn test_ord() {
1484 let x = RingBuf::new();
1485 let mut y = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471486 y.push_back(1i);
1487 y.push_back(2);
1488 y.push_back(3);
nham63615772014-07-27 03:18:561489 assert!(x < y);
1490 assert!(y > x);
1491 assert!(x <= x);
1492 assert!(x >= x);
1493 }
1494
1495 #[test]
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041496 fn test_show() {
Niko Matsakis9e3d0b02014-04-21 21:58:521497 let ringbuf: RingBuf<int> = range(0i, 10).collect();
Jorge Apariciof2af07e2014-11-27 16:45:501498 assert!(format!("{}", ringbuf) == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041499
1500 let ringbuf: RingBuf<&str> = vec!["just", "one", "test", "more"].iter()
1501 .map(|&s| s)
1502 .collect();
Jorge Apariciof2af07e2014-11-27 16:45:501503 assert!(format!("{}", ringbuf) == "[just, one, test, more]");
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041504 }
Colin Sherratt7a666df2014-10-19 20:19:071505
1506 #[test]
1507 fn test_drop() {
1508 static mut drops: uint = 0;
1509 struct Elem;
1510 impl Drop for Elem {
1511 fn drop(&mut self) {
1512 unsafe { drops += 1; }
1513 }
1514 }
1515
1516 let mut ring = RingBuf::new();
1517 ring.push_back(Elem);
1518 ring.push_front(Elem);
1519 ring.push_back(Elem);
1520 ring.push_front(Elem);
1521 drop(ring);
1522
1523 assert_eq!(unsafe {drops}, 4);
1524 }
1525
1526 #[test]
1527 fn test_drop_with_pop() {
1528 static mut drops: uint = 0;
1529 struct Elem;
1530 impl Drop for Elem {
1531 fn drop(&mut self) {
1532 unsafe { drops += 1; }
1533 }
1534 }
1535
1536 let mut ring = RingBuf::new();
1537 ring.push_back(Elem);
1538 ring.push_front(Elem);
1539 ring.push_back(Elem);
1540 ring.push_front(Elem);
1541
1542 drop(ring.pop_back());
1543 drop(ring.pop_front());
1544 assert_eq!(unsafe {drops}, 2);
1545
1546 drop(ring);
1547 assert_eq!(unsafe {drops}, 4);
1548 }
1549
1550 #[test]
1551 fn test_drop_clear() {
1552 static mut drops: uint = 0;
1553 struct Elem;
1554 impl Drop for Elem {
1555 fn drop(&mut self) {
1556 unsafe { drops += 1; }
1557 }
1558 }
1559
1560 let mut ring = RingBuf::new();
1561 ring.push_back(Elem);
1562 ring.push_front(Elem);
1563 ring.push_back(Elem);
1564 ring.push_front(Elem);
1565 ring.clear();
1566 assert_eq!(unsafe {drops}, 4);
1567
1568 drop(ring);
1569 assert_eq!(unsafe {drops}, 4);
1570 }
1571
1572 #[test]
1573 fn test_reserve_grow() {
1574 // test growth path A
1575 // [T o o H] -> [T o o H . . . . ]
1576 let mut ring = RingBuf::with_capacity(4);
1577 for i in range(0i, 3) {
1578 ring.push_back(i);
1579 }
1580 ring.reserve(7);
1581 for i in range(0i, 3) {
1582 assert_eq!(ring.pop_front(), Some(i));
1583 }
1584
1585 // test growth path B
1586 // [H T o o] -> [. T o o H . . . ]
1587 let mut ring = RingBuf::with_capacity(4);
1588 for i in range(0i, 1) {
1589 ring.push_back(i);
1590 assert_eq!(ring.pop_front(), Some(i));
1591 }
1592 for i in range(0i, 3) {
1593 ring.push_back(i);
1594 }
1595 ring.reserve(7);
1596 for i in range(0i, 3) {
1597 assert_eq!(ring.pop_front(), Some(i));
1598 }
1599
1600 // test growth path C
1601 // [o o H T] -> [o o H . . . . T ]
1602 let mut ring = RingBuf::with_capacity(4);
1603 for i in range(0i, 3) {
1604 ring.push_back(i);
1605 assert_eq!(ring.pop_front(), Some(i));
1606 }
1607 for i in range(0i, 3) {
1608 ring.push_back(i);
1609 }
1610 ring.reserve(7);
1611 for i in range(0i, 3) {
1612 assert_eq!(ring.pop_front(), Some(i));
1613 }
1614 }
1615
1616 #[test]
1617 fn test_get() {
1618 let mut ring = RingBuf::new();
1619 ring.push_back(0i);
1620 assert_eq!(ring.get(0), Some(&0));
1621 assert_eq!(ring.get(1), None);
1622
1623 ring.push_back(1);
1624 assert_eq!(ring.get(0), Some(&0));
1625 assert_eq!(ring.get(1), Some(&1));
1626 assert_eq!(ring.get(2), None);
1627
1628 ring.push_back(2);
1629 assert_eq!(ring.get(0), Some(&0));
1630 assert_eq!(ring.get(1), Some(&1));
1631 assert_eq!(ring.get(2), Some(&2));
1632 assert_eq!(ring.get(3), None);
1633
1634 assert_eq!(ring.pop_front(), Some(0));
1635 assert_eq!(ring.get(0), Some(&1));
1636 assert_eq!(ring.get(1), Some(&2));
1637 assert_eq!(ring.get(2), None);
1638
1639 assert_eq!(ring.pop_front(), Some(1));
1640 assert_eq!(ring.get(0), Some(&2));
1641 assert_eq!(ring.get(1), None);
1642
1643 assert_eq!(ring.pop_front(), Some(2));
1644 assert_eq!(ring.get(0), None);
1645 assert_eq!(ring.get(1), None);
1646 }
1647
1648 #[test]
1649 fn test_get_mut() {
1650 let mut ring = RingBuf::new();
1651 for i in range(0i, 3) {
1652 ring.push_back(i);
1653 }
1654
1655 match ring.get_mut(1) {
1656 Some(x) => *x = -1,
1657 None => ()
1658 };
1659
1660 assert_eq!(ring.get_mut(0), Some(&mut 0));
1661 assert_eq!(ring.get_mut(1), Some(&mut -1));
1662 assert_eq!(ring.get_mut(2), Some(&mut 2));
1663 assert_eq!(ring.get_mut(3), None);
1664
1665 assert_eq!(ring.pop_front(), Some(0));
1666 assert_eq!(ring.get_mut(0), Some(&mut -1));
1667 assert_eq!(ring.get_mut(1), Some(&mut 2));
1668 assert_eq!(ring.get_mut(2), None);
1669 }
Michael Sullivanc854d6e2012-07-03 17:52:321670}