blob: 8f0b0d41b03d4836eeceeb3cc1e6b8711a710c57 [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?
37// FIXME(conventions): implement into_iter
38
39
P1startf2aa88c2014-08-04 10:48:3940/// `RingBuf` is a circular buffer that implements `Deque`.
blake2-ppc70523712013-07-10 13:27:1441pub struct RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:0742 // tail and head are pointers into the buffer. Tail always points
43 // to the first element that could be read, Head always points
44 // to where data should be written.
45 // If tail == head the buffer is empty. The length of the ringbuf
46 // is defined as the distance between the two.
47
48 tail: uint,
49 head: uint,
50 cap: uint,
51 ptr: *mut T
52}
53
54impl<T: Clone> Clone for RingBuf<T> {
55 fn clone(&self) -> RingBuf<T> {
56 self.iter().map(|t| t.clone()).collect()
57 }
58}
59
60#[unsafe_destructor]
61impl<T> Drop for RingBuf<T> {
62 fn drop(&mut self) {
63 self.clear();
64 unsafe {
65 if mem::size_of::<T>() != 0 {
66 heap::deallocate(self.ptr as *mut u8,
67 self.cap * mem::size_of::<T>(),
68 mem::min_align_of::<T>())
69 }
70 }
71 }
Marijn Haverbeke26610db2012-01-11 11:49:3372}
Roy Frostig9c818892010-07-21 01:03:0973
Tom Jakubowskid6a39412014-06-09 07:30:0474impl<T> Default for RingBuf<T> {
75 #[inline]
76 fn default() -> RingBuf<T> { RingBuf::new() }
77}
78
blake2-ppc70523712013-07-10 13:27:1479impl<T> RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:0780 /// Turn ptr into a slice
81 #[inline]
82 unsafe fn buffer_as_slice(&self) -> &[T] {
83 mem::transmute(RawSlice { data: self.ptr as *const T, len: self.cap })
84 }
85
86 /// Moves an element out of the buffer
87 #[inline]
88 unsafe fn buffer_read(&mut self, off: uint) -> T {
89 ptr::read(self.ptr.offset(off as int) as *const T)
90 }
91
92 /// Writes an element into the buffer, moving it.
93 #[inline]
94 unsafe fn buffer_write(&mut self, off: uint, t: T) {
95 ptr::write(self.ptr.offset(off as int), t);
96 }
97
98 /// Returns true iff the buffer is at capacity
99 #[inline]
100 fn is_full(&self) -> bool { self.cap - self.len() == 1 }
Colin Sherratt40191182014-11-12 01:22:07101
102 /// Returns the index in the underlying buffer for a given logical element index.
103 #[inline]
104 fn wrap_index(&self, idx: uint) -> uint { wrap_index(idx, self.cap) }
Colin Sherratt7a666df2014-10-19 20:19:07105}
106
107impl<T> RingBuf<T> {
P1startf2aa88c2014-08-04 10:48:39108 /// Creates an empty `RingBuf`.
Alexis Beingessnercf3b2e42014-11-06 17:24:47109 #[unstable = "matches collection reform specification, waiting for dust to settle"]
blake2-ppc70523712013-07-10 13:27:14110 pub fn new() -> RingBuf<T> {
111 RingBuf::with_capacity(INITIAL_CAPACITY)
112 }
113
P1startf2aa88c2014-08-04 10:48:39114 /// Creates an empty `RingBuf` with space for at least `n` elements.
Alexis Beingessnercf3b2e42014-11-06 17:24:47115 #[unstable = "matches collection reform specification, waiting for dust to settle"]
blake2-ppc70523712013-07-10 13:27:14116 pub fn with_capacity(n: uint) -> RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:07117 // +1 since the ringbuffer always leaves one space empty
Colin Sherratt6277e3b2014-11-14 09:21:44118 let cap = cmp::max(n + 1, MINIMUM_CAPACITY).next_power_of_two();
119 let size = cap.checked_mul(mem::size_of::<T>())
Colin Sherratt7a666df2014-10-19 20:19:07120 .expect("capacity overflow");
121
Colin Sherrattba24e332014-11-10 03:34:53122 let ptr = if mem::size_of::<T>() != 0 {
123 unsafe {
124 let ptr = heap::allocate(size, mem::min_align_of::<T>()) as *mut T;;
125 if ptr.is_null() { ::alloc::oom() }
126 ptr
127 }
128 } else {
129 heap::EMPTY as *mut T
130 };
131
Colin Sherratt7a666df2014-10-19 20:19:07132 RingBuf {
133 tail: 0,
134 head: 0,
135 cap: cap,
Colin Sherrattba24e332014-11-10 03:34:53136 ptr: ptr
Colin Sherratt7a666df2014-10-19 20:19:07137 }
blake2-ppc70523712013-07-10 13:27:14138 }
139
P1startf2aa88c2014-08-04 10:48:39140 /// Retrieves an element in the `RingBuf` by index.
blake2-ppc70523712013-07-10 13:27:14141 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47142 /// # Example
143 ///
144 /// ```rust
145 /// use std::collections::RingBuf;
146 ///
147 /// let mut buf = RingBuf::new();
148 /// buf.push_back(3i);
149 /// buf.push_back(4);
150 /// buf.push_back(5);
151 /// assert_eq!(buf.get(1).unwrap(), &4);
152 /// ```
153 #[unstable = "matches collection reform specification, waiting for dust to settle"]
154 pub fn get(&self, i: uint) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07155 if i < self.len() {
Colin Sherratt40191182014-11-12 01:22:07156 let idx = self.wrap_index(self.tail + i);
Colin Sherratt7a666df2014-10-19 20:19:07157 unsafe { Some(&*self.ptr.offset(idx as int)) }
158 } else {
159 None
Alexis Beingessnercf3b2e42014-11-06 17:24:47160 }
161 }
162
163 /// Retrieves an element in the `RingBuf` mutably by index.
nhamebe80972014-07-17 23:19:51164 ///
165 /// # Example
166 ///
167 /// ```rust
168 /// use std::collections::RingBuf;
169 ///
170 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47171 /// buf.push_back(3i);
172 /// buf.push_back(4);
173 /// buf.push_back(5);
174 /// match buf.get_mut(1) {
175 /// None => {}
176 /// Some(elem) => {
177 /// *elem = 7;
178 /// }
179 /// }
180 ///
P1startfd10d202014-08-02 06:39:39181 /// assert_eq!(buf[1], 7);
nhamebe80972014-07-17 23:19:51182 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47183 #[unstable = "matches collection reform specification, waiting for dust to settle"]
184 pub fn get_mut(&mut self, i: uint) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07185 if i < self.len() {
Colin Sherratt40191182014-11-12 01:22:07186 let idx = self.wrap_index(self.tail + i);
Colin Sherratt7a666df2014-10-19 20:19:07187 unsafe { Some(&mut *self.ptr.offset(idx as int)) }
188 } else {
189 None
Alexis Beingessnercf3b2e42014-11-06 17:24:47190 }
blake2-ppc70523712013-07-10 13:27:14191 }
192
P1startf2aa88c2014-08-04 10:48:39193 /// Swaps elements at indices `i` and `j`.
blake2-ppc57757a82013-09-26 07:19:26194 ///
195 /// `i` and `j` may be equal.
196 ///
P1startf2aa88c2014-08-04 10:48:39197 /// Fails if there is no element with either index.
nhamebe80972014-07-17 23:19:51198 ///
199 /// # Example
200 ///
201 /// ```rust
202 /// use std::collections::RingBuf;
203 ///
204 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47205 /// buf.push_back(3i);
206 /// buf.push_back(4);
207 /// buf.push_back(5);
nhamebe80972014-07-17 23:19:51208 /// buf.swap(0, 2);
P1startfd10d202014-08-02 06:39:39209 /// assert_eq!(buf[0], 5);
210 /// assert_eq!(buf[2], 3);
nhamebe80972014-07-17 23:19:51211 /// ```
blake2-ppc57757a82013-09-26 07:19:26212 pub fn swap(&mut self, i: uint, j: uint) {
213 assert!(i < self.len());
214 assert!(j < self.len());
Colin Sherratt40191182014-11-12 01:22:07215 let ri = self.wrap_index(self.tail + i);
216 let rj = self.wrap_index(self.tail + j);
Colin Sherratt7a666df2014-10-19 20:19:07217 unsafe {
218 ptr::swap(self.ptr.offset(ri as int), self.ptr.offset(rj as int))
219 }
blake2-ppc70523712013-07-10 13:27:14220 }
221
Alexis Beingessnercf3b2e42014-11-06 17:24:47222 /// Returns the number of elements the `RingBuf` can hold without
223 /// reallocating.
224 ///
225 /// # Example
226 ///
227 /// ```
228 /// use std::collections::RingBuf;
229 ///
230 /// let buf: RingBuf<int> = RingBuf::with_capacity(10);
Colin Sherratt7a666df2014-10-19 20:19:07231 /// assert!(buf.capacity() >= 10);
Alexis Beingessnercf3b2e42014-11-06 17:24:47232 /// ```
233 #[inline]
234 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Colin Sherratt7a666df2014-10-19 20:19:07235 pub fn capacity(&self) -> uint { self.cap - 1 }
Tim Chevalier77de84b2013-05-27 18:47:38236
Alexis Beingessnercf3b2e42014-11-06 17:24:47237 /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
238 /// given `RingBuf`. Does nothing if the capacity is already sufficient.
Tim Chevalier77de84b2013-05-27 18:47:38239 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47240 /// Note that the allocator may give the collection more space than it requests. Therefore
241 /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
242 /// insertions are expected.
243 ///
244 /// # Panics
245 ///
246 /// Panics if the new capacity overflows `uint`.
247 ///
248 /// # Example
249 ///
250 /// ```
251 /// use std::collections::RingBuf;
252 ///
253 /// let mut buf: RingBuf<int> = vec![1].into_iter().collect();
254 /// buf.reserve_exact(10);
255 /// assert!(buf.capacity() >= 11);
256 /// ```
257 #[unstable = "matches collection reform specification, waiting for dust to settle"]
258 pub fn reserve_exact(&mut self, additional: uint) {
Colin Sherratt7a666df2014-10-19 20:19:07259 self.reserve(additional);
Alexis Beingessnercf3b2e42014-11-06 17:24:47260 }
261
262 /// Reserves capacity for at least `additional` more elements to be inserted in the given
263 /// `Ringbuf`. The collection may reserve more space to avoid frequent reallocations.
264 ///
265 /// # Panics
266 ///
267 /// Panics if the new capacity overflows `uint`.
268 ///
269 /// # Example
270 ///
271 /// ```
272 /// use std::collections::RingBuf;
273 ///
274 /// let mut buf: RingBuf<int> = vec![1].into_iter().collect();
275 /// buf.reserve(10);
276 /// assert!(buf.capacity() >= 11);
277 /// ```
278 #[unstable = "matches collection reform specification, waiting for dust to settle"]
279 pub fn reserve(&mut self, additional: uint) {
Colin Sherratt7a666df2014-10-19 20:19:07280 let new_len = self.len() + additional;
281 assert!(new_len + 1 > self.len(), "capacity overflow");
282 if new_len > self.capacity() {
Colin Sherratt6277e3b2014-11-14 09:21:44283 let count = (new_len + 1).next_power_of_two();
Colin Sherratt7a666df2014-10-19 20:19:07284 assert!(count >= new_len + 1);
285
286 if mem::size_of::<T>() != 0 {
287 let old = self.cap * mem::size_of::<T>();
Colin Sherratt6277e3b2014-11-14 09:21:44288 let new = count.checked_mul(mem::size_of::<T>())
Colin Sherratt7a666df2014-10-19 20:19:07289 .expect("capacity overflow");
290 unsafe {
291 self.ptr = heap::reallocate(self.ptr as *mut u8,
292 old,
293 new,
294 mem::min_align_of::<T>()) as *mut T;
Colin Sherrattba24e332014-11-10 03:34:53295 if self.ptr.is_null() { ::alloc::oom() }
Colin Sherratt7a666df2014-10-19 20:19:07296 }
297 }
298
299 // Move the shortest contiguous section of the ring buffer
300 // T H
301 // [o o o o o o o . ]
302 // T H
303 // A [o o o o o o o . . . . . . . . . ]
304 // H T
305 // [o o . o o o o o ]
306 // T H
307 // B [. . . o o o o o o o . . . . . . ]
308 // H T
309 // [o o o o o . o o ]
310 // H T
311 // C [o o o o o . . . . . . . . . o o ]
312
313 let oldcap = self.cap;
314 self.cap = count;
315
316 if self.tail <= self.head { // A
317 // Nop
318 } else if self.head < oldcap - self.tail { // B
319 unsafe {
320 ptr::copy_nonoverlapping_memory(
321 self.ptr.offset(oldcap as int),
322 self.ptr as *const T,
323 self.head
324 );
325 }
326 self.head += oldcap;
Colin Sherratt4cae9ad2014-11-11 02:16:29327 debug_assert!(self.head > self.tail);
Colin Sherratt7a666df2014-10-19 20:19:07328 } else { // C
329 unsafe {
330 ptr::copy_nonoverlapping_memory(
331 self.ptr.offset((count - (oldcap - self.tail)) as int),
332 self.ptr.offset(self.tail as int) as *const T,
333 oldcap - self.tail
334 );
335 }
336 self.tail = count - (oldcap - self.tail);
Colin Sherratt4cae9ad2014-11-11 02:16:29337 debug_assert!(self.head < self.tail);
Colin Sherratt7a666df2014-10-19 20:19:07338 }
Colin Sherratt4cae9ad2014-11-11 02:16:29339 debug_assert!(self.head < self.cap);
340 debug_assert!(self.tail < self.cap);
Colin Sherratt40191182014-11-12 01:22:07341 debug_assert!(self.cap.count_ones() == 1);
Colin Sherratt7a666df2014-10-19 20:19:07342 }
Tim Chevalier77de84b2013-05-27 18:47:38343 }
Jed Estep4f7a7422013-06-25 19:08:47344
P1startf2aa88c2014-08-04 10:48:39345 /// Returns a front-to-back iterator.
nhamebe80972014-07-17 23:19:51346 ///
347 /// # Example
348 ///
349 /// ```rust
350 /// use std::collections::RingBuf;
351 ///
352 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47353 /// buf.push_back(5i);
354 /// buf.push_back(3);
355 /// buf.push_back(4);
Nick Cameron52ef4622014-08-06 09:59:40356 /// let b: &[_] = &[&5, &3, &4];
357 /// assert_eq!(buf.iter().collect::<Vec<&int>>().as_slice(), b);
nhamebe80972014-07-17 23:19:51358 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47359 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24360 pub fn iter(&self) -> Items<T> {
Colin Sherratt7a666df2014-10-19 20:19:07361 Items {
362 tail: self.tail,
363 head: self.head,
364 ring: unsafe { self.buffer_as_slice() }
365 }
blake2-ppc3385e792013-07-15 23:13:26366 }
367
P1startf2aa88c2014-08-04 10:48:39368 /// Returns a front-to-back iterator which returns mutable references.
nhamebe80972014-07-17 23:19:51369 ///
370 /// # Example
371 ///
372 /// ```rust
373 /// use std::collections::RingBuf;
374 ///
375 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47376 /// buf.push_back(5i);
377 /// buf.push_back(3);
378 /// buf.push_back(4);
Aaron Turonfc525ee2014-09-15 03:27:36379 /// for num in buf.iter_mut() {
nhamebe80972014-07-17 23:19:51380 /// *num = *num - 2;
381 /// }
Nick Cameron52ef4622014-08-06 09:59:40382 /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
Nick Cameron59976942014-09-24 11:41:09383 /// assert_eq!(buf.iter_mut().collect::<Vec<&mut int>>()[], b);
nhamebe80972014-07-17 23:19:51384 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47385 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Colin Sherratt7a666df2014-10-19 20:19:07386 pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {
387 MutItems {
388 tail: self.tail,
389 head: self.head,
390 cap: self.cap,
391 ptr: self.ptr,
392 marker: marker::ContravariantLifetime::<'a>,
393 marker2: marker::NoCopy
Niko Matsakisbc4164d2013-11-16 22:29:39394 }
Jed Estep4f7a7422013-06-25 19:08:47395 }
Alex Crichton21ac9852014-10-30 20:43:24396
397 /// Returns the number of elements in the `RingBuf`.
398 ///
399 /// # Example
400 ///
401 /// ```
402 /// use std::collections::RingBuf;
403 ///
404 /// let mut v = RingBuf::new();
405 /// assert_eq!(v.len(), 0);
Alexis Beingessnercf3b2e42014-11-06 17:24:47406 /// v.push_back(1i);
Alex Crichton21ac9852014-10-30 20:43:24407 /// assert_eq!(v.len(), 1);
408 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47409 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Colin Sherratt7a666df2014-10-19 20:19:07410 pub fn len(&self) -> uint { count(self.tail, self.head, self.cap) }
Alex Crichton21ac9852014-10-30 20:43:24411
412 /// Returns true if the buffer contains no elements
413 ///
414 /// # Example
415 ///
416 /// ```
417 /// use std::collections::RingBuf;
418 ///
419 /// let mut v = RingBuf::new();
420 /// assert!(v.is_empty());
421 /// v.push_front(1i);
422 /// assert!(!v.is_empty());
423 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47424 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24425 pub fn is_empty(&self) -> bool { self.len() == 0 }
426
427 /// Clears the buffer, removing all values.
428 ///
429 /// # Example
430 ///
431 /// ```
432 /// use std::collections::RingBuf;
433 ///
434 /// let mut v = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47435 /// v.push_back(1i);
Alex Crichton21ac9852014-10-30 20:43:24436 /// v.clear();
437 /// assert!(v.is_empty());
438 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47439 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24440 pub fn clear(&mut self) {
Colin Sherrattba24e332014-11-10 03:34:53441 while self.pop_front().is_some() {}
Colin Sherratt7a666df2014-10-19 20:19:07442 self.head = 0;
443 self.tail = 0;
Alex Crichton21ac9852014-10-30 20:43:24444 }
445
446 /// Provides a reference to the front element, or `None` if the sequence is
447 /// empty.
448 ///
449 /// # Example
450 ///
451 /// ```
452 /// use std::collections::RingBuf;
453 ///
454 /// let mut d = RingBuf::new();
455 /// assert_eq!(d.front(), None);
456 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47457 /// d.push_back(1i);
458 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24459 /// assert_eq!(d.front(), Some(&1i));
460 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47461 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24462 pub fn front(&self) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07463 if !self.is_empty() { Some(&self[0]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24464 }
465
466 /// Provides a mutable reference to the front element, or `None` if the
467 /// sequence is empty.
468 ///
469 /// # Example
470 ///
471 /// ```
472 /// use std::collections::RingBuf;
473 ///
474 /// let mut d = RingBuf::new();
475 /// assert_eq!(d.front_mut(), None);
476 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47477 /// d.push_back(1i);
478 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24479 /// match d.front_mut() {
480 /// Some(x) => *x = 9i,
481 /// None => (),
482 /// }
483 /// assert_eq!(d.front(), Some(&9i));
484 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47485 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24486 pub fn front_mut(&mut self) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07487 if !self.is_empty() { Some(&mut self[0]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24488 }
489
490 /// Provides a reference to the back element, or `None` if the sequence is
491 /// empty.
492 ///
493 /// # Example
494 ///
495 /// ```
496 /// use std::collections::RingBuf;
497 ///
498 /// let mut d = RingBuf::new();
499 /// assert_eq!(d.back(), None);
500 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47501 /// d.push_back(1i);
502 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24503 /// assert_eq!(d.back(), Some(&2i));
504 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47505 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24506 pub fn back(&self) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07507 if !self.is_empty() { Some(&self[self.len() - 1]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24508 }
509
510 /// Provides a mutable reference to the back element, or `None` if the
511 /// sequence is empty.
512 ///
513 /// # Example
514 ///
515 /// ```
516 /// use std::collections::RingBuf;
517 ///
518 /// let mut d = RingBuf::new();
519 /// assert_eq!(d.back(), None);
520 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47521 /// d.push_back(1i);
522 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24523 /// match d.back_mut() {
524 /// Some(x) => *x = 9i,
525 /// None => (),
526 /// }
527 /// assert_eq!(d.back(), Some(&9i));
528 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47529 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24530 pub fn back_mut(&mut self) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07531 let len = self.len();
532 if !self.is_empty() { Some(&mut self[len - 1]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24533 }
534
535 /// Removes the first element and returns it, or `None` if the sequence is
536 /// empty.
537 ///
538 /// # Example
539 ///
540 /// ```
541 /// use std::collections::RingBuf;
542 ///
543 /// let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47544 /// d.push_back(1i);
545 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24546 ///
547 /// assert_eq!(d.pop_front(), Some(1i));
548 /// assert_eq!(d.pop_front(), Some(2i));
549 /// assert_eq!(d.pop_front(), None);
550 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47551 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24552 pub fn pop_front(&mut self) -> Option<T> {
Colin Sherratt7a666df2014-10-19 20:19:07553 if self.is_empty() {
554 None
555 } else {
556 let tail = self.tail;
Colin Sherratt40191182014-11-12 01:22:07557 self.tail = self.wrap_index(self.tail + 1);
Colin Sherratt7a666df2014-10-19 20:19:07558 unsafe { Some(self.buffer_read(tail)) }
Alex Crichton21ac9852014-10-30 20:43:24559 }
Alex Crichton21ac9852014-10-30 20:43:24560 }
561
562 /// Inserts an element first in the sequence.
563 ///
564 /// # Example
565 ///
566 /// ```
567 /// use std::collections::RingBuf;
568 ///
569 /// let mut d = RingBuf::new();
570 /// d.push_front(1i);
571 /// d.push_front(2i);
572 /// assert_eq!(d.front(), Some(&2i));
573 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47574 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alex Crichton21ac9852014-10-30 20:43:24575 pub fn push_front(&mut self, t: T) {
Colin Sherratt4cae9ad2014-11-11 02:16:29576 if self.is_full() {
577 self.reserve(1);
578 debug_assert!(!self.is_full());
579 }
Colin Sherratt7a666df2014-10-19 20:19:07580
Colin Sherratt40191182014-11-12 01:22:07581 self.tail = self.wrap_index(self.tail - 1);
Colin Sherratt7a666df2014-10-19 20:19:07582 let tail = self.tail;
583 unsafe { self.buffer_write(tail, t); }
Alex Crichton21ac9852014-10-30 20:43:24584 }
585
Alexis Beingessnercf3b2e42014-11-06 17:24:47586 /// Deprecated: Renamed to `push_back`.
587 #[deprecated = "Renamed to `push_back`"]
588 pub fn push(&mut self, t: T) {
589 self.push_back(t)
590 }
591
Alex Crichton21ac9852014-10-30 20:43:24592 /// Appends an element to the back of a buffer
593 ///
594 /// # Example
595 ///
596 /// ```rust
597 /// use std::collections::RingBuf;
598 ///
599 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47600 /// buf.push_back(1i);
601 /// buf.push_back(3);
Alex Crichton21ac9852014-10-30 20:43:24602 /// assert_eq!(3, *buf.back().unwrap());
603 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47604 #[unstable = "matches collection reform specification, waiting for dust to settle"]
605 pub fn push_back(&mut self, t: T) {
Colin Sherratt4cae9ad2014-11-11 02:16:29606 if self.is_full() {
607 self.reserve(1);
608 debug_assert!(!self.is_full());
609 }
Colin Sherratt7a666df2014-10-19 20:19:07610
611 let head = self.head;
Colin Sherratt40191182014-11-12 01:22:07612 self.head = self.wrap_index(self.head + 1);
Colin Sherratt7a666df2014-10-19 20:19:07613 unsafe { self.buffer_write(head, t) }
Alex Crichton21ac9852014-10-30 20:43:24614 }
615
Alexis Beingessnercf3b2e42014-11-06 17:24:47616 /// Deprecated: Renamed to `pop_back`.
617 #[deprecated = "Renamed to `pop_back`"]
618 pub fn pop(&mut self) -> Option<T> {
619 self.pop_back()
620 }
621
Alex Crichton21ac9852014-10-30 20:43:24622 /// Removes the last element from a buffer and returns it, or `None` if
623 /// it is empty.
624 ///
625 /// # Example
626 ///
627 /// ```rust
628 /// use std::collections::RingBuf;
629 ///
630 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47631 /// assert_eq!(buf.pop_back(), None);
632 /// buf.push_back(1i);
633 /// buf.push_back(3);
634 /// assert_eq!(buf.pop_back(), Some(3));
Alex Crichton21ac9852014-10-30 20:43:24635 /// ```
Alexis Beingessnercf3b2e42014-11-06 17:24:47636 #[unstable = "matches collection reform specification, waiting for dust to settle"]
637 pub fn pop_back(&mut self) -> Option<T> {
Colin Sherratt7a666df2014-10-19 20:19:07638 if self.is_empty() {
Alex Crichton21ac9852014-10-30 20:43:24639 None
Colin Sherratt7a666df2014-10-19 20:19:07640 } else {
Colin Sherratt40191182014-11-12 01:22:07641 self.head = self.wrap_index(self.head - 1);
Colin Sherratt7a666df2014-10-19 20:19:07642 let head = self.head;
643 unsafe { Some(self.buffer_read(head)) }
Alex Crichton21ac9852014-10-30 20:43:24644 }
645 }
Jed Estep4f7a7422013-06-25 19:08:47646}
647
Colin Sherratt7a666df2014-10-19 20:19:07648/// Returns the index in the underlying buffer for a given logical element index.
649#[inline]
650fn wrap_index(index: uint, size: uint) -> uint {
651 // size is always a power of 2
Colin Sherratt40191182014-11-12 01:22:07652 index & (size - 1)
Colin Sherratt7a666df2014-10-19 20:19:07653}
654
655/// Calculate the number of elements left to be read in the buffer
656#[inline]
657fn count(tail: uint, head: uint, size: uint) -> uint {
658 // size is always a power of 2
659 (head - tail) & (size - 1)
660}
661
Niko Matsakis1b487a82014-08-28 01:46:52662/// `RingBuf` iterator.
Niko Matsakis1b487a82014-08-28 01:46:52663pub struct Items<'a, T:'a> {
Colin Sherratt7a666df2014-10-19 20:19:07664 ring: &'a [T],
665 tail: uint,
666 head: uint
Niko Matsakis1b487a82014-08-28 01:46:52667}
668
Palmer Cox3fd8c8b2014-01-15 03:32:24669impl<'a, T> Iterator<&'a T> for Items<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:39670 #[inline]
Erik Price5731ca32013-12-10 07:16:18671 fn next(&mut self) -> Option<&'a T> {
Colin Sherratt7a666df2014-10-19 20:19:07672 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:39673 return None;
674 }
Colin Sherratt7a666df2014-10-19 20:19:07675 let tail = self.tail;
676 self.tail = wrap_index(self.tail + 1, self.ring.len());
677 unsafe { Some(self.ring.unsafe_get(tail)) }
Niko Matsakisbc4164d2013-11-16 22:29:39678 }
679
680 #[inline]
681 fn size_hint(&self) -> (uint, Option<uint>) {
Colin Sherratt7a666df2014-10-19 20:19:07682 let len = count(self.tail, self.head, self.ring.len());
Niko Matsakisbc4164d2013-11-16 22:29:39683 (len, Some(len))
684 }
685}
686
Palmer Cox3fd8c8b2014-01-15 03:32:24687impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:39688 #[inline]
Erik Price5731ca32013-12-10 07:16:18689 fn next_back(&mut self) -> Option<&'a T> {
Colin Sherratt7a666df2014-10-19 20:19:07690 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:39691 return None;
692 }
Colin Sherratt7a666df2014-10-19 20:19:07693 self.head = wrap_index(self.head - 1, self.ring.len());
694 unsafe { Some(self.ring.unsafe_get(self.head)) }
Niko Matsakisbc4164d2013-11-16 22:29:39695 }
696}
Jed Estep35314c92013-06-26 15:38:29697
Aaron Turonb299c2b2014-11-06 17:32:37698impl<'a, T> ExactSizeIterator<&'a T> for Items<'a, T> {}
blake2-ppc7c369ee72013-09-01 16:20:24699
Palmer Cox3fd8c8b2014-01-15 03:32:24700impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
blake2-ppcf6862132013-07-29 18:16:26701 #[inline]
Colin Sherratt7a666df2014-10-19 20:19:07702 fn indexable(&self) -> uint {
703 let (len, _) = self.size_hint();
704 len
705 }
blake2-ppcf6862132013-07-29 18:16:26706
707 #[inline]
Alex Crichtonf4083a22014-04-22 05:15:42708 fn idx(&mut self, j: uint) -> Option<&'a T> {
blake2-ppcf6862132013-07-29 18:16:26709 if j >= self.indexable() {
710 None
711 } else {
Colin Sherratt7a666df2014-10-19 20:19:07712 let idx = wrap_index(self.tail + j, self.ring.len());
713 unsafe { Some(self.ring.unsafe_get(idx)) }
blake2-ppcf6862132013-07-29 18:16:26714 }
715 }
716}
717
Colin Sherratt7a666df2014-10-19 20:19:07718// FIXME This was implemented differently from Items because of a problem
719// with returning the mutable reference. I couldn't find a way to
720// make the lifetime checker happy so, but there should be a way.
Niko Matsakis1b487a82014-08-28 01:46:52721/// `RingBuf` mutable iterator.
Niko Matsakis1b487a82014-08-28 01:46:52722pub struct MutItems<'a, T:'a> {
Colin Sherratt7a666df2014-10-19 20:19:07723 ptr: *mut T,
724 tail: uint,
725 head: uint,
726 cap: uint,
727 marker: marker::ContravariantLifetime<'a>,
728 marker2: marker::NoCopy
Niko Matsakis1b487a82014-08-28 01:46:52729}
730
Palmer Cox3fd8c8b2014-01-15 03:32:24731impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:39732 #[inline]
Erik Price5731ca32013-12-10 07:16:18733 fn next(&mut self) -> Option<&'a mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07734 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:39735 return None;
736 }
Colin Sherratt7a666df2014-10-19 20:19:07737 let tail = self.tail;
738 self.tail = wrap_index(self.tail + 1, self.cap);
739 if mem::size_of::<T>() != 0 {
740 unsafe { Some(&mut *self.ptr.offset(tail as int)) }
741 } else {
Colin Sherrattba24e332014-11-10 03:34:53742 // use a non-zero pointer
Colin Sherratt7a666df2014-10-19 20:19:07743 Some(unsafe { mem::transmute(1u) })
Alex Crichton9d5d97b2014-10-15 06:05:01744 }
Niko Matsakisbc4164d2013-11-16 22:29:39745 }
746
747 #[inline]
748 fn size_hint(&self) -> (uint, Option<uint>) {
Colin Sherratt7a666df2014-10-19 20:19:07749 let len = count(self.tail, self.head, self.cap);
750 (len, Some(len))
Niko Matsakisbc4164d2013-11-16 22:29:39751 }
752}
753
Palmer Cox3fd8c8b2014-01-15 03:32:24754impl<'a, T> DoubleEndedIterator<&'a mut T> for MutItems<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:39755 #[inline]
Erik Price5731ca32013-12-10 07:16:18756 fn next_back(&mut self) -> Option<&'a mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07757 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:39758 return None;
759 }
Colin Sherratt7a666df2014-10-19 20:19:07760 self.head = wrap_index(self.head - 1, self.cap);
761 unsafe { Some(&mut *self.ptr.offset(self.head as int)) }
Niko Matsakisbc4164d2013-11-16 22:29:39762 }
763}
Daniel Micayb47e1e92013-02-16 22:55:55764
Aaron Turonb299c2b2014-11-06 17:32:37765impl<'a, T> ExactSizeIterator<&'a mut T> for MutItems<'a, T> {}
blake2-ppc7c369ee72013-09-01 16:20:24766
Alex Crichton748bc3c2014-05-30 00:45:07767impl<A: PartialEq> PartialEq for RingBuf<A> {
blake2-ppc70523712013-07-10 13:27:14768 fn eq(&self, other: &RingBuf<A>) -> bool {
Colin Sherratt7a666df2014-10-19 20:19:07769 self.len() == other.len() &&
blake2-ppc10c76982013-07-06 13:27:32770 self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
771 }
blake2-ppc70523712013-07-10 13:27:14772 fn ne(&self, other: &RingBuf<A>) -> bool {
blake2-ppc10c76982013-07-06 13:27:32773 !self.eq(other)
774 }
775}
776
nham25acfde2014-08-01 20:05:03777impl<A: Eq> Eq for RingBuf<A> {}
778
nham63615772014-07-27 03:18:56779impl<A: PartialOrd> PartialOrd for RingBuf<A> {
780 fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
781 iter::order::partial_cmp(self.iter(), other.iter())
782 }
783}
784
nham3737c532014-08-01 20:22:48785impl<A: Ord> Ord for RingBuf<A> {
786 #[inline]
787 fn cmp(&self, other: &RingBuf<A>) -> Ordering {
788 iter::order::cmp(self.iter(), other.iter())
789 }
790}
791
nham1cfa6562014-07-27 02:33:47792impl<S: Writer, A: Hash<S>> Hash<S> for RingBuf<A> {
793 fn hash(&self, state: &mut S) {
nham9fa44242014-07-27 16:37:32794 self.len().hash(state);
nham1cfa6562014-07-27 02:33:47795 for elt in self.iter() {
796 elt.hash(state);
797 }
798 }
799}
800
P1startfd10d202014-08-02 06:39:39801impl<A> Index<uint, A> for RingBuf<A> {
802 #[inline]
803 fn index<'a>(&'a self, i: &uint) -> &'a A {
Colin Sherratt7a666df2014-10-19 20:19:07804 self.get(*i).expect("Out of bounds access")
P1startfd10d202014-08-02 06:39:39805 }
806}
807
Alex Crichton1d356622014-10-23 15:42:21808impl<A> IndexMut<uint, A> for RingBuf<A> {
P1startfd10d202014-08-02 06:39:39809 #[inline]
Alex Crichton1d356622014-10-23 15:42:21810 fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut A {
Colin Sherratt7a666df2014-10-19 20:19:07811 self.get_mut(*i).expect("Out of bounds access")
P1startfd10d202014-08-02 06:39:39812 }
Alex Crichton1d356622014-10-23 15:42:21813}
P1startfd10d202014-08-02 06:39:39814
Huon Wilson53487a02013-08-13 13:08:14815impl<A> FromIterator<A> for RingBuf<A> {
Brian Andersonee052192014-03-31 04:45:55816 fn from_iter<T: Iterator<A>>(iterator: T) -> RingBuf<A> {
blake2-ppcf8ae5262013-07-30 00:06:49817 let (lower, _) = iterator.size_hint();
818 let mut deq = RingBuf::with_capacity(lower);
819 deq.extend(iterator);
blake2-ppc08dc72f2013-07-06 03:42:45820 deq
821 }
822}
823
gamazeps16c8cd92014-11-08 00:39:39824impl<A> Extend<A> for RingBuf<A> {
Marvin Löbel6200e762014-03-20 13:12:56825 fn extend<T: Iterator<A>>(&mut self, mut iterator: T) {
826 for elt in iterator {
Alexis Beingessnercf3b2e42014-11-06 17:24:47827 self.push_back(elt);
blake2-ppcf8ae5262013-07-30 00:06:49828 }
829 }
830}
831
Alex Crichton6a585372014-05-30 01:50:12832impl<T: fmt::Show> fmt::Show for RingBuf<T> {
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:04833 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
834 try!(write!(f, "["));
835
836 for (i, e) in self.iter().enumerate() {
837 if i != 0 { try!(write!(f, ", ")); }
838 try!(write!(f, "{}", *e));
839 }
840
841 write!(f, "]")
842 }
843}
844
Brian Anderson6e27b272012-01-18 03:05:07845#[cfg(test)]
846mod tests {
Steven Fackler3dcd2152014-11-06 08:05:53847 use self::Taggy::*;
848 use self::Taggypar::*;
Alex Crichton02882fb2014-02-28 09:23:06849 use std::fmt::Show;
Alex Crichton760b93a2014-05-30 02:03:06850 use std::prelude::*;
nham1cfa6562014-07-27 02:33:47851 use std::hash;
Alex Crichton760b93a2014-05-30 02:03:06852 use test::Bencher;
853 use test;
854
Alex Crichtonf47e4b22014-01-07 06:33:50855 use super::RingBuf;
Alex Crichton760b93a2014-05-30 02:03:06856 use vec::Vec;
Patrick Waltonfa5ee932012-12-28 02:24:18857
Brian Anderson6e27b272012-01-18 03:05:07858 #[test]
Victor Berger52ea83d2014-09-22 17:30:06859 #[allow(deprecated)]
Brian Anderson6e27b272012-01-18 03:05:07860 fn test_simple() {
blake2-ppc70523712013-07-10 13:27:14861 let mut d = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:45862 assert_eq!(d.len(), 0u);
Niko Matsakis9e3d0b02014-04-21 21:58:52863 d.push_front(17i);
864 d.push_front(42i);
Alexis Beingessnercf3b2e42014-11-06 17:24:47865 d.push_back(137);
Corey Richardsoncc57ca02013-05-19 02:02:45866 assert_eq!(d.len(), 3u);
Alexis Beingessnercf3b2e42014-11-06 17:24:47867 d.push_back(137);
Corey Richardsoncc57ca02013-05-19 02:02:45868 assert_eq!(d.len(), 4u);
Luqman Aden3ef9aa02014-10-15 07:22:55869 debug!("{}", d.front());
blake2-ppc70523712013-07-10 13:27:14870 assert_eq!(*d.front().unwrap(), 42);
Luqman Aden3ef9aa02014-10-15 07:22:55871 debug!("{}", d.back());
blake2-ppc70523712013-07-10 13:27:14872 assert_eq!(*d.back().unwrap(), 137);
873 let mut i = d.pop_front();
Luqman Aden3ef9aa02014-10-15 07:22:55874 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:14875 assert_eq!(i, Some(42));
Alexis Beingessnercf3b2e42014-11-06 17:24:47876 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:55877 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:14878 assert_eq!(i, Some(137));
Alexis Beingessnercf3b2e42014-11-06 17:24:47879 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:55880 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:14881 assert_eq!(i, Some(137));
Alexis Beingessnercf3b2e42014-11-06 17:24:47882 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:55883 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:14884 assert_eq!(i, Some(17));
Corey Richardsoncc57ca02013-05-19 02:02:45885 assert_eq!(d.len(), 0u);
Alexis Beingessnercf3b2e42014-11-06 17:24:47886 d.push_back(3);
Corey Richardsoncc57ca02013-05-19 02:02:45887 assert_eq!(d.len(), 1u);
blake2-ppc70523712013-07-10 13:27:14888 d.push_front(2);
Corey Richardsoncc57ca02013-05-19 02:02:45889 assert_eq!(d.len(), 2u);
Alexis Beingessnercf3b2e42014-11-06 17:24:47890 d.push_back(4);
Corey Richardsoncc57ca02013-05-19 02:02:45891 assert_eq!(d.len(), 3u);
blake2-ppc70523712013-07-10 13:27:14892 d.push_front(1);
Corey Richardsoncc57ca02013-05-19 02:02:45893 assert_eq!(d.len(), 4u);
Alex Crichton9d5d97b2014-10-15 06:05:01894 debug!("{}", d[0]);
895 debug!("{}", d[1]);
896 debug!("{}", d[2]);
897 debug!("{}", d[3]);
898 assert_eq!(d[0], 1);
899 assert_eq!(d[1], 2);
900 assert_eq!(d[2], 3);
901 assert_eq!(d[3], 4);
Brian Anderson6e27b272012-01-18 03:05:07902 }
903
Felix S. Klock IIa636f512013-05-01 23:32:37904 #[cfg(test)]
Alex Crichton748bc3c2014-05-30 00:45:07905 fn test_parameterized<T:Clone + PartialEq + Show>(a: T, b: T, c: T, d: T) {
Patrick Waltondc4bf172013-07-13 04:05:59906 let mut deq = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:45907 assert_eq!(deq.len(), 0);
Patrick Waltondc4bf172013-07-13 04:05:59908 deq.push_front(a.clone());
909 deq.push_front(b.clone());
Alexis Beingessnercf3b2e42014-11-06 17:24:47910 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45911 assert_eq!(deq.len(), 3);
Alexis Beingessnercf3b2e42014-11-06 17:24:47912 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45913 assert_eq!(deq.len(), 4);
Marvin Löbel0ac7a212013-08-03 23:59:24914 assert_eq!((*deq.front().unwrap()).clone(), b.clone());
915 assert_eq!((*deq.back().unwrap()).clone(), d.clone());
916 assert_eq!(deq.pop_front().unwrap(), b.clone());
Alexis Beingessnercf3b2e42014-11-06 17:24:47917 assert_eq!(deq.pop_back().unwrap(), d.clone());
918 assert_eq!(deq.pop_back().unwrap(), c.clone());
919 assert_eq!(deq.pop_back().unwrap(), a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45920 assert_eq!(deq.len(), 0);
Alexis Beingessnercf3b2e42014-11-06 17:24:47921 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45922 assert_eq!(deq.len(), 1);
Patrick Waltondc4bf172013-07-13 04:05:59923 deq.push_front(b.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45924 assert_eq!(deq.len(), 2);
Alexis Beingessnercf3b2e42014-11-06 17:24:47925 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45926 assert_eq!(deq.len(), 3);
Patrick Waltondc4bf172013-07-13 04:05:59927 deq.push_front(a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:45928 assert_eq!(deq.len(), 4);
NODA, Kaif27ad3d2014-10-05 10:11:17929 assert_eq!(deq[0].clone(), a.clone());
930 assert_eq!(deq[1].clone(), b.clone());
931 assert_eq!(deq[2].clone(), c.clone());
932 assert_eq!(deq[3].clone(), d.clone());
Brian Anderson6e27b272012-01-18 03:05:07933 }
934
blake2-ppc81933ed2013-07-06 03:42:45935 #[test]
blake2-ppc70523712013-07-10 13:27:14936 fn test_push_front_grow() {
937 let mut deq = RingBuf::new();
Daniel Micay100894552013-08-03 16:45:23938 for i in range(0u, 66) {
blake2-ppc70523712013-07-10 13:27:14939 deq.push_front(i);
blake2-ppc81933ed2013-07-06 03:42:45940 }
941 assert_eq!(deq.len(), 66);
942
Daniel Micay100894552013-08-03 16:45:23943 for i in range(0u, 66) {
NODA, Kaif27ad3d2014-10-05 10:11:17944 assert_eq!(deq[i], 65 - i);
blake2-ppc81933ed2013-07-06 03:42:45945 }
946
blake2-ppc70523712013-07-10 13:27:14947 let mut deq = RingBuf::new();
Daniel Micay100894552013-08-03 16:45:23948 for i in range(0u, 66) {
Alexis Beingessnercf3b2e42014-11-06 17:24:47949 deq.push_back(i);
blake2-ppc81933ed2013-07-06 03:42:45950 }
951
Daniel Micay100894552013-08-03 16:45:23952 for i in range(0u, 66) {
NODA, Kaif27ad3d2014-10-05 10:11:17953 assert_eq!(deq[i], i);
blake2-ppc81933ed2013-07-06 03:42:45954 }
955 }
956
P1startfd10d202014-08-02 06:39:39957 #[test]
958 fn test_index() {
959 let mut deq = RingBuf::new();
960 for i in range(1u, 4) {
961 deq.push_front(i);
962 }
963 assert_eq!(deq[1], 2);
964 }
965
966 #[test]
967 #[should_fail]
968 fn test_index_out_of_bounds() {
969 let mut deq = RingBuf::new();
970 for i in range(1u, 4) {
971 deq.push_front(i);
972 }
973 deq[3];
974 }
975
blake2-ppc81933ed2013-07-06 03:42:45976 #[bench]
Liigo Zhuang408f4842014-04-01 01:16:35977 fn bench_new(b: &mut test::Bencher) {
Patrick Walton38efa172013-11-22 03:20:48978 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:52979 let ring: RingBuf<u64> = RingBuf::new();
980 test::black_box(ring);
Patrick Walton38efa172013-11-22 03:20:48981 })
blake2-ppc81933ed2013-07-06 03:42:45982 }
983
984 #[bench]
Colin Sherratt7a666df2014-10-19 20:19:07985 fn bench_push_back_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:52986 let mut deq = RingBuf::with_capacity(101);
Patrick Walton38efa172013-11-22 03:20:48987 b.iter(|| {
Colin Sherratt7a666df2014-10-19 20:19:07988 for i in range(0i, 100) {
989 deq.push_back(i);
990 }
Colin Sherratt5e549d82014-11-11 02:57:52991 deq.head = 0;
992 deq.tail = 0;
Patrick Walton38efa172013-11-22 03:20:48993 })
blake2-ppc81933ed2013-07-06 03:42:45994 }
995
996 #[bench]
Colin Sherratt7a666df2014-10-19 20:19:07997 fn bench_push_front_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:52998 let mut deq = RingBuf::with_capacity(101);
Patrick Walton38efa172013-11-22 03:20:48999 b.iter(|| {
Colin Sherratt7a666df2014-10-19 20:19:071000 for i in range(0i, 100) {
1001 deq.push_front(i);
1002 }
Colin Sherratt5e549d82014-11-11 02:57:521003 deq.head = 0;
1004 deq.tail = 0;
Patrick Walton38efa172013-11-22 03:20:481005 })
blake2-ppc81933ed2013-07-06 03:42:451006 }
1007
1008 #[bench]
Colin Sherratt5e549d82014-11-11 02:57:521009 fn bench_pop_back_100(b: &mut test::Bencher) {
1010 let mut deq: RingBuf<int> = RingBuf::with_capacity(101);
Colin Sherratt7a666df2014-10-19 20:19:071011
Patrick Walton38efa172013-11-22 03:20:481012 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521013 deq.head = 100;
1014 deq.tail = 0;
1015 while !deq.is_empty() {
1016 test::black_box(deq.pop_back());
Colin Sherratt7a666df2014-10-19 20:19:071017 }
Colin Sherratt7a666df2014-10-19 20:19:071018 })
1019 }
1020
1021 #[bench]
1022 fn bench_pop_front_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521023 let mut deq: RingBuf<int> = RingBuf::with_capacity(101);
Colin Sherratt7a666df2014-10-19 20:19:071024
1025 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521026 deq.head = 100;
1027 deq.tail = 0;
1028 while !deq.is_empty() {
1029 test::black_box(deq.pop_front());
Colin Sherratt7a666df2014-10-19 20:19:071030 }
Colin Sherratt7a666df2014-10-19 20:19:071031 })
1032 }
1033
1034 #[bench]
1035 fn bench_grow_1025(b: &mut test::Bencher) {
1036 b.iter(|| {
1037 let mut deq = RingBuf::new();
1038 for i in range(0i, 1025) {
1039 deq.push_front(i);
Brendan Zabarauskas729060d2014-01-30 00:20:341040 }
Colin Sherratt5e549d82014-11-11 02:57:521041 test::black_box(deq);
Patrick Walton38efa172013-11-22 03:20:481042 })
blake2-ppc81933ed2013-07-06 03:42:451043 }
1044
Colin Sherratt7a666df2014-10-19 20:19:071045 #[bench]
1046 fn bench_iter_1000(b: &mut test::Bencher) {
1047 let ring: RingBuf<int> = range(0i, 1000).collect();
1048
1049 b.iter(|| {
1050 let mut sum = 0;
1051 for &i in ring.iter() {
1052 sum += i;
1053 }
Colin Sherratt5e549d82014-11-11 02:57:521054 test::black_box(sum);
Colin Sherratt7a666df2014-10-19 20:19:071055 })
1056 }
1057
1058 #[bench]
1059 fn bench_mut_iter_1000(b: &mut test::Bencher) {
1060 let mut ring: RingBuf<int> = range(0i, 1000).collect();
1061
1062 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521063 let mut sum = 0;
Colin Sherratt7a666df2014-10-19 20:19:071064 for i in ring.iter_mut() {
Colin Sherratt5e549d82014-11-11 02:57:521065 sum += *i;
Colin Sherratt7a666df2014-10-19 20:19:071066 }
Colin Sherratt5e549d82014-11-11 02:57:521067 test::black_box(sum);
Colin Sherratt7a666df2014-10-19 20:19:071068 })
1069 }
1070
1071
Alex Crichton748bc3c2014-05-30 00:45:071072 #[deriving(Clone, PartialEq, Show)]
Patrick Walton99b33f72013-07-02 19:47:321073 enum Taggy {
1074 One(int),
1075 Two(int, int),
1076 Three(int, int, int),
Brian Anderson6e27b272012-01-18 03:05:071077 }
1078
Alex Crichton748bc3c2014-05-30 00:45:071079 #[deriving(Clone, PartialEq, Show)]
Patrick Walton99b33f72013-07-02 19:47:321080 enum Taggypar<T> {
1081 Onepar(int),
1082 Twopar(int, int),
1083 Threepar(int, int, int),
1084 }
1085
Alex Crichton748bc3c2014-05-30 00:45:071086 #[deriving(Clone, PartialEq, Show)]
Erick Tryzelaare84576b2013-01-22 16:44:241087 struct RecCy {
1088 x: int,
1089 y: int,
Patrick Waltoneb4d39e2013-01-26 00:57:391090 t: Taggy
Patrick Walton9117dcb2012-09-20 01:00:261091 }
Kevin Cantuc43426e2012-09-13 05:09:551092
1093 #[test]
1094 fn test_param_int() {
1095 test_parameterized::<int>(5, 72, 64, 175);
1096 }
1097
1098 #[test]
Kevin Cantuc43426e2012-09-13 05:09:551099 fn test_param_taggy() {
Corey Richardsonf8ae9b02013-06-26 22:14:351100 test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:551101 }
1102
1103 #[test]
1104 fn test_param_taggypar() {
1105 test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
Ben Striegela605fd02012-08-11 14:08:421106 Twopar::<int>(1, 2),
1107 Threepar::<int>(1, 2, 3),
1108 Twopar::<int>(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:551109 }
Brian Anderson6e27b272012-01-18 03:05:071110
Kevin Cantuc43426e2012-09-13 05:09:551111 #[test]
1112 fn test_param_reccy() {
Erick Tryzelaare84576b2013-01-22 16:44:241113 let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
1114 let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
1115 let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
1116 let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
Kevin Cantuc43426e2012-09-13 05:09:551117 test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
Brian Anderson6e27b272012-01-18 03:05:071118 }
Erick Tryzelaar909d8f02013-03-30 01:02:441119
1120 #[test]
blake2-ppc0ff5c172013-07-06 03:42:451121 fn test_with_capacity() {
blake2-ppc70523712013-07-10 13:27:141122 let mut d = RingBuf::with_capacity(0);
Alexis Beingessnercf3b2e42014-11-06 17:24:471123 d.push_back(1i);
blake2-ppc0ff5c172013-07-06 03:42:451124 assert_eq!(d.len(), 1);
blake2-ppc70523712013-07-10 13:27:141125 let mut d = RingBuf::with_capacity(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471126 d.push_back(1i);
blake2-ppc0ff5c172013-07-06 03:42:451127 assert_eq!(d.len(), 1);
1128 }
1129
1130 #[test]
Kevin Butler64896d62014-08-07 01:11:131131 fn test_with_capacity_non_power_two() {
1132 let mut d3 = RingBuf::with_capacity(3);
Alexis Beingessnercf3b2e42014-11-06 17:24:471133 d3.push_back(1i);
Kevin Butler64896d62014-08-07 01:11:131134
1135 // X = None, | = lo
1136 // [|1, X, X]
1137 assert_eq!(d3.pop_front(), Some(1));
1138 // [X, |X, X]
1139 assert_eq!(d3.front(), None);
1140
1141 // [X, |3, X]
Alexis Beingessnercf3b2e42014-11-06 17:24:471142 d3.push_back(3);
Kevin Butler64896d62014-08-07 01:11:131143 // [X, |3, 6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471144 d3.push_back(6);
Kevin Butler64896d62014-08-07 01:11:131145 // [X, X, |6]
1146 assert_eq!(d3.pop_front(), Some(3));
1147
1148 // Pushing the lo past half way point to trigger
1149 // the 'B' scenario for growth
1150 // [9, X, |6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471151 d3.push_back(9);
Kevin Butler64896d62014-08-07 01:11:131152 // [9, 12, |6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471153 d3.push_back(12);
Kevin Butler64896d62014-08-07 01:11:131154
Alexis Beingessnercf3b2e42014-11-06 17:24:471155 d3.push_back(15);
Kevin Butler64896d62014-08-07 01:11:131156 // There used to be a bug here about how the
1157 // RingBuf made growth assumptions about the
1158 // underlying Vec which didn't hold and lead
1159 // to corruption.
1160 // (Vec grows to next power of two)
1161 //good- [9, 12, 15, X, X, X, X, |6]
1162 //bug- [15, 12, X, X, X, |6, X, X]
1163 assert_eq!(d3.pop_front(), Some(6));
1164
1165 // Which leads us to the following state which
1166 // would be a failure case.
1167 //bug- [15, 12, X, X, X, X, |X, X]
1168 assert_eq!(d3.front(), Some(&9));
1169 }
1170
1171 #[test]
David Manescu65f35782014-01-31 13:03:201172 fn test_reserve_exact() {
blake2-ppc70523712013-07-10 13:27:141173 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471174 d.push_back(0u64);
David Manescu65f35782014-01-31 13:03:201175 d.reserve_exact(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471176 assert!(d.capacity() >= 51);
blake2-ppc70523712013-07-10 13:27:141177 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471178 d.push_back(0u32);
David Manescu65f35782014-01-31 13:03:201179 d.reserve_exact(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471180 assert!(d.capacity() >= 51);
Tim Chevalier77de84b2013-05-27 18:47:381181 }
1182
1183 #[test]
David Manescu65f35782014-01-31 13:03:201184 fn test_reserve() {
blake2-ppc70523712013-07-10 13:27:141185 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471186 d.push_back(0u64);
David Manescu65f35782014-01-31 13:03:201187 d.reserve(50);
Colin Sherratt7a666df2014-10-19 20:19:071188 assert!(d.capacity() >= 51);
blake2-ppc70523712013-07-10 13:27:141189 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471190 d.push_back(0u32);
David Manescu65f35782014-01-31 13:03:201191 d.reserve(50);
Colin Sherratt7a666df2014-10-19 20:19:071192 assert!(d.capacity() >= 51);
Tim Chevalier77de84b2013-05-27 18:47:381193 }
1194
Jed Estep096fb792013-06-26 14:04:441195 #[test]
blake2-ppc57757a82013-09-26 07:19:261196 fn test_swap() {
Niko Matsakis9e3d0b02014-04-21 21:58:521197 let mut d: RingBuf<int> = range(0i, 5).collect();
blake2-ppc57757a82013-09-26 07:19:261198 d.pop_front();
1199 d.swap(0, 3);
Huon Wilson4b9a7a22014-04-05 05:45:421200 assert_eq!(d.iter().map(|&x|x).collect::<Vec<int>>(), vec!(4, 2, 3, 1));
blake2-ppc57757a82013-09-26 07:19:261201 }
1202
1203 #[test]
Jed Estep096fb792013-06-26 14:04:441204 fn test_iter() {
blake2-ppc70523712013-07-10 13:27:141205 let mut d = RingBuf::new();
blake2-ppcf88d5322013-07-06 03:42:451206 assert_eq!(d.iter().next(), None);
blake2-ppc9ccf4432013-07-14 20:30:221207 assert_eq!(d.iter().size_hint(), (0, Some(0)));
blake2-ppcf88d5322013-07-06 03:42:451208
Niko Matsakis9e3d0b02014-04-21 21:58:521209 for i in range(0i, 5) {
Alexis Beingessnercf3b2e42014-11-06 17:24:471210 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:441211 }
Nick Cameron37a94b82014-08-04 12:19:021212 {
1213 let b: &[_] = &[&0,&1,&2,&3,&4];
1214 assert_eq!(d.iter().collect::<Vec<&int>>().as_slice(), b);
1215 }
Corey Richardsonf8ae9b02013-06-26 22:14:351216
Niko Matsakis9e3d0b02014-04-21 21:58:521217 for i in range(6i, 9) {
blake2-ppc70523712013-07-10 13:27:141218 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:441219 }
Nick Cameron37a94b82014-08-04 12:19:021220 {
1221 let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
1222 assert_eq!(d.iter().collect::<Vec<&int>>().as_slice(), b);
1223 }
blake2-ppc9ccf4432013-07-14 20:30:221224
1225 let mut it = d.iter();
1226 let mut len = d.len();
1227 loop {
1228 match it.next() {
1229 None => break,
1230 _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
1231 }
1232 }
Jed Estep096fb792013-06-26 14:04:441233 }
1234
1235 #[test]
1236 fn test_rev_iter() {
blake2-ppc70523712013-07-10 13:27:141237 let mut d = RingBuf::new();
Jonathan S03609e52014-04-21 04:59:121238 assert_eq!(d.iter().rev().next(), None);
blake2-ppcf88d5322013-07-06 03:42:451239
Niko Matsakis9e3d0b02014-04-21 21:58:521240 for i in range(0i, 5) {
Alexis Beingessnercf3b2e42014-11-06 17:24:471241 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:441242 }
Nick Cameron37a94b82014-08-04 12:19:021243 {
1244 let b: &[_] = &[&4,&3,&2,&1,&0];
1245 assert_eq!(d.iter().rev().collect::<Vec<&int>>().as_slice(), b);
1246 }
Corey Richardsonf8ae9b02013-06-26 22:14:351247
Niko Matsakis9e3d0b02014-04-21 21:58:521248 for i in range(6i, 9) {
blake2-ppc70523712013-07-10 13:27:141249 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:441250 }
Nick Cameron37a94b82014-08-04 12:19:021251 let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
1252 assert_eq!(d.iter().rev().collect::<Vec<&int>>().as_slice(), b);
Jed Estep096fb792013-06-26 14:04:441253 }
blake2-ppc08dc72f2013-07-06 03:42:451254
1255 #[test]
Niko Matsakisbc4164d2013-11-16 22:29:391256 fn test_mut_rev_iter_wrap() {
1257 let mut d = RingBuf::with_capacity(3);
Aaron Turonfc525ee2014-09-15 03:27:361258 assert!(d.iter_mut().rev().next().is_none());
Niko Matsakisbc4164d2013-11-16 22:29:391259
Alexis Beingessnercf3b2e42014-11-06 17:24:471260 d.push_back(1i);
1261 d.push_back(2);
1262 d.push_back(3);
Niko Matsakisbc4164d2013-11-16 22:29:391263 assert_eq!(d.pop_front(), Some(1));
Alexis Beingessnercf3b2e42014-11-06 17:24:471264 d.push_back(4);
Niko Matsakisbc4164d2013-11-16 22:29:391265
Aaron Turonfc525ee2014-09-15 03:27:361266 assert_eq!(d.iter_mut().rev().map(|x| *x).collect::<Vec<int>>(),
Huon Wilson4b9a7a22014-04-05 05:45:421267 vec!(4, 3, 2));
Niko Matsakisbc4164d2013-11-16 22:29:391268 }
1269
1270 #[test]
blake2-ppcf88d5322013-07-06 03:42:451271 fn test_mut_iter() {
blake2-ppc70523712013-07-10 13:27:141272 let mut d = RingBuf::new();
Aaron Turonfc525ee2014-09-15 03:27:361273 assert!(d.iter_mut().next().is_none());
blake2-ppcf88d5322013-07-06 03:42:451274
Daniel Micay100894552013-08-03 16:45:231275 for i in range(0u, 3) {
blake2-ppc70523712013-07-10 13:27:141276 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:451277 }
1278
Aaron Turonfc525ee2014-09-15 03:27:361279 for (i, elt) in d.iter_mut().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:451280 assert_eq!(*elt, 2 - i);
1281 *elt = i;
1282 }
1283
1284 {
Aaron Turonfc525ee2014-09-15 03:27:361285 let mut it = d.iter_mut();
blake2-ppcf88d5322013-07-06 03:42:451286 assert_eq!(*it.next().unwrap(), 0);
1287 assert_eq!(*it.next().unwrap(), 1);
1288 assert_eq!(*it.next().unwrap(), 2);
1289 assert!(it.next().is_none());
1290 }
1291 }
1292
1293 #[test]
1294 fn test_mut_rev_iter() {
blake2-ppc70523712013-07-10 13:27:141295 let mut d = RingBuf::new();
Aaron Turonfc525ee2014-09-15 03:27:361296 assert!(d.iter_mut().rev().next().is_none());
blake2-ppcf88d5322013-07-06 03:42:451297
Daniel Micay100894552013-08-03 16:45:231298 for i in range(0u, 3) {
blake2-ppc70523712013-07-10 13:27:141299 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:451300 }
1301
Aaron Turonfc525ee2014-09-15 03:27:361302 for (i, elt) in d.iter_mut().rev().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:451303 assert_eq!(*elt, i);
1304 *elt = i;
1305 }
1306
1307 {
Aaron Turonfc525ee2014-09-15 03:27:361308 let mut it = d.iter_mut().rev();
blake2-ppcf88d5322013-07-06 03:42:451309 assert_eq!(*it.next().unwrap(), 0);
1310 assert_eq!(*it.next().unwrap(), 1);
1311 assert_eq!(*it.next().unwrap(), 2);
1312 assert!(it.next().is_none());
1313 }
1314 }
1315
1316 #[test]
Brian Andersonee052192014-03-31 04:45:551317 fn test_from_iter() {
Daniel Micay6919cf52013-09-08 15:01:161318 use std::iter;
Niko Matsakis9e3d0b02014-04-21 21:58:521319 let v = vec!(1i,2,3,4,5,6,7);
Erick Tryzelaar68f40d22013-08-10 03:09:471320 let deq: RingBuf<int> = v.iter().map(|&x| x).collect();
Huon Wilson4b9a7a22014-04-05 05:45:421321 let u: Vec<int> = deq.iter().map(|&x| x).collect();
blake2-ppc08dc72f2013-07-06 03:42:451322 assert_eq!(u, v);
1323
Aaron Turonb299c2b2014-11-06 17:32:371324 let seq = iter::count(0u, 2).take(256);
blake2-ppc70523712013-07-10 13:27:141325 let deq: RingBuf<uint> = seq.collect();
Daniel Micay100894552013-08-03 16:45:231326 for (i, &x) in deq.iter().enumerate() {
blake2-ppc08dc72f2013-07-06 03:42:451327 assert_eq!(2*i, x);
1328 }
1329 assert_eq!(deq.len(), 256);
1330 }
blake2-ppc10c76982013-07-06 13:27:321331
1332 #[test]
1333 fn test_clone() {
blake2-ppc70523712013-07-10 13:27:141334 let mut d = RingBuf::new();
Niko Matsakis9e3d0b02014-04-21 21:58:521335 d.push_front(17i);
blake2-ppc70523712013-07-10 13:27:141336 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:471337 d.push_back(137);
1338 d.push_back(137);
blake2-ppc10c76982013-07-06 13:27:321339 assert_eq!(d.len(), 4u);
1340 let mut e = d.clone();
1341 assert_eq!(e.len(), 4u);
1342 while !d.is_empty() {
Alexis Beingessnercf3b2e42014-11-06 17:24:471343 assert_eq!(d.pop_back(), e.pop_back());
blake2-ppc10c76982013-07-06 13:27:321344 }
1345 assert_eq!(d.len(), 0u);
1346 assert_eq!(e.len(), 0u);
1347 }
1348
1349 #[test]
1350 fn test_eq() {
blake2-ppc70523712013-07-10 13:27:141351 let mut d = RingBuf::new();
Alex Crichton02882fb2014-02-28 09:23:061352 assert!(d == RingBuf::with_capacity(0));
Niko Matsakis9e3d0b02014-04-21 21:58:521353 d.push_front(137i);
blake2-ppc70523712013-07-10 13:27:141354 d.push_front(17);
1355 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:471356 d.push_back(137);
blake2-ppc70523712013-07-10 13:27:141357 let mut e = RingBuf::with_capacity(0);
Alexis Beingessnercf3b2e42014-11-06 17:24:471358 e.push_back(42);
1359 e.push_back(17);
1360 e.push_back(137);
1361 e.push_back(137);
Alex Crichton02882fb2014-02-28 09:23:061362 assert!(&e == &d);
Alexis Beingessnercf3b2e42014-11-06 17:24:471363 e.pop_back();
1364 e.push_back(0);
blake2-ppc10c76982013-07-06 13:27:321365 assert!(e != d);
1366 e.clear();
Alex Crichton02882fb2014-02-28 09:23:061367 assert!(e == RingBuf::new());
blake2-ppc10c76982013-07-06 13:27:321368 }
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041369
1370 #[test]
nham1cfa6562014-07-27 02:33:471371 fn test_hash() {
1372 let mut x = RingBuf::new();
1373 let mut y = RingBuf::new();
1374
Alexis Beingessnercf3b2e42014-11-06 17:24:471375 x.push_back(1i);
1376 x.push_back(2);
1377 x.push_back(3);
nham1cfa6562014-07-27 02:33:471378
Alexis Beingessnercf3b2e42014-11-06 17:24:471379 y.push_back(0i);
1380 y.push_back(1i);
nham1cfa6562014-07-27 02:33:471381 y.pop_front();
Alexis Beingessnercf3b2e42014-11-06 17:24:471382 y.push_back(2);
1383 y.push_back(3);
nham1cfa6562014-07-27 02:33:471384
1385 assert!(hash::hash(&x) == hash::hash(&y));
1386 }
1387
1388 #[test]
nham63615772014-07-27 03:18:561389 fn test_ord() {
1390 let x = RingBuf::new();
1391 let mut y = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471392 y.push_back(1i);
1393 y.push_back(2);
1394 y.push_back(3);
nham63615772014-07-27 03:18:561395 assert!(x < y);
1396 assert!(y > x);
1397 assert!(x <= x);
1398 assert!(x >= x);
1399 }
1400
1401 #[test]
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041402 fn test_show() {
Niko Matsakis9e3d0b02014-04-21 21:58:521403 let ringbuf: RingBuf<int> = range(0i, 10).collect();
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041404 assert!(format!("{}", ringbuf).as_slice() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
1405
1406 let ringbuf: RingBuf<&str> = vec!["just", "one", "test", "more"].iter()
1407 .map(|&s| s)
1408 .collect();
1409 assert!(format!("{}", ringbuf).as_slice() == "[just, one, test, more]");
1410 }
Colin Sherratt7a666df2014-10-19 20:19:071411
1412 #[test]
1413 fn test_drop() {
1414 static mut drops: uint = 0;
1415 struct Elem;
1416 impl Drop for Elem {
1417 fn drop(&mut self) {
1418 unsafe { drops += 1; }
1419 }
1420 }
1421
1422 let mut ring = RingBuf::new();
1423 ring.push_back(Elem);
1424 ring.push_front(Elem);
1425 ring.push_back(Elem);
1426 ring.push_front(Elem);
1427 drop(ring);
1428
1429 assert_eq!(unsafe {drops}, 4);
1430 }
1431
1432 #[test]
1433 fn test_drop_with_pop() {
1434 static mut drops: uint = 0;
1435 struct Elem;
1436 impl Drop for Elem {
1437 fn drop(&mut self) {
1438 unsafe { drops += 1; }
1439 }
1440 }
1441
1442 let mut ring = RingBuf::new();
1443 ring.push_back(Elem);
1444 ring.push_front(Elem);
1445 ring.push_back(Elem);
1446 ring.push_front(Elem);
1447
1448 drop(ring.pop_back());
1449 drop(ring.pop_front());
1450 assert_eq!(unsafe {drops}, 2);
1451
1452 drop(ring);
1453 assert_eq!(unsafe {drops}, 4);
1454 }
1455
1456 #[test]
1457 fn test_drop_clear() {
1458 static mut drops: uint = 0;
1459 struct Elem;
1460 impl Drop for Elem {
1461 fn drop(&mut self) {
1462 unsafe { drops += 1; }
1463 }
1464 }
1465
1466 let mut ring = RingBuf::new();
1467 ring.push_back(Elem);
1468 ring.push_front(Elem);
1469 ring.push_back(Elem);
1470 ring.push_front(Elem);
1471 ring.clear();
1472 assert_eq!(unsafe {drops}, 4);
1473
1474 drop(ring);
1475 assert_eq!(unsafe {drops}, 4);
1476 }
1477
1478 #[test]
1479 fn test_reserve_grow() {
1480 // test growth path A
1481 // [T o o H] -> [T o o H . . . . ]
1482 let mut ring = RingBuf::with_capacity(4);
1483 for i in range(0i, 3) {
1484 ring.push_back(i);
1485 }
1486 ring.reserve(7);
1487 for i in range(0i, 3) {
1488 assert_eq!(ring.pop_front(), Some(i));
1489 }
1490
1491 // test growth path B
1492 // [H T o o] -> [. T o o H . . . ]
1493 let mut ring = RingBuf::with_capacity(4);
1494 for i in range(0i, 1) {
1495 ring.push_back(i);
1496 assert_eq!(ring.pop_front(), Some(i));
1497 }
1498 for i in range(0i, 3) {
1499 ring.push_back(i);
1500 }
1501 ring.reserve(7);
1502 for i in range(0i, 3) {
1503 assert_eq!(ring.pop_front(), Some(i));
1504 }
1505
1506 // test growth path C
1507 // [o o H T] -> [o o H . . . . T ]
1508 let mut ring = RingBuf::with_capacity(4);
1509 for i in range(0i, 3) {
1510 ring.push_back(i);
1511 assert_eq!(ring.pop_front(), Some(i));
1512 }
1513 for i in range(0i, 3) {
1514 ring.push_back(i);
1515 }
1516 ring.reserve(7);
1517 for i in range(0i, 3) {
1518 assert_eq!(ring.pop_front(), Some(i));
1519 }
1520 }
1521
1522 #[test]
1523 fn test_get() {
1524 let mut ring = RingBuf::new();
1525 ring.push_back(0i);
1526 assert_eq!(ring.get(0), Some(&0));
1527 assert_eq!(ring.get(1), None);
1528
1529 ring.push_back(1);
1530 assert_eq!(ring.get(0), Some(&0));
1531 assert_eq!(ring.get(1), Some(&1));
1532 assert_eq!(ring.get(2), None);
1533
1534 ring.push_back(2);
1535 assert_eq!(ring.get(0), Some(&0));
1536 assert_eq!(ring.get(1), Some(&1));
1537 assert_eq!(ring.get(2), Some(&2));
1538 assert_eq!(ring.get(3), None);
1539
1540 assert_eq!(ring.pop_front(), Some(0));
1541 assert_eq!(ring.get(0), Some(&1));
1542 assert_eq!(ring.get(1), Some(&2));
1543 assert_eq!(ring.get(2), None);
1544
1545 assert_eq!(ring.pop_front(), Some(1));
1546 assert_eq!(ring.get(0), Some(&2));
1547 assert_eq!(ring.get(1), None);
1548
1549 assert_eq!(ring.pop_front(), Some(2));
1550 assert_eq!(ring.get(0), None);
1551 assert_eq!(ring.get(1), None);
1552 }
1553
1554 #[test]
1555 fn test_get_mut() {
1556 let mut ring = RingBuf::new();
1557 for i in range(0i, 3) {
1558 ring.push_back(i);
1559 }
1560
1561 match ring.get_mut(1) {
1562 Some(x) => *x = -1,
1563 None => ()
1564 };
1565
1566 assert_eq!(ring.get_mut(0), Some(&mut 0));
1567 assert_eq!(ring.get_mut(1), Some(&mut -1));
1568 assert_eq!(ring.get_mut(2), Some(&mut 2));
1569 assert_eq!(ring.get_mut(3), None);
1570
1571 assert_eq!(ring.pop_front(), Some(0));
1572 assert_eq!(ring.get_mut(0), Some(&mut -1));
1573 assert_eq!(ring.get_mut(1), Some(&mut 2));
1574 assert_eq!(ring.get_mut(2), None);
1575 }
Michael Sullivanc854d6e2012-07-03 17:52:321576}