blob: e4c9e51a8455b46f4eb7e31e312527d8056fac39 [file] [log] [blame]
Jonathan S03609e52014-04-21 04:59:121// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
Graydon Hoare00c856c2012-12-04 00:48:012// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
Steve Klabnik84030fd2014-08-30 21:11:2211//! This crate implements a double-ended queue with `O(1)` amortized inserts and removals from both
12//! ends of the container. It also has `O(1)` indexing like a vector. The contained elements are
13//! not required to be copyable, and the queue will be sendable if the contained type is sendable.
Patrick Waltonf3723cf2013-05-17 22:28:4414
Alex Crichton6a585372014-05-30 01:50:1215use core::prelude::*;
16
Alex Crichton56290a02014-12-22 17:04:2317use core::cmp::Ordering;
Tom Jakubowskid6a39412014-06-09 07:30:0418use core::default::Default;
Alex Crichton6a585372014-05-30 01:50:1219use core::fmt;
Alex Crichton56290a02014-12-22 17:04:2320use core::iter::{mod, FromIterator, RandomAccessIterator};
Colin Sherratt7a666df2014-10-19 20:19:0721use core::kinds::marker;
22use core::mem;
Colin Sherratt6277e3b2014-11-14 09:21:4423use core::num::{Int, UnsignedInt};
Alex Crichton56290a02014-12-22 17:04:2324use core::ops::{Index, IndexMut};
25use core::ptr;
26use core::raw::Slice as RawSlice;
Alex Crichton998fece2013-05-06 04:42:5427
Colin Sherratt7a666df2014-10-19 20:19:0728use std::hash::{Writer, Hash};
29use std::cmp;
30
31use alloc::heap;
blake2-ppc70523712013-07-10 13:27:1432
blake2-ppc0ff5c172013-07-06 03:42:4533static INITIAL_CAPACITY: uint = 8u; // 2^3
34static MINIMUM_CAPACITY: uint = 2u;
Daniel Micayb47e1e92013-02-16 22:55:5535
Alexis Beingessnercf3b2e42014-11-06 17:24:4736// FIXME(conventions): implement shrink_to_fit. Awkward with the current design, but it should
37// be scrapped anyway. Defer to rewrite?
Alexis Beingessnercf3b2e42014-11-06 17:24:4738
Tobias Bucher4a46f5e2014-12-09 22:05:1639/// `RingBuf` is a circular buffer, which can be used as a double-ended queue efficiently.
Alexis Beingessner8dbaa712014-12-31 00:07:5340#[stable]
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
Aaron Turon92ccc072014-12-20 08:35:0654#[stable]
Rohit Joshi8fb25ab2014-12-30 09:20:2455unsafe impl<T: Send> Send for RingBuf<T> {}
56
57#[stable]
58unsafe impl<T: Sync> Sync for RingBuf<T> {}
59
60#[stable]
Colin Sherratt7a666df2014-10-19 20:19:0761impl<T: Clone> Clone for RingBuf<T> {
62 fn clone(&self) -> RingBuf<T> {
63 self.iter().map(|t| t.clone()).collect()
64 }
65}
66
67#[unsafe_destructor]
Alexis Beingessner8dbaa712014-12-31 00:07:5368#[stable]
Colin Sherratt7a666df2014-10-19 20:19:0769impl<T> Drop for RingBuf<T> {
70 fn drop(&mut self) {
71 self.clear();
72 unsafe {
73 if mem::size_of::<T>() != 0 {
74 heap::deallocate(self.ptr as *mut u8,
75 self.cap * mem::size_of::<T>(),
76 mem::min_align_of::<T>())
77 }
78 }
79 }
Marijn Haverbeke26610db2012-01-11 11:49:3380}
Roy Frostig9c818892010-07-21 01:03:0981
Alex Crichton9021f612014-12-16 04:04:5282#[stable]
Tom Jakubowskid6a39412014-06-09 07:30:0483impl<T> Default for RingBuf<T> {
84 #[inline]
85 fn default() -> RingBuf<T> { RingBuf::new() }
86}
87
blake2-ppc70523712013-07-10 13:27:1488impl<T> RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:0789 /// Turn ptr into a slice
90 #[inline]
Alexis Beingessner8dbaa712014-12-31 00:07:5391 unsafe fn buffer_as_slice(&self) -> &[T] {
Clark Gaebel525f65e2014-12-16 04:01:5892 mem::transmute(RawSlice { data: self.ptr as *const T, len: self.cap })
93 }
94
95 /// Turn ptr into a mut slice
96 #[inline]
Alexis Beingessner8dbaa712014-12-31 00:07:5397 unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] {
Colin Sherratt7a666df2014-10-19 20:19:0798 mem::transmute(RawSlice { data: self.ptr as *const T, len: self.cap })
99 }
100
101 /// Moves an element out of the buffer
102 #[inline]
103 unsafe fn buffer_read(&mut self, off: uint) -> T {
104 ptr::read(self.ptr.offset(off as int) as *const T)
105 }
106
107 /// Writes an element into the buffer, moving it.
108 #[inline]
109 unsafe fn buffer_write(&mut self, off: uint, t: T) {
110 ptr::write(self.ptr.offset(off as int), t);
111 }
112
113 /// Returns true iff the buffer is at capacity
114 #[inline]
115 fn is_full(&self) -> bool { self.cap - self.len() == 1 }
Colin Sherratt40191182014-11-12 01:22:07116
117 /// Returns the index in the underlying buffer for a given logical element index.
118 #[inline]
119 fn wrap_index(&self, idx: uint) -> uint { wrap_index(idx, self.cap) }
Matt Murphy40f28c72014-12-03 17:12:30120
121 /// Copies a contiguous block of memory len long from src to dst
122 #[inline]
Piotr Czarnecki59d41532014-12-16 23:37:55123 unsafe fn copy(&self, dst: uint, src: uint, len: uint) {
124 debug_assert!(dst + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
125 self.cap);
126 debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
127 self.cap);
128 ptr::copy_memory(
129 self.ptr.offset(dst as int),
130 self.ptr.offset(src as int) as *const T,
131 len);
Matt Murphy40f28c72014-12-03 17:12:30132 }
Colin Sherratt7a666df2014-10-19 20:19:07133}
134
135impl<T> RingBuf<T> {
P1startf2aa88c2014-08-04 10:48:39136 /// Creates an empty `RingBuf`.
Alexis Beingessner8dbaa712014-12-31 00:07:53137 #[stable]
blake2-ppc70523712013-07-10 13:27:14138 pub fn new() -> RingBuf<T> {
139 RingBuf::with_capacity(INITIAL_CAPACITY)
140 }
141
P1startf2aa88c2014-08-04 10:48:39142 /// Creates an empty `RingBuf` with space for at least `n` elements.
Alexis Beingessner8dbaa712014-12-31 00:07:53143 #[stable]
blake2-ppc70523712013-07-10 13:27:14144 pub fn with_capacity(n: uint) -> RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:07145 // +1 since the ringbuffer always leaves one space empty
Colin Sherratt6277e3b2014-11-14 09:21:44146 let cap = cmp::max(n + 1, MINIMUM_CAPACITY).next_power_of_two();
147 let size = cap.checked_mul(mem::size_of::<T>())
Colin Sherratt7a666df2014-10-19 20:19:07148 .expect("capacity overflow");
149
Colin Sherrattba24e332014-11-10 03:34:53150 let ptr = if mem::size_of::<T>() != 0 {
151 unsafe {
152 let ptr = heap::allocate(size, mem::min_align_of::<T>()) as *mut T;;
153 if ptr.is_null() { ::alloc::oom() }
154 ptr
155 }
156 } else {
157 heap::EMPTY as *mut T
158 };
159
Colin Sherratt7a666df2014-10-19 20:19:07160 RingBuf {
161 tail: 0,
162 head: 0,
163 cap: cap,
Colin Sherrattba24e332014-11-10 03:34:53164 ptr: ptr
Colin Sherratt7a666df2014-10-19 20:19:07165 }
blake2-ppc70523712013-07-10 13:27:14166 }
167
P1startf2aa88c2014-08-04 10:48:39168 /// Retrieves an element in the `RingBuf` by index.
blake2-ppc70523712013-07-10 13:27:14169 ///
jbranchaudc09defa2014-12-09 05:28:07170 /// # Examples
Alexis Beingessnercf3b2e42014-11-06 17:24:47171 ///
172 /// ```rust
173 /// use std::collections::RingBuf;
174 ///
175 /// let mut buf = RingBuf::new();
176 /// buf.push_back(3i);
177 /// buf.push_back(4);
178 /// buf.push_back(5);
179 /// assert_eq!(buf.get(1).unwrap(), &4);
180 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53181 #[stable]
Alexis Beingessnercf3b2e42014-11-06 17:24:47182 pub fn get(&self, i: uint) -> Option<&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(&*self.ptr.offset(idx as int)) }
186 } else {
187 None
Alexis Beingessnercf3b2e42014-11-06 17:24:47188 }
189 }
190
191 /// Retrieves an element in the `RingBuf` mutably by index.
nhamebe80972014-07-17 23:19:51192 ///
jbranchaudc09defa2014-12-09 05:28:07193 /// # Examples
nhamebe80972014-07-17 23:19:51194 ///
195 /// ```rust
196 /// use std::collections::RingBuf;
197 ///
198 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47199 /// buf.push_back(3i);
200 /// buf.push_back(4);
201 /// buf.push_back(5);
202 /// match buf.get_mut(1) {
203 /// None => {}
204 /// Some(elem) => {
205 /// *elem = 7;
206 /// }
207 /// }
208 ///
P1startfd10d202014-08-02 06:39:39209 /// assert_eq!(buf[1], 7);
nhamebe80972014-07-17 23:19:51210 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53211 #[stable]
Alexis Beingessnercf3b2e42014-11-06 17:24:47212 pub fn get_mut(&mut self, i: uint) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07213 if i < self.len() {
Colin Sherratt40191182014-11-12 01:22:07214 let idx = self.wrap_index(self.tail + i);
Colin Sherratt7a666df2014-10-19 20:19:07215 unsafe { Some(&mut *self.ptr.offset(idx as int)) }
216 } else {
217 None
Alexis Beingessnercf3b2e42014-11-06 17:24:47218 }
blake2-ppc70523712013-07-10 13:27:14219 }
220
P1startf2aa88c2014-08-04 10:48:39221 /// Swaps elements at indices `i` and `j`.
blake2-ppc57757a82013-09-26 07:19:26222 ///
223 /// `i` and `j` may be equal.
224 ///
P1startf2aa88c2014-08-04 10:48:39225 /// Fails if there is no element with either index.
nhamebe80972014-07-17 23:19:51226 ///
jbranchaudc09defa2014-12-09 05:28:07227 /// # Examples
nhamebe80972014-07-17 23:19:51228 ///
229 /// ```rust
230 /// use std::collections::RingBuf;
231 ///
232 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47233 /// buf.push_back(3i);
234 /// buf.push_back(4);
235 /// buf.push_back(5);
nhamebe80972014-07-17 23:19:51236 /// buf.swap(0, 2);
P1startfd10d202014-08-02 06:39:39237 /// assert_eq!(buf[0], 5);
238 /// assert_eq!(buf[2], 3);
nhamebe80972014-07-17 23:19:51239 /// ```
Chase Southwoodabf492d2014-12-19 23:53:40240 #[stable]
blake2-ppc57757a82013-09-26 07:19:26241 pub fn swap(&mut self, i: uint, j: uint) {
242 assert!(i < self.len());
243 assert!(j < self.len());
Colin Sherratt40191182014-11-12 01:22:07244 let ri = self.wrap_index(self.tail + i);
245 let rj = self.wrap_index(self.tail + j);
Colin Sherratt7a666df2014-10-19 20:19:07246 unsafe {
247 ptr::swap(self.ptr.offset(ri as int), self.ptr.offset(rj as int))
248 }
blake2-ppc70523712013-07-10 13:27:14249 }
250
Alexis Beingessnercf3b2e42014-11-06 17:24:47251 /// Returns the number of elements the `RingBuf` can hold without
252 /// reallocating.
253 ///
jbranchaudc09defa2014-12-09 05:28:07254 /// # Examples
Alexis Beingessnercf3b2e42014-11-06 17:24:47255 ///
256 /// ```
257 /// use std::collections::RingBuf;
258 ///
259 /// let buf: RingBuf<int> = RingBuf::with_capacity(10);
Colin Sherratt7a666df2014-10-19 20:19:07260 /// assert!(buf.capacity() >= 10);
Alexis Beingessnercf3b2e42014-11-06 17:24:47261 /// ```
262 #[inline]
Alexis Beingessner8dbaa712014-12-31 00:07:53263 #[stable]
Colin Sherratt7a666df2014-10-19 20:19:07264 pub fn capacity(&self) -> uint { self.cap - 1 }
Tim Chevalier77de84b2013-05-27 18:47:38265
Alexis Beingessnercf3b2e42014-11-06 17:24:47266 /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
267 /// given `RingBuf`. Does nothing if the capacity is already sufficient.
Tim Chevalier77de84b2013-05-27 18:47:38268 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47269 /// Note that the allocator may give the collection more space than it requests. Therefore
270 /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
271 /// insertions are expected.
272 ///
273 /// # Panics
274 ///
275 /// Panics if the new capacity overflows `uint`.
276 ///
jbranchaudc09defa2014-12-09 05:28:07277 /// # Examples
Alexis Beingessnercf3b2e42014-11-06 17:24:47278 ///
279 /// ```
280 /// use std::collections::RingBuf;
281 ///
282 /// let mut buf: RingBuf<int> = vec![1].into_iter().collect();
283 /// buf.reserve_exact(10);
284 /// assert!(buf.capacity() >= 11);
285 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53286 #[stable]
Alexis Beingessnercf3b2e42014-11-06 17:24:47287 pub fn reserve_exact(&mut self, additional: uint) {
Colin Sherratt7a666df2014-10-19 20:19:07288 self.reserve(additional);
Alexis Beingessnercf3b2e42014-11-06 17:24:47289 }
290
291 /// Reserves capacity for at least `additional` more elements to be inserted in the given
292 /// `Ringbuf`. The collection may reserve more space to avoid frequent reallocations.
293 ///
294 /// # Panics
295 ///
296 /// Panics if the new capacity overflows `uint`.
297 ///
jbranchaudc09defa2014-12-09 05:28:07298 /// # Examples
Alexis Beingessnercf3b2e42014-11-06 17:24:47299 ///
300 /// ```
301 /// use std::collections::RingBuf;
302 ///
303 /// let mut buf: RingBuf<int> = vec![1].into_iter().collect();
304 /// buf.reserve(10);
305 /// assert!(buf.capacity() >= 11);
306 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53307 #[stable]
Alexis Beingessnercf3b2e42014-11-06 17:24:47308 pub fn reserve(&mut self, additional: uint) {
Colin Sherratt7a666df2014-10-19 20:19:07309 let new_len = self.len() + additional;
310 assert!(new_len + 1 > self.len(), "capacity overflow");
311 if new_len > self.capacity() {
Colin Sherratt6277e3b2014-11-14 09:21:44312 let count = (new_len + 1).next_power_of_two();
Colin Sherratt7a666df2014-10-19 20:19:07313 assert!(count >= new_len + 1);
314
315 if mem::size_of::<T>() != 0 {
316 let old = self.cap * mem::size_of::<T>();
Colin Sherratt6277e3b2014-11-14 09:21:44317 let new = count.checked_mul(mem::size_of::<T>())
Colin Sherratt7a666df2014-10-19 20:19:07318 .expect("capacity overflow");
319 unsafe {
320 self.ptr = heap::reallocate(self.ptr as *mut u8,
321 old,
322 new,
323 mem::min_align_of::<T>()) as *mut T;
Colin Sherrattba24e332014-11-10 03:34:53324 if self.ptr.is_null() { ::alloc::oom() }
Colin Sherratt7a666df2014-10-19 20:19:07325 }
326 }
327
328 // Move the shortest contiguous section of the ring buffer
329 // T H
330 // [o o o o o o o . ]
331 // T H
332 // A [o o o o o o o . . . . . . . . . ]
333 // H T
334 // [o o . o o o o o ]
335 // T H
336 // B [. . . o o o o o o o . . . . . . ]
337 // H T
338 // [o o o o o . o o ]
339 // H T
340 // C [o o o o o . . . . . . . . . o o ]
341
342 let oldcap = self.cap;
343 self.cap = count;
344
345 if self.tail <= self.head { // A
346 // Nop
347 } else if self.head < oldcap - self.tail { // B
348 unsafe {
349 ptr::copy_nonoverlapping_memory(
350 self.ptr.offset(oldcap as int),
351 self.ptr as *const T,
352 self.head
353 );
354 }
355 self.head += oldcap;
Colin Sherratt4cae9ad2014-11-11 02:16:29356 debug_assert!(self.head > self.tail);
Colin Sherratt7a666df2014-10-19 20:19:07357 } else { // C
358 unsafe {
359 ptr::copy_nonoverlapping_memory(
360 self.ptr.offset((count - (oldcap - self.tail)) as int),
361 self.ptr.offset(self.tail as int) as *const T,
362 oldcap - self.tail
363 );
364 }
365 self.tail = count - (oldcap - self.tail);
Colin Sherratt4cae9ad2014-11-11 02:16:29366 debug_assert!(self.head < self.tail);
Colin Sherratt7a666df2014-10-19 20:19:07367 }
Colin Sherratt4cae9ad2014-11-11 02:16:29368 debug_assert!(self.head < self.cap);
369 debug_assert!(self.tail < self.cap);
Colin Sherratt40191182014-11-12 01:22:07370 debug_assert!(self.cap.count_ones() == 1);
Colin Sherratt7a666df2014-10-19 20:19:07371 }
Tim Chevalier77de84b2013-05-27 18:47:38372 }
Jed Estep4f7a7422013-06-25 19:08:47373
P1startf2aa88c2014-08-04 10:48:39374 /// Returns a front-to-back iterator.
nhamebe80972014-07-17 23:19:51375 ///
jbranchaudc09defa2014-12-09 05:28:07376 /// # Examples
nhamebe80972014-07-17 23:19:51377 ///
378 /// ```rust
379 /// use std::collections::RingBuf;
380 ///
381 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47382 /// buf.push_back(5i);
383 /// buf.push_back(3);
384 /// buf.push_back(4);
Nick Cameron52ef4622014-08-06 09:59:40385 /// let b: &[_] = &[&5, &3, &4];
386 /// assert_eq!(buf.iter().collect::<Vec<&int>>().as_slice(), b);
nhamebe80972014-07-17 23:19:51387 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53388 #[stable]
Florian Wilkensf8cfd242014-12-19 20:52:10389 pub fn iter(&self) -> Iter<T> {
390 Iter {
Colin Sherratt7a666df2014-10-19 20:19:07391 tail: self.tail,
392 head: self.head,
393 ring: unsafe { self.buffer_as_slice() }
394 }
blake2-ppc3385e792013-07-15 23:13:26395 }
396
Andrew Wagner8fcc8322014-12-15 09:22:49397 /// Returns a front-to-back iterator that returns mutable references.
nhamebe80972014-07-17 23:19:51398 ///
jbranchaudc09defa2014-12-09 05:28:07399 /// # Examples
nhamebe80972014-07-17 23:19:51400 ///
401 /// ```rust
402 /// use std::collections::RingBuf;
403 ///
404 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47405 /// buf.push_back(5i);
406 /// buf.push_back(3);
407 /// buf.push_back(4);
Aaron Turonfc525ee2014-09-15 03:27:36408 /// for num in buf.iter_mut() {
nhamebe80972014-07-17 23:19:51409 /// *num = *num - 2;
410 /// }
Nick Cameron52ef4622014-08-06 09:59:40411 /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
Nick Cameron59976942014-09-24 11:41:09412 /// assert_eq!(buf.iter_mut().collect::<Vec<&mut int>>()[], b);
nhamebe80972014-07-17 23:19:51413 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53414 #[stable]
Florian Wilkensf8cfd242014-12-19 20:52:10415 pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> {
416 IterMut {
Colin Sherratt7a666df2014-10-19 20:19:07417 tail: self.tail,
418 head: self.head,
419 cap: self.cap,
420 ptr: self.ptr,
421 marker: marker::ContravariantLifetime::<'a>,
Niko Matsakisbc4164d2013-11-16 22:29:39422 }
Jed Estep4f7a7422013-06-25 19:08:47423 }
Alex Crichton21ac9852014-10-30 20:43:24424
Alexis Beingessner865c2db2014-11-23 02:34:11425 /// Consumes the list into an iterator yielding elements by value.
Alexis Beingessner8dbaa712014-12-31 00:07:53426 #[stable]
Florian Wilkensf8cfd242014-12-19 20:52:10427 pub fn into_iter(self) -> IntoIter<T> {
428 IntoIter {
Alexis Beingessner865c2db2014-11-23 02:34:11429 inner: self,
430 }
431 }
432
Clark Gaebel525f65e2014-12-16 04:01:58433 /// Returns a pair of slices which contain, in order, the contents of the
434 /// `RingBuf`.
435 #[inline]
436 #[unstable = "matches collection reform specification, waiting for dust to settle"]
437 pub fn as_slices<'a>(&'a self) -> (&'a [T], &'a [T]) {
438 unsafe {
439 let contiguous = self.is_contiguous();
440 let buf = self.buffer_as_slice();
441 if contiguous {
442 let (empty, buf) = buf.split_at(0);
443 (buf[self.tail..self.head], empty)
444 } else {
445 let (mid, right) = buf.split_at(self.tail);
446 let (left, _) = mid.split_at(self.head);
447 (right, left)
448 }
449 }
450 }
451
452 /// Returns a pair of slices which contain, in order, the contents of the
453 /// `RingBuf`.
454 #[inline]
455 #[unstable = "matches collection reform specification, waiting for dust to settle"]
456 pub fn as_mut_slices<'a>(&'a mut self) -> (&'a mut [T], &'a mut [T]) {
457 unsafe {
458 let contiguous = self.is_contiguous();
459 let head = self.head;
460 let tail = self.tail;
461 let buf = self.buffer_as_mut_slice();
462
463 if contiguous {
464 let (empty, buf) = buf.split_at_mut(0);
Nick Cameron113f8aa2014-12-23 03:23:11465 (buf.slice_mut(tail, head), empty)
Clark Gaebel525f65e2014-12-16 04:01:58466 } else {
467 let (mid, right) = buf.split_at_mut(tail);
468 let (left, _) = mid.split_at_mut(head);
469
470 (right, left)
471 }
472 }
473 }
474
Alex Crichton21ac9852014-10-30 20:43:24475 /// Returns the number of elements in the `RingBuf`.
476 ///
jbranchaudc09defa2014-12-09 05:28:07477 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24478 ///
479 /// ```
480 /// use std::collections::RingBuf;
481 ///
482 /// let mut v = RingBuf::new();
483 /// assert_eq!(v.len(), 0);
Alexis Beingessnercf3b2e42014-11-06 17:24:47484 /// v.push_back(1i);
Alex Crichton21ac9852014-10-30 20:43:24485 /// assert_eq!(v.len(), 1);
486 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53487 #[stable]
Colin Sherratt7a666df2014-10-19 20:19:07488 pub fn len(&self) -> uint { count(self.tail, self.head, self.cap) }
Alex Crichton21ac9852014-10-30 20:43:24489
490 /// Returns true if the buffer contains no elements
491 ///
jbranchaudc09defa2014-12-09 05:28:07492 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24493 ///
494 /// ```
495 /// use std::collections::RingBuf;
496 ///
497 /// let mut v = RingBuf::new();
498 /// assert!(v.is_empty());
499 /// v.push_front(1i);
500 /// assert!(!v.is_empty());
501 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53502 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24503 pub fn is_empty(&self) -> bool { self.len() == 0 }
504
Clark Gaebeld57f2592014-12-16 22:45:03505 /// Creates a draining iterator that clears the `RingBuf` and iterates over
506 /// the removed items from start to end.
507 ///
508 /// # Examples
509 ///
510 /// ```
511 /// use std::collections::RingBuf;
512 ///
513 /// let mut v = RingBuf::new();
514 /// v.push_back(1i);
515 /// assert_eq!(v.drain().next(), Some(1));
516 /// assert!(v.is_empty());
517 /// ```
518 #[inline]
519 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alexis Beingessner8dbaa712014-12-31 00:07:53520 pub fn drain(&mut self) -> Drain<T> {
Clark Gaebeld57f2592014-12-16 22:45:03521 Drain {
522 inner: self,
523 }
524 }
525
Alex Crichton21ac9852014-10-30 20:43:24526 /// Clears the buffer, removing all values.
527 ///
jbranchaudc09defa2014-12-09 05:28:07528 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24529 ///
530 /// ```
531 /// use std::collections::RingBuf;
532 ///
533 /// let mut v = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47534 /// v.push_back(1i);
Alex Crichton21ac9852014-10-30 20:43:24535 /// v.clear();
536 /// assert!(v.is_empty());
537 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53538 #[stable]
Clark Gaebeld57f2592014-12-16 22:45:03539 #[inline]
Alex Crichton21ac9852014-10-30 20:43:24540 pub fn clear(&mut self) {
Clark Gaebeld57f2592014-12-16 22:45:03541 self.drain();
Alex Crichton21ac9852014-10-30 20:43:24542 }
543
544 /// Provides a reference to the front element, or `None` if the sequence is
545 /// empty.
546 ///
jbranchaudc09defa2014-12-09 05:28:07547 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24548 ///
549 /// ```
550 /// use std::collections::RingBuf;
551 ///
552 /// let mut d = RingBuf::new();
553 /// assert_eq!(d.front(), None);
554 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47555 /// d.push_back(1i);
556 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24557 /// assert_eq!(d.front(), Some(&1i));
558 /// ```
Chase Southwoodabf492d2014-12-19 23:53:40559 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24560 pub fn front(&self) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07561 if !self.is_empty() { Some(&self[0]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24562 }
563
564 /// Provides a mutable reference to the front element, or `None` if the
565 /// sequence is empty.
566 ///
jbranchaudc09defa2014-12-09 05:28:07567 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24568 ///
569 /// ```
570 /// use std::collections::RingBuf;
571 ///
572 /// let mut d = RingBuf::new();
573 /// assert_eq!(d.front_mut(), None);
574 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47575 /// d.push_back(1i);
576 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24577 /// match d.front_mut() {
578 /// Some(x) => *x = 9i,
579 /// None => (),
580 /// }
581 /// assert_eq!(d.front(), Some(&9i));
582 /// ```
Chase Southwoodabf492d2014-12-19 23:53:40583 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24584 pub fn front_mut(&mut self) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07585 if !self.is_empty() { Some(&mut self[0]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24586 }
587
588 /// Provides a reference to the back element, or `None` if the sequence is
589 /// empty.
590 ///
jbranchaudc09defa2014-12-09 05:28:07591 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24592 ///
593 /// ```
594 /// use std::collections::RingBuf;
595 ///
596 /// let mut d = RingBuf::new();
597 /// assert_eq!(d.back(), None);
598 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47599 /// d.push_back(1i);
600 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24601 /// assert_eq!(d.back(), Some(&2i));
602 /// ```
Chase Southwoodabf492d2014-12-19 23:53:40603 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24604 pub fn back(&self) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07605 if !self.is_empty() { Some(&self[self.len() - 1]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24606 }
607
608 /// Provides a mutable reference to the back element, or `None` if the
609 /// sequence is empty.
610 ///
jbranchaudc09defa2014-12-09 05:28:07611 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24612 ///
613 /// ```
614 /// use std::collections::RingBuf;
615 ///
616 /// let mut d = RingBuf::new();
617 /// assert_eq!(d.back(), None);
618 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47619 /// d.push_back(1i);
620 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24621 /// match d.back_mut() {
622 /// Some(x) => *x = 9i,
623 /// None => (),
624 /// }
625 /// assert_eq!(d.back(), Some(&9i));
626 /// ```
Chase Southwoodabf492d2014-12-19 23:53:40627 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24628 pub fn back_mut(&mut self) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07629 let len = self.len();
630 if !self.is_empty() { Some(&mut self[len - 1]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24631 }
632
633 /// Removes the first element and returns it, or `None` if the sequence is
634 /// empty.
635 ///
jbranchaudc09defa2014-12-09 05:28:07636 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24637 ///
638 /// ```
639 /// use std::collections::RingBuf;
640 ///
641 /// let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47642 /// d.push_back(1i);
643 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24644 ///
645 /// assert_eq!(d.pop_front(), Some(1i));
646 /// assert_eq!(d.pop_front(), Some(2i));
647 /// assert_eq!(d.pop_front(), None);
648 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53649 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24650 pub fn pop_front(&mut self) -> Option<T> {
Colin Sherratt7a666df2014-10-19 20:19:07651 if self.is_empty() {
652 None
653 } else {
654 let tail = self.tail;
Colin Sherratt40191182014-11-12 01:22:07655 self.tail = self.wrap_index(self.tail + 1);
Colin Sherratt7a666df2014-10-19 20:19:07656 unsafe { Some(self.buffer_read(tail)) }
Alex Crichton21ac9852014-10-30 20:43:24657 }
Alex Crichton21ac9852014-10-30 20:43:24658 }
659
660 /// Inserts an element first in the sequence.
661 ///
jbranchaudc09defa2014-12-09 05:28:07662 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24663 ///
664 /// ```
665 /// use std::collections::RingBuf;
666 ///
667 /// let mut d = RingBuf::new();
668 /// d.push_front(1i);
669 /// d.push_front(2i);
670 /// assert_eq!(d.front(), Some(&2i));
671 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53672 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24673 pub fn push_front(&mut self, t: T) {
Colin Sherratt4cae9ad2014-11-11 02:16:29674 if self.is_full() {
675 self.reserve(1);
676 debug_assert!(!self.is_full());
677 }
Colin Sherratt7a666df2014-10-19 20:19:07678
Colin Sherratt40191182014-11-12 01:22:07679 self.tail = self.wrap_index(self.tail - 1);
Colin Sherratt7a666df2014-10-19 20:19:07680 let tail = self.tail;
681 unsafe { self.buffer_write(tail, t); }
Alex Crichton21ac9852014-10-30 20:43:24682 }
683
Alexis Beingessnercf3b2e42014-11-06 17:24:47684 /// Deprecated: Renamed to `push_back`.
685 #[deprecated = "Renamed to `push_back`"]
686 pub fn push(&mut self, t: T) {
687 self.push_back(t)
688 }
689
Alex Crichton21ac9852014-10-30 20:43:24690 /// Appends an element to the back of a buffer
691 ///
jbranchaudc09defa2014-12-09 05:28:07692 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24693 ///
694 /// ```rust
695 /// use std::collections::RingBuf;
696 ///
697 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47698 /// buf.push_back(1i);
699 /// buf.push_back(3);
Alex Crichton21ac9852014-10-30 20:43:24700 /// assert_eq!(3, *buf.back().unwrap());
701 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53702 #[stable]
Alexis Beingessnercf3b2e42014-11-06 17:24:47703 pub fn push_back(&mut self, t: T) {
Colin Sherratt4cae9ad2014-11-11 02:16:29704 if self.is_full() {
705 self.reserve(1);
706 debug_assert!(!self.is_full());
707 }
Colin Sherratt7a666df2014-10-19 20:19:07708
709 let head = self.head;
Colin Sherratt40191182014-11-12 01:22:07710 self.head = self.wrap_index(self.head + 1);
Colin Sherratt7a666df2014-10-19 20:19:07711 unsafe { self.buffer_write(head, t) }
Alex Crichton21ac9852014-10-30 20:43:24712 }
713
Alexis Beingessnercf3b2e42014-11-06 17:24:47714 /// Deprecated: Renamed to `pop_back`.
715 #[deprecated = "Renamed to `pop_back`"]
716 pub fn pop(&mut self) -> Option<T> {
717 self.pop_back()
718 }
719
Alex Crichton21ac9852014-10-30 20:43:24720 /// Removes the last element from a buffer and returns it, or `None` if
721 /// it is empty.
722 ///
jbranchaudc09defa2014-12-09 05:28:07723 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24724 ///
725 /// ```rust
726 /// use std::collections::RingBuf;
727 ///
728 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47729 /// assert_eq!(buf.pop_back(), None);
730 /// buf.push_back(1i);
731 /// buf.push_back(3);
732 /// assert_eq!(buf.pop_back(), Some(3));
Alex Crichton21ac9852014-10-30 20:43:24733 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53734 #[stable]
Alexis Beingessnercf3b2e42014-11-06 17:24:47735 pub fn pop_back(&mut self) -> Option<T> {
Colin Sherratt7a666df2014-10-19 20:19:07736 if self.is_empty() {
Alex Crichton21ac9852014-10-30 20:43:24737 None
Colin Sherratt7a666df2014-10-19 20:19:07738 } else {
Colin Sherratt40191182014-11-12 01:22:07739 self.head = self.wrap_index(self.head - 1);
Colin Sherratt7a666df2014-10-19 20:19:07740 let head = self.head;
741 unsafe { Some(self.buffer_read(head)) }
Alex Crichton21ac9852014-10-30 20:43:24742 }
743 }
Matt Murphy40f28c72014-12-03 17:12:30744
Clark Gaebel525f65e2014-12-16 04:01:58745 #[inline]
746 fn is_contiguous(&self) -> bool {
747 self.tail <= self.head
748 }
749
Matt Murphy40f28c72014-12-03 17:12:30750 /// Inserts an element at position `i` within the ringbuf. Whichever
751 /// end is closer to the insertion point will be moved to make room,
752 /// and all the affected elements will be moved to new positions.
753 ///
754 /// # Panics
755 ///
756 /// Panics if `i` is greater than ringbuf's length
757 ///
758 /// # Example
759 /// ```rust
760 /// use std::collections::RingBuf;
761 ///
762 /// let mut buf = RingBuf::new();
763 /// buf.push_back(10i);
764 /// buf.push_back(12);
765 /// buf.insert(1,11);
766 /// assert_eq!(Some(&11), buf.get(1));
767 /// ```
768 pub fn insert(&mut self, i: uint, t: T) {
769 assert!(i <= self.len(), "index out of bounds");
770 if self.is_full() {
771 self.reserve(1);
772 debug_assert!(!self.is_full());
773 }
774
775 // Move the least number of elements in the ring buffer and insert
776 // the given object
777 //
778 // At most len/2 - 1 elements will be moved. O(min(n, n-i))
779 //
780 // There are three main cases:
781 // Elements are contiguous
782 // - special case when tail is 0
783 // Elements are discontiguous and the insert is in the tail section
784 // Elements are discontiguous and the insert is in the head section
785 //
786 // For each of those there are two more cases:
787 // Insert is closer to tail
788 // Insert is closer to head
789 //
790 // Key: H - self.head
791 // T - self.tail
792 // o - Valid element
793 // I - Insertion element
794 // A - The element that should be after the insertion point
795 // M - Indicates element was moved
796
797 let idx = self.wrap_index(self.tail + i);
798
799 let distance_to_tail = i;
800 let distance_to_head = self.len() - i;
801
Clark Gaebel525f65e2014-12-16 04:01:58802 let contiguous = self.is_contiguous();
Matt Murphy40f28c72014-12-03 17:12:30803
804 match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
805 (true, true, _) if i == 0 => {
806 // push_front
807 //
808 // T
809 // I H
810 // [A o o o o o o . . . . . . . . .]
811 //
812 // H T
813 // [A o o o o o o o . . . . . I]
814 //
815
816 self.tail = self.wrap_index(self.tail - 1);
817 },
Piotr Czarnecki59d41532014-12-16 23:37:55818 (true, true, _) => unsafe {
Matt Murphy40f28c72014-12-03 17:12:30819 // contiguous, insert closer to tail:
820 //
821 // T I H
822 // [. . . o o A o o o o . . . . . .]
823 //
824 // T H
825 // [. . o o I A o o o o . . . . . .]
826 // M M
827 //
828 // contiguous, insert closer to tail and tail is 0:
829 //
830 //
831 // T I H
832 // [o o A o o o o . . . . . . . . .]
833 //
834 // H T
835 // [o I A o o o o o . . . . . . . o]
836 // M M
837
Piotr Czarnecki59d41532014-12-16 23:37:55838 let new_tail = self.wrap_index(self.tail - 1);
Matt Murphy40f28c72014-12-03 17:12:30839
Piotr Czarnecki59d41532014-12-16 23:37:55840 self.copy(new_tail, self.tail, 1);
841 // Already moved the tail, so we only copy `i - 1` elements.
842 self.copy(self.tail, self.tail + 1, i - 1);
843
844 self.tail = new_tail;
Matt Murphy40f28c72014-12-03 17:12:30845 },
Piotr Czarnecki59d41532014-12-16 23:37:55846 (true, false, _) => unsafe {
Matt Murphy40f28c72014-12-03 17:12:30847 // contiguous, insert closer to head:
848 //
849 // T I H
850 // [. . . o o o o A o o . . . . . .]
851 //
852 // T H
853 // [. . . o o o o I A o o . . . . .]
854 // M M M
855
Piotr Czarnecki59d41532014-12-16 23:37:55856 self.copy(idx + 1, idx, self.head - idx);
Matt Murphy40f28c72014-12-03 17:12:30857 self.head = self.wrap_index(self.head + 1);
Matt Murphy40f28c72014-12-03 17:12:30858 },
Piotr Czarnecki59d41532014-12-16 23:37:55859 (false, true, true) => unsafe {
860 // discontiguous, insert closer to tail, tail section:
Matt Murphy40f28c72014-12-03 17:12:30861 //
862 // H T I
863 // [o o o o o o . . . . . o o A o o]
864 //
865 // H T
866 // [o o o o o o . . . . o o I A o o]
867 // M M
868
Piotr Czarnecki59d41532014-12-16 23:37:55869 self.copy(self.tail - 1, self.tail, i);
870 self.tail -= 1;
Matt Murphy40f28c72014-12-03 17:12:30871 },
Piotr Czarnecki59d41532014-12-16 23:37:55872 (false, false, true) => unsafe {
873 // discontiguous, insert closer to head, tail section:
Matt Murphy40f28c72014-12-03 17:12:30874 //
875 // H T I
876 // [o o . . . . . . . o o o o o A o]
877 //
878 // H T
879 // [o o o . . . . . . o o o o o I A]
880 // M M M M
881
Matt Murphy40f28c72014-12-03 17:12:30882 // copy elements up to new head
Piotr Czarnecki59d41532014-12-16 23:37:55883 self.copy(1, 0, self.head);
Matt Murphy40f28c72014-12-03 17:12:30884
885 // copy last element into empty spot at bottom of buffer
886 self.copy(0, self.cap - 1, 1);
887
888 // move elements from idx to end forward not including ^ element
889 self.copy(idx + 1, idx, self.cap - 1 - idx);
Piotr Czarnecki59d41532014-12-16 23:37:55890
891 self.head += 1;
Matt Murphy40f28c72014-12-03 17:12:30892 },
Piotr Czarnecki59d41532014-12-16 23:37:55893 (false, true, false) if idx == 0 => unsafe {
894 // discontiguous, insert is closer to tail, head section,
Matt Murphy40f28c72014-12-03 17:12:30895 // and is at index zero in the internal buffer:
896 //
897 // I H T
898 // [A o o o o o o o o o . . . o o o]
899 //
900 // H T
901 // [A o o o o o o o o o . . o o o I]
902 // M M M
903
Matt Murphy40f28c72014-12-03 17:12:30904 // copy elements up to new tail
Piotr Czarnecki59d41532014-12-16 23:37:55905 self.copy(self.tail - 1, self.tail, self.cap - self.tail);
Matt Murphy40f28c72014-12-03 17:12:30906
907 // copy last element into empty spot at bottom of buffer
908 self.copy(self.cap - 1, 0, 1);
Piotr Czarnecki59d41532014-12-16 23:37:55909
910 self.tail -= 1;
Matt Murphy40f28c72014-12-03 17:12:30911 },
Piotr Czarnecki59d41532014-12-16 23:37:55912 (false, true, false) => unsafe {
913 // discontiguous, insert closer to tail, head section:
Matt Murphy40f28c72014-12-03 17:12:30914 //
915 // I H T
916 // [o o o A o o o o o o . . . o o o]
917 //
918 // H T
919 // [o o I A o o o o o o . . o o o o]
920 // M M M M M M
921
Matt Murphy40f28c72014-12-03 17:12:30922 // copy elements up to new tail
Piotr Czarnecki59d41532014-12-16 23:37:55923 self.copy(self.tail - 1, self.tail, self.cap - self.tail);
Matt Murphy40f28c72014-12-03 17:12:30924
925 // copy last element into empty spot at bottom of buffer
926 self.copy(self.cap - 1, 0, 1);
927
928 // move elements from idx-1 to end forward not including ^ element
929 self.copy(0, 1, idx - 1);
Piotr Czarnecki59d41532014-12-16 23:37:55930
931 self.tail -= 1;
932 },
933 (false, false, false) => unsafe {
934 // discontiguous, insert closer to head, head section:
Matt Murphy40f28c72014-12-03 17:12:30935 //
936 // I H T
937 // [o o o o A o o . . . . . . o o o]
938 //
939 // H T
940 // [o o o o I A o o . . . . . o o o]
941 // M M M
942
Piotr Czarnecki59d41532014-12-16 23:37:55943 self.copy(idx + 1, idx, self.head - idx);
944 self.head += 1;
Matt Murphy40f28c72014-12-03 17:12:30945 }
946 }
947
948 // tail might've been changed so we need to recalculate
949 let new_idx = self.wrap_index(self.tail + i);
950 unsafe {
951 self.buffer_write(new_idx, t);
952 }
953 }
Piotr Czarnecki59d41532014-12-16 23:37:55954
955 /// Removes and returns the element at position `i` from the ringbuf.
956 /// Whichever end is closer to the removal point will be moved to make
957 /// room, and all the affected elements will be moved to new positions.
958 /// Returns `None` if `i` is out of bounds.
959 ///
960 /// # Example
961 /// ```rust
962 /// use std::collections::RingBuf;
963 ///
964 /// let mut buf = RingBuf::new();
965 /// buf.push_back(5i);
966 /// buf.push_back(10i);
967 /// buf.push_back(12i);
968 /// buf.push_back(15);
969 /// buf.remove(2);
970 /// assert_eq!(Some(&15), buf.get(2));
971 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53972 #[stable]
Piotr Czarnecki59d41532014-12-16 23:37:55973 pub fn remove(&mut self, i: uint) -> Option<T> {
974 if self.is_empty() || self.len() <= i {
975 return None;
976 }
977
978 // There are three main cases:
979 // Elements are contiguous
980 // Elements are discontiguous and the removal is in the tail section
981 // Elements are discontiguous and the removal is in the head section
982 // - special case when elements are technically contiguous,
983 // but self.head = 0
984 //
985 // For each of those there are two more cases:
986 // Insert is closer to tail
987 // Insert is closer to head
988 //
989 // Key: H - self.head
990 // T - self.tail
991 // o - Valid element
992 // x - Element marked for removal
993 // R - Indicates element that is being removed
994 // M - Indicates element was moved
995
996 let idx = self.wrap_index(self.tail + i);
997
998 let elem = unsafe {
999 Some(self.buffer_read(idx))
1000 };
1001
1002 let distance_to_tail = i;
1003 let distance_to_head = self.len() - i;
1004
1005 let contiguous = self.tail <= self.head;
1006
1007 match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
1008 (true, true, _) => unsafe {
1009 // contiguous, remove closer to tail:
1010 //
1011 // T R H
1012 // [. . . o o x o o o o . . . . . .]
1013 //
1014 // T H
1015 // [. . . . o o o o o o . . . . . .]
1016 // M M
1017
1018 self.copy(self.tail + 1, self.tail, i);
1019 self.tail += 1;
1020 },
1021 (true, false, _) => unsafe {
1022 // contiguous, remove closer to head:
1023 //
1024 // T R H
1025 // [. . . o o o o x o o . . . . . .]
1026 //
1027 // T H
1028 // [. . . o o o o o o . . . . . . .]
1029 // M M
1030
1031 self.copy(idx, idx + 1, self.head - idx - 1);
1032 self.head -= 1;
1033 },
1034 (false, true, true) => unsafe {
1035 // discontiguous, remove closer to tail, tail section:
1036 //
1037 // H T R
1038 // [o o o o o o . . . . . o o x o o]
1039 //
1040 // H T
1041 // [o o o o o o . . . . . . o o o o]
1042 // M M
1043
1044 self.copy(self.tail + 1, self.tail, i);
1045 self.tail = self.wrap_index(self.tail + 1);
1046 },
1047 (false, false, false) => unsafe {
1048 // discontiguous, remove closer to head, head section:
1049 //
1050 // R H T
1051 // [o o o o x o o . . . . . . o o o]
1052 //
1053 // H T
1054 // [o o o o o o . . . . . . . o o o]
1055 // M M
1056
1057 self.copy(idx, idx + 1, self.head - idx - 1);
1058 self.head -= 1;
1059 },
1060 (false, false, true) => unsafe {
1061 // discontiguous, remove closer to head, tail section:
1062 //
1063 // H T R
1064 // [o o o . . . . . . o o o o o x o]
1065 //
1066 // H T
1067 // [o o . . . . . . . o o o o o o o]
1068 // M M M M
1069 //
1070 // or quasi-discontiguous, remove next to head, tail section:
1071 //
1072 // H T R
1073 // [. . . . . . . . . o o o o o x o]
1074 //
1075 // T H
1076 // [. . . . . . . . . o o o o o o .]
1077 // M
1078
1079 // draw in elements in the tail section
1080 self.copy(idx, idx + 1, self.cap - idx - 1);
1081
1082 // Prevents underflow.
1083 if self.head != 0 {
1084 // copy first element into empty spot
1085 self.copy(self.cap - 1, 0, 1);
1086
1087 // move elements in the head section backwards
1088 self.copy(0, 1, self.head - 1);
1089 }
1090
1091 self.head = self.wrap_index(self.head - 1);
1092 },
1093 (false, true, false) => unsafe {
1094 // discontiguous, remove closer to tail, head section:
1095 //
1096 // R H T
1097 // [o o x o o o o o o o . . . o o o]
1098 //
1099 // H T
1100 // [o o o o o o o o o o . . . . o o]
1101 // M M M M M
1102
1103 // draw in elements up to idx
1104 self.copy(1, 0, idx);
1105
1106 // copy last element into empty spot
1107 self.copy(0, self.cap - 1, 1);
1108
1109 // move elements from tail to end forward, excluding the last one
1110 self.copy(self.tail + 1, self.tail, self.cap - self.tail - 1);
1111
1112 self.tail = self.wrap_index(self.tail + 1);
1113 }
1114 }
1115
1116 return elem;
1117 }
Jed Estep4f7a7422013-06-25 19:08:471118}
1119
Colin Sherratt7a666df2014-10-19 20:19:071120/// Returns the index in the underlying buffer for a given logical element index.
1121#[inline]
1122fn wrap_index(index: uint, size: uint) -> uint {
1123 // size is always a power of 2
Colin Sherratt40191182014-11-12 01:22:071124 index & (size - 1)
Colin Sherratt7a666df2014-10-19 20:19:071125}
1126
1127/// Calculate the number of elements left to be read in the buffer
1128#[inline]
1129fn count(tail: uint, head: uint, size: uint) -> uint {
1130 // size is always a power of 2
1131 (head - tail) & (size - 1)
1132}
1133
Niko Matsakis1b487a82014-08-28 01:46:521134/// `RingBuf` iterator.
Alexis Beingessner8dbaa712014-12-31 00:07:531135#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101136pub struct Iter<'a, T:'a> {
Colin Sherratt7a666df2014-10-19 20:19:071137 ring: &'a [T],
1138 tail: uint,
1139 head: uint
Niko Matsakis1b487a82014-08-28 01:46:521140}
1141
Huon Wilsonb7832ed2014-12-30 10:01:361142// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
1143impl<'a, T> Clone for Iter<'a, T> {
1144 fn clone(&self) -> Iter<'a, T> {
1145 Iter {
1146 ring: self.ring,
1147 tail: self.tail,
1148 head: self.head
1149 }
1150 }
1151}
1152
Alexis Beingessner8dbaa712014-12-31 00:07:531153#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101154impl<'a, T> Iterator<&'a T> for Iter<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:391155 #[inline]
Erik Price5731ca32013-12-10 07:16:181156 fn next(&mut self) -> Option<&'a T> {
Colin Sherratt7a666df2014-10-19 20:19:071157 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:391158 return None;
1159 }
Colin Sherratt7a666df2014-10-19 20:19:071160 let tail = self.tail;
1161 self.tail = wrap_index(self.tail + 1, self.ring.len());
Aaron Turon6abfac02014-12-30 18:51:181162 unsafe { Some(self.ring.get_unchecked(tail)) }
Niko Matsakisbc4164d2013-11-16 22:29:391163 }
1164
1165 #[inline]
1166 fn size_hint(&self) -> (uint, Option<uint>) {
Colin Sherratt7a666df2014-10-19 20:19:071167 let len = count(self.tail, self.head, self.ring.len());
Niko Matsakisbc4164d2013-11-16 22:29:391168 (len, Some(len))
1169 }
1170}
1171
Alexis Beingessner8dbaa712014-12-31 00:07:531172#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101173impl<'a, T> DoubleEndedIterator<&'a T> for Iter<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:391174 #[inline]
Erik Price5731ca32013-12-10 07:16:181175 fn next_back(&mut self) -> Option<&'a T> {
Colin Sherratt7a666df2014-10-19 20:19:071176 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:391177 return None;
1178 }
Colin Sherratt7a666df2014-10-19 20:19:071179 self.head = wrap_index(self.head - 1, self.ring.len());
Aaron Turon6abfac02014-12-30 18:51:181180 unsafe { Some(self.ring.get_unchecked(self.head)) }
Niko Matsakisbc4164d2013-11-16 22:29:391181 }
1182}
Jed Estep35314c92013-06-26 15:38:291183
Alexis Beingessner8dbaa712014-12-31 00:07:531184#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101185impl<'a, T> ExactSizeIterator<&'a T> for Iter<'a, T> {}
blake2-ppc7c369ee72013-09-01 16:20:241186
Alexis Beingessner8dbaa712014-12-31 00:07:531187#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101188impl<'a, T> RandomAccessIterator<&'a T> for Iter<'a, T> {
blake2-ppcf6862132013-07-29 18:16:261189 #[inline]
Colin Sherratt7a666df2014-10-19 20:19:071190 fn indexable(&self) -> uint {
1191 let (len, _) = self.size_hint();
1192 len
1193 }
blake2-ppcf6862132013-07-29 18:16:261194
1195 #[inline]
Alex Crichtonf4083a22014-04-22 05:15:421196 fn idx(&mut self, j: uint) -> Option<&'a T> {
blake2-ppcf6862132013-07-29 18:16:261197 if j >= self.indexable() {
1198 None
1199 } else {
Colin Sherratt7a666df2014-10-19 20:19:071200 let idx = wrap_index(self.tail + j, self.ring.len());
Aaron Turon6abfac02014-12-30 18:51:181201 unsafe { Some(self.ring.get_unchecked(idx)) }
blake2-ppcf6862132013-07-29 18:16:261202 }
1203 }
1204}
1205
Florian Wilkensf8cfd242014-12-19 20:52:101206// FIXME This was implemented differently from Iter because of a problem
Colin Sherratt7a666df2014-10-19 20:19:071207// with returning the mutable reference. I couldn't find a way to
1208// make the lifetime checker happy so, but there should be a way.
Niko Matsakis1b487a82014-08-28 01:46:521209/// `RingBuf` mutable iterator.
Alexis Beingessner8dbaa712014-12-31 00:07:531210#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101211pub struct IterMut<'a, T:'a> {
Colin Sherratt7a666df2014-10-19 20:19:071212 ptr: *mut T,
1213 tail: uint,
1214 head: uint,
1215 cap: uint,
1216 marker: marker::ContravariantLifetime<'a>,
Niko Matsakis1b487a82014-08-28 01:46:521217}
1218
Alexis Beingessner8dbaa712014-12-31 00:07:531219#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101220impl<'a, T> Iterator<&'a mut T> for IterMut<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:391221 #[inline]
Erik Price5731ca32013-12-10 07:16:181222 fn next(&mut self) -> Option<&'a mut T> {
Colin Sherratt7a666df2014-10-19 20:19:071223 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:391224 return None;
1225 }
Colin Sherratt7a666df2014-10-19 20:19:071226 let tail = self.tail;
1227 self.tail = wrap_index(self.tail + 1, self.cap);
Alexis Beingessner865c2db2014-11-23 02:34:111228
1229 unsafe {
1230 Some(&mut *self.ptr.offset(tail as int))
Alex Crichton9d5d97b2014-10-15 06:05:011231 }
Niko Matsakisbc4164d2013-11-16 22:29:391232 }
1233
1234 #[inline]
1235 fn size_hint(&self) -> (uint, Option<uint>) {
Colin Sherratt7a666df2014-10-19 20:19:071236 let len = count(self.tail, self.head, self.cap);
1237 (len, Some(len))
Niko Matsakisbc4164d2013-11-16 22:29:391238 }
1239}
1240
Alexis Beingessner8dbaa712014-12-31 00:07:531241#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101242impl<'a, T> DoubleEndedIterator<&'a mut T> for IterMut<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:391243 #[inline]
Erik Price5731ca32013-12-10 07:16:181244 fn next_back(&mut self) -> Option<&'a mut T> {
Colin Sherratt7a666df2014-10-19 20:19:071245 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:391246 return None;
1247 }
Colin Sherratt7a666df2014-10-19 20:19:071248 self.head = wrap_index(self.head - 1, self.cap);
Alexis Beingessner865c2db2014-11-23 02:34:111249
1250 unsafe {
1251 Some(&mut *self.ptr.offset(self.head as int))
1252 }
Niko Matsakisbc4164d2013-11-16 22:29:391253 }
1254}
Daniel Micayb47e1e92013-02-16 22:55:551255
Alexis Beingessner8dbaa712014-12-31 00:07:531256#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101257impl<'a, T> ExactSizeIterator<&'a mut T> for IterMut<'a, T> {}
blake2-ppc7c369ee72013-09-01 16:20:241258
Alexis Beingessner8dbaa712014-12-31 00:07:531259/// A by-value RingBuf iterator
1260#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101261pub struct IntoIter<T> {
Alexis Beingessner865c2db2014-11-23 02:34:111262 inner: RingBuf<T>,
1263}
1264
Alexis Beingessner8dbaa712014-12-31 00:07:531265#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101266impl<T> Iterator<T> for IntoIter<T> {
Alexis Beingessner865c2db2014-11-23 02:34:111267 #[inline]
1268 fn next(&mut self) -> Option<T> {
1269 self.inner.pop_front()
1270 }
1271
1272 #[inline]
1273 fn size_hint(&self) -> (uint, Option<uint>) {
1274 let len = self.inner.len();
1275 (len, Some(len))
1276 }
1277}
1278
Alexis Beingessner8dbaa712014-12-31 00:07:531279#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101280impl<T> DoubleEndedIterator<T> for IntoIter<T> {
Alexis Beingessner865c2db2014-11-23 02:34:111281 #[inline]
1282 fn next_back(&mut self) -> Option<T> {
1283 self.inner.pop_back()
1284 }
1285}
1286
Alexis Beingessner8dbaa712014-12-31 00:07:531287#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101288impl<T> ExactSizeIterator<T> for IntoIter<T> {}
Alexis Beingessner865c2db2014-11-23 02:34:111289
Clark Gaebeld57f2592014-12-16 22:45:031290/// A draining RingBuf iterator
Alexis Beingessner8dbaa712014-12-31 00:07:531291#[unstable = "matches collection reform specification, waiting for dust to settle"]
Clark Gaebeld57f2592014-12-16 22:45:031292pub struct Drain<'a, T: 'a> {
1293 inner: &'a mut RingBuf<T>,
1294}
1295
1296#[unsafe_destructor]
Alexis Beingessner8dbaa712014-12-31 00:07:531297#[stable]
Clark Gaebeld57f2592014-12-16 22:45:031298impl<'a, T: 'a> Drop for Drain<'a, T> {
1299 fn drop(&mut self) {
1300 for _ in *self {}
1301 self.inner.head = 0;
1302 self.inner.tail = 0;
1303 }
1304}
1305
Alexis Beingessner8dbaa712014-12-31 00:07:531306#[stable]
Clark Gaebeld57f2592014-12-16 22:45:031307impl<'a, T: 'a> Iterator<T> for Drain<'a, T> {
1308 #[inline]
1309 fn next(&mut self) -> Option<T> {
1310 self.inner.pop_front()
1311 }
1312
1313 #[inline]
1314 fn size_hint(&self) -> (uint, Option<uint>) {
1315 let len = self.inner.len();
1316 (len, Some(len))
1317 }
1318}
1319
Alexis Beingessner8dbaa712014-12-31 00:07:531320#[stable]
Clark Gaebeld57f2592014-12-16 22:45:031321impl<'a, T: 'a> DoubleEndedIterator<T> for Drain<'a, T> {
1322 #[inline]
1323 fn next_back(&mut self) -> Option<T> {
1324 self.inner.pop_back()
1325 }
1326}
1327
Alexis Beingessner8dbaa712014-12-31 00:07:531328#[stable]
Clark Gaebeld57f2592014-12-16 22:45:031329impl<'a, T: 'a> ExactSizeIterator<T> for Drain<'a, T> {}
1330
Aaron Turonb94bcbf2014-12-30 22:44:261331#[stable]
Alex Crichton748bc3c2014-05-30 00:45:071332impl<A: PartialEq> PartialEq for RingBuf<A> {
blake2-ppc70523712013-07-10 13:27:141333 fn eq(&self, other: &RingBuf<A>) -> bool {
Colin Sherratt7a666df2014-10-19 20:19:071334 self.len() == other.len() &&
blake2-ppc10c76982013-07-06 13:27:321335 self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
1336 }
blake2-ppc10c76982013-07-06 13:27:321337}
1338
Aaron Turonb94bcbf2014-12-30 22:44:261339#[stable]
nham25acfde2014-08-01 20:05:031340impl<A: Eq> Eq for RingBuf<A> {}
1341
Aaron Turonb94bcbf2014-12-30 22:44:261342#[stable]
nham63615772014-07-27 03:18:561343impl<A: PartialOrd> PartialOrd for RingBuf<A> {
1344 fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
1345 iter::order::partial_cmp(self.iter(), other.iter())
1346 }
1347}
1348
Aaron Turonb94bcbf2014-12-30 22:44:261349#[stable]
nham3737c532014-08-01 20:22:481350impl<A: Ord> Ord for RingBuf<A> {
1351 #[inline]
1352 fn cmp(&self, other: &RingBuf<A>) -> Ordering {
1353 iter::order::cmp(self.iter(), other.iter())
1354 }
1355}
1356
Alexis Beingessner8dbaa712014-12-31 00:07:531357#[stable]
nham1cfa6562014-07-27 02:33:471358impl<S: Writer, A: Hash<S>> Hash<S> for RingBuf<A> {
1359 fn hash(&self, state: &mut S) {
nham9fa44242014-07-27 16:37:321360 self.len().hash(state);
nham1cfa6562014-07-27 02:33:471361 for elt in self.iter() {
1362 elt.hash(state);
1363 }
1364 }
1365}
1366
Alexis Beingessner8dbaa712014-12-31 00:07:531367#[stable]
P1startfd10d202014-08-02 06:39:391368impl<A> Index<uint, A> for RingBuf<A> {
1369 #[inline]
1370 fn index<'a>(&'a self, i: &uint) -> &'a A {
Colin Sherratt7a666df2014-10-19 20:19:071371 self.get(*i).expect("Out of bounds access")
P1startfd10d202014-08-02 06:39:391372 }
1373}
1374
Alexis Beingessner8dbaa712014-12-31 00:07:531375#[stable]
Alex Crichton1d356622014-10-23 15:42:211376impl<A> IndexMut<uint, A> for RingBuf<A> {
P1startfd10d202014-08-02 06:39:391377 #[inline]
Alex Crichton1d356622014-10-23 15:42:211378 fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut A {
Colin Sherratt7a666df2014-10-19 20:19:071379 self.get_mut(*i).expect("Out of bounds access")
P1startfd10d202014-08-02 06:39:391380 }
Alex Crichton1d356622014-10-23 15:42:211381}
P1startfd10d202014-08-02 06:39:391382
Alexis Beingessner8dbaa712014-12-31 00:07:531383#[stable]
Huon Wilson53487a02013-08-13 13:08:141384impl<A> FromIterator<A> for RingBuf<A> {
Brian Andersonee052192014-03-31 04:45:551385 fn from_iter<T: Iterator<A>>(iterator: T) -> RingBuf<A> {
blake2-ppcf8ae5262013-07-30 00:06:491386 let (lower, _) = iterator.size_hint();
1387 let mut deq = RingBuf::with_capacity(lower);
1388 deq.extend(iterator);
blake2-ppc08dc72f2013-07-06 03:42:451389 deq
1390 }
1391}
1392
Alexis Beingessner8dbaa712014-12-31 00:07:531393#[stable]
gamazeps16c8cd92014-11-08 00:39:391394impl<A> Extend<A> for RingBuf<A> {
Marvin Löbel6200e762014-03-20 13:12:561395 fn extend<T: Iterator<A>>(&mut self, mut iterator: T) {
1396 for elt in iterator {
Alexis Beingessnercf3b2e42014-11-06 17:24:471397 self.push_back(elt);
blake2-ppcf8ae5262013-07-30 00:06:491398 }
1399 }
1400}
1401
Alexis Beingessner8dbaa712014-12-31 00:07:531402#[stable]
Alex Crichton6a585372014-05-30 01:50:121403impl<T: fmt::Show> fmt::Show for RingBuf<T> {
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041404 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1405 try!(write!(f, "["));
1406
1407 for (i, e) in self.iter().enumerate() {
1408 if i != 0 { try!(write!(f, ", ")); }
1409 try!(write!(f, "{}", *e));
1410 }
1411
1412 write!(f, "]")
1413 }
1414}
1415
Brian Anderson6e27b272012-01-18 03:05:071416#[cfg(test)]
1417mod tests {
Steven Fackler3dcd2152014-11-06 08:05:531418 use self::Taggy::*;
1419 use self::Taggypar::*;
Eduard Burtescub45d30d2014-12-19 12:02:221420 use prelude::*;
1421 use core::cmp;
1422 use core::iter;
Alex Crichton02882fb2014-02-28 09:23:061423 use std::fmt::Show;
nham1cfa6562014-07-27 02:33:471424 use std::hash;
Alex Crichton760b93a2014-05-30 02:03:061425 use test::Bencher;
1426 use test;
1427
Alex Crichtonf47e4b22014-01-07 06:33:501428 use super::RingBuf;
Patrick Waltonfa5ee932012-12-28 02:24:181429
Brian Anderson6e27b272012-01-18 03:05:071430 #[test]
Victor Berger52ea83d2014-09-22 17:30:061431 #[allow(deprecated)]
Brian Anderson6e27b272012-01-18 03:05:071432 fn test_simple() {
blake2-ppc70523712013-07-10 13:27:141433 let mut d = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:451434 assert_eq!(d.len(), 0u);
Niko Matsakis9e3d0b02014-04-21 21:58:521435 d.push_front(17i);
1436 d.push_front(42i);
Alexis Beingessnercf3b2e42014-11-06 17:24:471437 d.push_back(137);
Corey Richardsoncc57ca02013-05-19 02:02:451438 assert_eq!(d.len(), 3u);
Alexis Beingessnercf3b2e42014-11-06 17:24:471439 d.push_back(137);
Corey Richardsoncc57ca02013-05-19 02:02:451440 assert_eq!(d.len(), 4u);
Luqman Aden3ef9aa02014-10-15 07:22:551441 debug!("{}", d.front());
blake2-ppc70523712013-07-10 13:27:141442 assert_eq!(*d.front().unwrap(), 42);
Luqman Aden3ef9aa02014-10-15 07:22:551443 debug!("{}", d.back());
blake2-ppc70523712013-07-10 13:27:141444 assert_eq!(*d.back().unwrap(), 137);
1445 let mut i = d.pop_front();
Luqman Aden3ef9aa02014-10-15 07:22:551446 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:141447 assert_eq!(i, Some(42));
Alexis Beingessnercf3b2e42014-11-06 17:24:471448 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:551449 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:141450 assert_eq!(i, Some(137));
Alexis Beingessnercf3b2e42014-11-06 17:24:471451 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:551452 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:141453 assert_eq!(i, Some(137));
Alexis Beingessnercf3b2e42014-11-06 17:24:471454 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:551455 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:141456 assert_eq!(i, Some(17));
Corey Richardsoncc57ca02013-05-19 02:02:451457 assert_eq!(d.len(), 0u);
Alexis Beingessnercf3b2e42014-11-06 17:24:471458 d.push_back(3);
Corey Richardsoncc57ca02013-05-19 02:02:451459 assert_eq!(d.len(), 1u);
blake2-ppc70523712013-07-10 13:27:141460 d.push_front(2);
Corey Richardsoncc57ca02013-05-19 02:02:451461 assert_eq!(d.len(), 2u);
Alexis Beingessnercf3b2e42014-11-06 17:24:471462 d.push_back(4);
Corey Richardsoncc57ca02013-05-19 02:02:451463 assert_eq!(d.len(), 3u);
blake2-ppc70523712013-07-10 13:27:141464 d.push_front(1);
Corey Richardsoncc57ca02013-05-19 02:02:451465 assert_eq!(d.len(), 4u);
Alex Crichton9d5d97b2014-10-15 06:05:011466 debug!("{}", d[0]);
1467 debug!("{}", d[1]);
1468 debug!("{}", d[2]);
1469 debug!("{}", d[3]);
1470 assert_eq!(d[0], 1);
1471 assert_eq!(d[1], 2);
1472 assert_eq!(d[2], 3);
1473 assert_eq!(d[3], 4);
Brian Anderson6e27b272012-01-18 03:05:071474 }
1475
Felix S. Klock IIa636f512013-05-01 23:32:371476 #[cfg(test)]
Alex Crichton748bc3c2014-05-30 00:45:071477 fn test_parameterized<T:Clone + PartialEq + Show>(a: T, b: T, c: T, d: T) {
Patrick Waltondc4bf172013-07-13 04:05:591478 let mut deq = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:451479 assert_eq!(deq.len(), 0);
Patrick Waltondc4bf172013-07-13 04:05:591480 deq.push_front(a.clone());
1481 deq.push_front(b.clone());
Alexis Beingessnercf3b2e42014-11-06 17:24:471482 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451483 assert_eq!(deq.len(), 3);
Alexis Beingessnercf3b2e42014-11-06 17:24:471484 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451485 assert_eq!(deq.len(), 4);
Marvin Löbel0ac7a212013-08-03 23:59:241486 assert_eq!((*deq.front().unwrap()).clone(), b.clone());
1487 assert_eq!((*deq.back().unwrap()).clone(), d.clone());
1488 assert_eq!(deq.pop_front().unwrap(), b.clone());
Alexis Beingessnercf3b2e42014-11-06 17:24:471489 assert_eq!(deq.pop_back().unwrap(), d.clone());
1490 assert_eq!(deq.pop_back().unwrap(), c.clone());
1491 assert_eq!(deq.pop_back().unwrap(), a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451492 assert_eq!(deq.len(), 0);
Alexis Beingessnercf3b2e42014-11-06 17:24:471493 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451494 assert_eq!(deq.len(), 1);
Patrick Waltondc4bf172013-07-13 04:05:591495 deq.push_front(b.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451496 assert_eq!(deq.len(), 2);
Alexis Beingessnercf3b2e42014-11-06 17:24:471497 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451498 assert_eq!(deq.len(), 3);
Patrick Waltondc4bf172013-07-13 04:05:591499 deq.push_front(a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451500 assert_eq!(deq.len(), 4);
NODA, Kaif27ad3d2014-10-05 10:11:171501 assert_eq!(deq[0].clone(), a.clone());
1502 assert_eq!(deq[1].clone(), b.clone());
1503 assert_eq!(deq[2].clone(), c.clone());
1504 assert_eq!(deq[3].clone(), d.clone());
Brian Anderson6e27b272012-01-18 03:05:071505 }
1506
blake2-ppc81933ed2013-07-06 03:42:451507 #[test]
blake2-ppc70523712013-07-10 13:27:141508 fn test_push_front_grow() {
1509 let mut deq = RingBuf::new();
Daniel Micay100894552013-08-03 16:45:231510 for i in range(0u, 66) {
blake2-ppc70523712013-07-10 13:27:141511 deq.push_front(i);
blake2-ppc81933ed2013-07-06 03:42:451512 }
1513 assert_eq!(deq.len(), 66);
1514
Daniel Micay100894552013-08-03 16:45:231515 for i in range(0u, 66) {
NODA, Kaif27ad3d2014-10-05 10:11:171516 assert_eq!(deq[i], 65 - i);
blake2-ppc81933ed2013-07-06 03:42:451517 }
1518
blake2-ppc70523712013-07-10 13:27:141519 let mut deq = RingBuf::new();
Daniel Micay100894552013-08-03 16:45:231520 for i in range(0u, 66) {
Alexis Beingessnercf3b2e42014-11-06 17:24:471521 deq.push_back(i);
blake2-ppc81933ed2013-07-06 03:42:451522 }
1523
Daniel Micay100894552013-08-03 16:45:231524 for i in range(0u, 66) {
NODA, Kaif27ad3d2014-10-05 10:11:171525 assert_eq!(deq[i], i);
blake2-ppc81933ed2013-07-06 03:42:451526 }
1527 }
1528
P1startfd10d202014-08-02 06:39:391529 #[test]
1530 fn test_index() {
1531 let mut deq = RingBuf::new();
1532 for i in range(1u, 4) {
1533 deq.push_front(i);
1534 }
1535 assert_eq!(deq[1], 2);
1536 }
1537
1538 #[test]
1539 #[should_fail]
1540 fn test_index_out_of_bounds() {
1541 let mut deq = RingBuf::new();
1542 for i in range(1u, 4) {
1543 deq.push_front(i);
1544 }
1545 deq[3];
1546 }
1547
blake2-ppc81933ed2013-07-06 03:42:451548 #[bench]
Liigo Zhuang408f4842014-04-01 01:16:351549 fn bench_new(b: &mut test::Bencher) {
Patrick Walton38efa172013-11-22 03:20:481550 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521551 let ring: RingBuf<u64> = RingBuf::new();
1552 test::black_box(ring);
Patrick Walton38efa172013-11-22 03:20:481553 })
blake2-ppc81933ed2013-07-06 03:42:451554 }
1555
1556 #[bench]
Colin Sherratt7a666df2014-10-19 20:19:071557 fn bench_push_back_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521558 let mut deq = RingBuf::with_capacity(101);
Patrick Walton38efa172013-11-22 03:20:481559 b.iter(|| {
Colin Sherratt7a666df2014-10-19 20:19:071560 for i in range(0i, 100) {
1561 deq.push_back(i);
1562 }
Colin Sherratt5e549d82014-11-11 02:57:521563 deq.head = 0;
1564 deq.tail = 0;
Patrick Walton38efa172013-11-22 03:20:481565 })
blake2-ppc81933ed2013-07-06 03:42:451566 }
1567
1568 #[bench]
Colin Sherratt7a666df2014-10-19 20:19:071569 fn bench_push_front_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521570 let mut deq = RingBuf::with_capacity(101);
Patrick Walton38efa172013-11-22 03:20:481571 b.iter(|| {
Colin Sherratt7a666df2014-10-19 20:19:071572 for i in range(0i, 100) {
1573 deq.push_front(i);
1574 }
Colin Sherratt5e549d82014-11-11 02:57:521575 deq.head = 0;
1576 deq.tail = 0;
Patrick Walton38efa172013-11-22 03:20:481577 })
blake2-ppc81933ed2013-07-06 03:42:451578 }
1579
1580 #[bench]
Colin Sherratt5e549d82014-11-11 02:57:521581 fn bench_pop_back_100(b: &mut test::Bencher) {
1582 let mut deq: RingBuf<int> = RingBuf::with_capacity(101);
Colin Sherratt7a666df2014-10-19 20:19:071583
Patrick Walton38efa172013-11-22 03:20:481584 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521585 deq.head = 100;
1586 deq.tail = 0;
1587 while !deq.is_empty() {
1588 test::black_box(deq.pop_back());
Colin Sherratt7a666df2014-10-19 20:19:071589 }
Colin Sherratt7a666df2014-10-19 20:19:071590 })
1591 }
1592
1593 #[bench]
1594 fn bench_pop_front_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521595 let mut deq: RingBuf<int> = RingBuf::with_capacity(101);
Colin Sherratt7a666df2014-10-19 20:19:071596
1597 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521598 deq.head = 100;
1599 deq.tail = 0;
1600 while !deq.is_empty() {
1601 test::black_box(deq.pop_front());
Colin Sherratt7a666df2014-10-19 20:19:071602 }
Colin Sherratt7a666df2014-10-19 20:19:071603 })
1604 }
1605
1606 #[bench]
1607 fn bench_grow_1025(b: &mut test::Bencher) {
1608 b.iter(|| {
1609 let mut deq = RingBuf::new();
1610 for i in range(0i, 1025) {
1611 deq.push_front(i);
Brendan Zabarauskas729060d2014-01-30 00:20:341612 }
Colin Sherratt5e549d82014-11-11 02:57:521613 test::black_box(deq);
Patrick Walton38efa172013-11-22 03:20:481614 })
blake2-ppc81933ed2013-07-06 03:42:451615 }
1616
Colin Sherratt7a666df2014-10-19 20:19:071617 #[bench]
1618 fn bench_iter_1000(b: &mut test::Bencher) {
1619 let ring: RingBuf<int> = range(0i, 1000).collect();
1620
1621 b.iter(|| {
1622 let mut sum = 0;
1623 for &i in ring.iter() {
1624 sum += i;
1625 }
Colin Sherratt5e549d82014-11-11 02:57:521626 test::black_box(sum);
Colin Sherratt7a666df2014-10-19 20:19:071627 })
1628 }
1629
1630 #[bench]
1631 fn bench_mut_iter_1000(b: &mut test::Bencher) {
1632 let mut ring: RingBuf<int> = range(0i, 1000).collect();
1633
1634 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521635 let mut sum = 0;
Colin Sherratt7a666df2014-10-19 20:19:071636 for i in ring.iter_mut() {
Colin Sherratt5e549d82014-11-11 02:57:521637 sum += *i;
Colin Sherratt7a666df2014-10-19 20:19:071638 }
Colin Sherratt5e549d82014-11-11 02:57:521639 test::black_box(sum);
Colin Sherratt7a666df2014-10-19 20:19:071640 })
1641 }
1642
Alex Crichton748bc3c2014-05-30 00:45:071643 #[deriving(Clone, PartialEq, Show)]
Patrick Walton99b33f72013-07-02 19:47:321644 enum Taggy {
1645 One(int),
1646 Two(int, int),
1647 Three(int, int, int),
Brian Anderson6e27b272012-01-18 03:05:071648 }
1649
Alex Crichton748bc3c2014-05-30 00:45:071650 #[deriving(Clone, PartialEq, Show)]
Patrick Walton99b33f72013-07-02 19:47:321651 enum Taggypar<T> {
1652 Onepar(int),
1653 Twopar(int, int),
1654 Threepar(int, int, int),
1655 }
1656
Alex Crichton748bc3c2014-05-30 00:45:071657 #[deriving(Clone, PartialEq, Show)]
Erick Tryzelaare84576b2013-01-22 16:44:241658 struct RecCy {
1659 x: int,
1660 y: int,
Patrick Waltoneb4d39e2013-01-26 00:57:391661 t: Taggy
Patrick Walton9117dcb2012-09-20 01:00:261662 }
Kevin Cantuc43426e2012-09-13 05:09:551663
1664 #[test]
1665 fn test_param_int() {
1666 test_parameterized::<int>(5, 72, 64, 175);
1667 }
1668
1669 #[test]
Kevin Cantuc43426e2012-09-13 05:09:551670 fn test_param_taggy() {
Corey Richardsonf8ae9b02013-06-26 22:14:351671 test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:551672 }
1673
1674 #[test]
1675 fn test_param_taggypar() {
1676 test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
Ben Striegela605fd02012-08-11 14:08:421677 Twopar::<int>(1, 2),
1678 Threepar::<int>(1, 2, 3),
1679 Twopar::<int>(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:551680 }
Brian Anderson6e27b272012-01-18 03:05:071681
Kevin Cantuc43426e2012-09-13 05:09:551682 #[test]
1683 fn test_param_reccy() {
Erick Tryzelaare84576b2013-01-22 16:44:241684 let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
1685 let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
1686 let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
1687 let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
Kevin Cantuc43426e2012-09-13 05:09:551688 test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
Brian Anderson6e27b272012-01-18 03:05:071689 }
Erick Tryzelaar909d8f02013-03-30 01:02:441690
1691 #[test]
blake2-ppc0ff5c172013-07-06 03:42:451692 fn test_with_capacity() {
blake2-ppc70523712013-07-10 13:27:141693 let mut d = RingBuf::with_capacity(0);
Alexis Beingessnercf3b2e42014-11-06 17:24:471694 d.push_back(1i);
blake2-ppc0ff5c172013-07-06 03:42:451695 assert_eq!(d.len(), 1);
blake2-ppc70523712013-07-10 13:27:141696 let mut d = RingBuf::with_capacity(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471697 d.push_back(1i);
blake2-ppc0ff5c172013-07-06 03:42:451698 assert_eq!(d.len(), 1);
1699 }
1700
1701 #[test]
Kevin Butler64896d62014-08-07 01:11:131702 fn test_with_capacity_non_power_two() {
1703 let mut d3 = RingBuf::with_capacity(3);
Alexis Beingessnercf3b2e42014-11-06 17:24:471704 d3.push_back(1i);
Kevin Butler64896d62014-08-07 01:11:131705
1706 // X = None, | = lo
1707 // [|1, X, X]
1708 assert_eq!(d3.pop_front(), Some(1));
1709 // [X, |X, X]
1710 assert_eq!(d3.front(), None);
1711
1712 // [X, |3, X]
Alexis Beingessnercf3b2e42014-11-06 17:24:471713 d3.push_back(3);
Kevin Butler64896d62014-08-07 01:11:131714 // [X, |3, 6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471715 d3.push_back(6);
Kevin Butler64896d62014-08-07 01:11:131716 // [X, X, |6]
1717 assert_eq!(d3.pop_front(), Some(3));
1718
1719 // Pushing the lo past half way point to trigger
1720 // the 'B' scenario for growth
1721 // [9, X, |6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471722 d3.push_back(9);
Kevin Butler64896d62014-08-07 01:11:131723 // [9, 12, |6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471724 d3.push_back(12);
Kevin Butler64896d62014-08-07 01:11:131725
Alexis Beingessnercf3b2e42014-11-06 17:24:471726 d3.push_back(15);
Kevin Butler64896d62014-08-07 01:11:131727 // There used to be a bug here about how the
1728 // RingBuf made growth assumptions about the
1729 // underlying Vec which didn't hold and lead
1730 // to corruption.
1731 // (Vec grows to next power of two)
1732 //good- [9, 12, 15, X, X, X, X, |6]
1733 //bug- [15, 12, X, X, X, |6, X, X]
1734 assert_eq!(d3.pop_front(), Some(6));
1735
1736 // Which leads us to the following state which
1737 // would be a failure case.
1738 //bug- [15, 12, X, X, X, X, |X, X]
1739 assert_eq!(d3.front(), Some(&9));
1740 }
1741
1742 #[test]
David Manescu65f35782014-01-31 13:03:201743 fn test_reserve_exact() {
blake2-ppc70523712013-07-10 13:27:141744 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471745 d.push_back(0u64);
David Manescu65f35782014-01-31 13:03:201746 d.reserve_exact(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471747 assert!(d.capacity() >= 51);
blake2-ppc70523712013-07-10 13:27:141748 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471749 d.push_back(0u32);
David Manescu65f35782014-01-31 13:03:201750 d.reserve_exact(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471751 assert!(d.capacity() >= 51);
Tim Chevalier77de84b2013-05-27 18:47:381752 }
1753
1754 #[test]
David Manescu65f35782014-01-31 13:03:201755 fn test_reserve() {
blake2-ppc70523712013-07-10 13:27:141756 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471757 d.push_back(0u64);
David Manescu65f35782014-01-31 13:03:201758 d.reserve(50);
Colin Sherratt7a666df2014-10-19 20:19:071759 assert!(d.capacity() >= 51);
blake2-ppc70523712013-07-10 13:27:141760 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471761 d.push_back(0u32);
David Manescu65f35782014-01-31 13:03:201762 d.reserve(50);
Colin Sherratt7a666df2014-10-19 20:19:071763 assert!(d.capacity() >= 51);
Tim Chevalier77de84b2013-05-27 18:47:381764 }
1765
Jed Estep096fb792013-06-26 14:04:441766 #[test]
blake2-ppc57757a82013-09-26 07:19:261767 fn test_swap() {
Niko Matsakis9e3d0b02014-04-21 21:58:521768 let mut d: RingBuf<int> = range(0i, 5).collect();
blake2-ppc57757a82013-09-26 07:19:261769 d.pop_front();
1770 d.swap(0, 3);
Huon Wilson4b9a7a22014-04-05 05:45:421771 assert_eq!(d.iter().map(|&x|x).collect::<Vec<int>>(), vec!(4, 2, 3, 1));
blake2-ppc57757a82013-09-26 07:19:261772 }
1773
1774 #[test]
Jed Estep096fb792013-06-26 14:04:441775 fn test_iter() {
blake2-ppc70523712013-07-10 13:27:141776 let mut d = RingBuf::new();
blake2-ppcf88d5322013-07-06 03:42:451777 assert_eq!(d.iter().next(), None);
blake2-ppc9ccf4432013-07-14 20:30:221778 assert_eq!(d.iter().size_hint(), (0, Some(0)));
blake2-ppcf88d5322013-07-06 03:42:451779
Niko Matsakis9e3d0b02014-04-21 21:58:521780 for i in range(0i, 5) {
Alexis Beingessnercf3b2e42014-11-06 17:24:471781 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:441782 }
Nick Cameron37a94b82014-08-04 12:19:021783 {
1784 let b: &[_] = &[&0,&1,&2,&3,&4];
Jorge Apariciof2af07e2014-11-27 16:45:501785 assert_eq!(d.iter().collect::<Vec<&int>>(), b);
Nick Cameron37a94b82014-08-04 12:19:021786 }
Corey Richardsonf8ae9b02013-06-26 22:14:351787
Niko Matsakis9e3d0b02014-04-21 21:58:521788 for i in range(6i, 9) {
blake2-ppc70523712013-07-10 13:27:141789 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:441790 }
Nick Cameron37a94b82014-08-04 12:19:021791 {
1792 let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
Jorge Apariciof2af07e2014-11-27 16:45:501793 assert_eq!(d.iter().collect::<Vec<&int>>(), b);
Nick Cameron37a94b82014-08-04 12:19:021794 }
blake2-ppc9ccf4432013-07-14 20:30:221795
1796 let mut it = d.iter();
1797 let mut len = d.len();
1798 loop {
1799 match it.next() {
1800 None => break,
1801 _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
1802 }
1803 }
Jed Estep096fb792013-06-26 14:04:441804 }
1805
1806 #[test]
1807 fn test_rev_iter() {
blake2-ppc70523712013-07-10 13:27:141808 let mut d = RingBuf::new();
Jonathan S03609e52014-04-21 04:59:121809 assert_eq!(d.iter().rev().next(), None);
blake2-ppcf88d5322013-07-06 03:42:451810
Niko Matsakis9e3d0b02014-04-21 21:58:521811 for i in range(0i, 5) {
Alexis Beingessnercf3b2e42014-11-06 17:24:471812 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:441813 }
Nick Cameron37a94b82014-08-04 12:19:021814 {
1815 let b: &[_] = &[&4,&3,&2,&1,&0];
Jorge Apariciof2af07e2014-11-27 16:45:501816 assert_eq!(d.iter().rev().collect::<Vec<&int>>(), b);
Nick Cameron37a94b82014-08-04 12:19:021817 }
Corey Richardsonf8ae9b02013-06-26 22:14:351818
Niko Matsakis9e3d0b02014-04-21 21:58:521819 for i in range(6i, 9) {
blake2-ppc70523712013-07-10 13:27:141820 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:441821 }
Nick Cameron37a94b82014-08-04 12:19:021822 let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
Jorge Apariciof2af07e2014-11-27 16:45:501823 assert_eq!(d.iter().rev().collect::<Vec<&int>>(), b);
Jed Estep096fb792013-06-26 14:04:441824 }
blake2-ppc08dc72f2013-07-06 03:42:451825
1826 #[test]
Niko Matsakisbc4164d2013-11-16 22:29:391827 fn test_mut_rev_iter_wrap() {
1828 let mut d = RingBuf::with_capacity(3);
Aaron Turonfc525ee2014-09-15 03:27:361829 assert!(d.iter_mut().rev().next().is_none());
Niko Matsakisbc4164d2013-11-16 22:29:391830
Alexis Beingessnercf3b2e42014-11-06 17:24:471831 d.push_back(1i);
1832 d.push_back(2);
1833 d.push_back(3);
Niko Matsakisbc4164d2013-11-16 22:29:391834 assert_eq!(d.pop_front(), Some(1));
Alexis Beingessnercf3b2e42014-11-06 17:24:471835 d.push_back(4);
Niko Matsakisbc4164d2013-11-16 22:29:391836
Aaron Turonfc525ee2014-09-15 03:27:361837 assert_eq!(d.iter_mut().rev().map(|x| *x).collect::<Vec<int>>(),
Huon Wilson4b9a7a22014-04-05 05:45:421838 vec!(4, 3, 2));
Niko Matsakisbc4164d2013-11-16 22:29:391839 }
1840
1841 #[test]
blake2-ppcf88d5322013-07-06 03:42:451842 fn test_mut_iter() {
blake2-ppc70523712013-07-10 13:27:141843 let mut d = RingBuf::new();
Aaron Turonfc525ee2014-09-15 03:27:361844 assert!(d.iter_mut().next().is_none());
blake2-ppcf88d5322013-07-06 03:42:451845
Daniel Micay100894552013-08-03 16:45:231846 for i in range(0u, 3) {
blake2-ppc70523712013-07-10 13:27:141847 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:451848 }
1849
Aaron Turonfc525ee2014-09-15 03:27:361850 for (i, elt) in d.iter_mut().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:451851 assert_eq!(*elt, 2 - i);
1852 *elt = i;
1853 }
1854
1855 {
Aaron Turonfc525ee2014-09-15 03:27:361856 let mut it = d.iter_mut();
blake2-ppcf88d5322013-07-06 03:42:451857 assert_eq!(*it.next().unwrap(), 0);
1858 assert_eq!(*it.next().unwrap(), 1);
1859 assert_eq!(*it.next().unwrap(), 2);
1860 assert!(it.next().is_none());
1861 }
1862 }
1863
1864 #[test]
1865 fn test_mut_rev_iter() {
blake2-ppc70523712013-07-10 13:27:141866 let mut d = RingBuf::new();
Aaron Turonfc525ee2014-09-15 03:27:361867 assert!(d.iter_mut().rev().next().is_none());
blake2-ppcf88d5322013-07-06 03:42:451868
Daniel Micay100894552013-08-03 16:45:231869 for i in range(0u, 3) {
blake2-ppc70523712013-07-10 13:27:141870 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:451871 }
1872
Aaron Turonfc525ee2014-09-15 03:27:361873 for (i, elt) in d.iter_mut().rev().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:451874 assert_eq!(*elt, i);
1875 *elt = i;
1876 }
1877
1878 {
Aaron Turonfc525ee2014-09-15 03:27:361879 let mut it = d.iter_mut().rev();
blake2-ppcf88d5322013-07-06 03:42:451880 assert_eq!(*it.next().unwrap(), 0);
1881 assert_eq!(*it.next().unwrap(), 1);
1882 assert_eq!(*it.next().unwrap(), 2);
1883 assert!(it.next().is_none());
1884 }
1885 }
1886
1887 #[test]
Alexis Beingessner865c2db2014-11-23 02:34:111888 fn test_into_iter() {
1889
1890 // Empty iter
1891 {
1892 let d: RingBuf<int> = RingBuf::new();
1893 let mut iter = d.into_iter();
1894
1895 assert_eq!(iter.size_hint(), (0, Some(0)));
1896 assert_eq!(iter.next(), None);
1897 assert_eq!(iter.size_hint(), (0, Some(0)));
1898 }
1899
1900 // simple iter
1901 {
1902 let mut d = RingBuf::new();
1903 for i in range(0i, 5) {
1904 d.push_back(i);
1905 }
1906
1907 let b = vec![0,1,2,3,4];
1908 assert_eq!(d.into_iter().collect::<Vec<int>>(), b);
1909 }
1910
1911 // wrapped iter
1912 {
1913 let mut d = RingBuf::new();
1914 for i in range(0i, 5) {
1915 d.push_back(i);
1916 }
1917 for i in range(6, 9) {
1918 d.push_front(i);
1919 }
1920
1921 let b = vec![8,7,6,0,1,2,3,4];
1922 assert_eq!(d.into_iter().collect::<Vec<int>>(), b);
1923 }
1924
1925 // partially used
1926 {
1927 let mut d = RingBuf::new();
1928 for i in range(0i, 5) {
1929 d.push_back(i);
1930 }
1931 for i in range(6, 9) {
1932 d.push_front(i);
1933 }
1934
1935 let mut it = d.into_iter();
1936 assert_eq!(it.size_hint(), (8, Some(8)));
1937 assert_eq!(it.next(), Some(8));
1938 assert_eq!(it.size_hint(), (7, Some(7)));
1939 assert_eq!(it.next_back(), Some(4));
1940 assert_eq!(it.size_hint(), (6, Some(6)));
1941 assert_eq!(it.next(), Some(7));
1942 assert_eq!(it.size_hint(), (5, Some(5)));
1943 }
1944 }
1945
1946 #[test]
Clark Gaebeld57f2592014-12-16 22:45:031947 fn test_drain() {
1948
1949 // Empty iter
1950 {
1951 let mut d: RingBuf<int> = RingBuf::new();
1952
1953 {
1954 let mut iter = d.drain();
1955
1956 assert_eq!(iter.size_hint(), (0, Some(0)));
1957 assert_eq!(iter.next(), None);
1958 assert_eq!(iter.size_hint(), (0, Some(0)));
1959 }
1960
1961 assert!(d.is_empty());
1962 }
1963
1964 // simple iter
1965 {
1966 let mut d = RingBuf::new();
1967 for i in range(0i, 5) {
1968 d.push_back(i);
1969 }
1970
1971 assert_eq!(d.drain().collect::<Vec<int>>(), [0, 1, 2, 3, 4]);
1972 assert!(d.is_empty());
1973 }
1974
1975 // wrapped iter
1976 {
1977 let mut d = RingBuf::new();
1978 for i in range(0i, 5) {
1979 d.push_back(i);
1980 }
1981 for i in range(6, 9) {
1982 d.push_front(i);
1983 }
1984
1985 assert_eq!(d.drain().collect::<Vec<int>>(), [8,7,6,0,1,2,3,4]);
1986 assert!(d.is_empty());
1987 }
1988
1989 // partially used
1990 {
1991 let mut d = RingBuf::new();
1992 for i in range(0i, 5) {
1993 d.push_back(i);
1994 }
1995 for i in range(6, 9) {
1996 d.push_front(i);
1997 }
1998
1999 {
2000 let mut it = d.drain();
2001 assert_eq!(it.size_hint(), (8, Some(8)));
2002 assert_eq!(it.next(), Some(8));
2003 assert_eq!(it.size_hint(), (7, Some(7)));
2004 assert_eq!(it.next_back(), Some(4));
2005 assert_eq!(it.size_hint(), (6, Some(6)));
2006 assert_eq!(it.next(), Some(7));
2007 assert_eq!(it.size_hint(), (5, Some(5)));
2008 }
2009 assert!(d.is_empty());
2010 }
2011 }
2012
2013 #[test]
Brian Andersonee052192014-03-31 04:45:552014 fn test_from_iter() {
Eduard Burtescub45d30d2014-12-19 12:02:222015 use core::iter;
Niko Matsakis9e3d0b02014-04-21 21:58:522016 let v = vec!(1i,2,3,4,5,6,7);
Erick Tryzelaar68f40d22013-08-10 03:09:472017 let deq: RingBuf<int> = v.iter().map(|&x| x).collect();
Huon Wilson4b9a7a22014-04-05 05:45:422018 let u: Vec<int> = deq.iter().map(|&x| x).collect();
blake2-ppc08dc72f2013-07-06 03:42:452019 assert_eq!(u, v);
2020
Aaron Turonb299c2b2014-11-06 17:32:372021 let seq = iter::count(0u, 2).take(256);
blake2-ppc70523712013-07-10 13:27:142022 let deq: RingBuf<uint> = seq.collect();
Daniel Micay100894552013-08-03 16:45:232023 for (i, &x) in deq.iter().enumerate() {
blake2-ppc08dc72f2013-07-06 03:42:452024 assert_eq!(2*i, x);
2025 }
2026 assert_eq!(deq.len(), 256);
2027 }
blake2-ppc10c76982013-07-06 13:27:322028
2029 #[test]
2030 fn test_clone() {
blake2-ppc70523712013-07-10 13:27:142031 let mut d = RingBuf::new();
Niko Matsakis9e3d0b02014-04-21 21:58:522032 d.push_front(17i);
blake2-ppc70523712013-07-10 13:27:142033 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:472034 d.push_back(137);
2035 d.push_back(137);
blake2-ppc10c76982013-07-06 13:27:322036 assert_eq!(d.len(), 4u);
2037 let mut e = d.clone();
2038 assert_eq!(e.len(), 4u);
2039 while !d.is_empty() {
Alexis Beingessnercf3b2e42014-11-06 17:24:472040 assert_eq!(d.pop_back(), e.pop_back());
blake2-ppc10c76982013-07-06 13:27:322041 }
2042 assert_eq!(d.len(), 0u);
2043 assert_eq!(e.len(), 0u);
2044 }
2045
2046 #[test]
2047 fn test_eq() {
blake2-ppc70523712013-07-10 13:27:142048 let mut d = RingBuf::new();
Alex Crichton02882fb2014-02-28 09:23:062049 assert!(d == RingBuf::with_capacity(0));
Niko Matsakis9e3d0b02014-04-21 21:58:522050 d.push_front(137i);
blake2-ppc70523712013-07-10 13:27:142051 d.push_front(17);
2052 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:472053 d.push_back(137);
blake2-ppc70523712013-07-10 13:27:142054 let mut e = RingBuf::with_capacity(0);
Alexis Beingessnercf3b2e42014-11-06 17:24:472055 e.push_back(42);
2056 e.push_back(17);
2057 e.push_back(137);
2058 e.push_back(137);
Alex Crichton02882fb2014-02-28 09:23:062059 assert!(&e == &d);
Alexis Beingessnercf3b2e42014-11-06 17:24:472060 e.pop_back();
2061 e.push_back(0);
blake2-ppc10c76982013-07-06 13:27:322062 assert!(e != d);
2063 e.clear();
Alex Crichton02882fb2014-02-28 09:23:062064 assert!(e == RingBuf::new());
blake2-ppc10c76982013-07-06 13:27:322065 }
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042066
2067 #[test]
nham1cfa6562014-07-27 02:33:472068 fn test_hash() {
2069 let mut x = RingBuf::new();
2070 let mut y = RingBuf::new();
2071
Alexis Beingessnercf3b2e42014-11-06 17:24:472072 x.push_back(1i);
2073 x.push_back(2);
2074 x.push_back(3);
nham1cfa6562014-07-27 02:33:472075
Alexis Beingessnercf3b2e42014-11-06 17:24:472076 y.push_back(0i);
2077 y.push_back(1i);
nham1cfa6562014-07-27 02:33:472078 y.pop_front();
Alexis Beingessnercf3b2e42014-11-06 17:24:472079 y.push_back(2);
2080 y.push_back(3);
nham1cfa6562014-07-27 02:33:472081
2082 assert!(hash::hash(&x) == hash::hash(&y));
2083 }
2084
2085 #[test]
nham63615772014-07-27 03:18:562086 fn test_ord() {
2087 let x = RingBuf::new();
2088 let mut y = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:472089 y.push_back(1i);
2090 y.push_back(2);
2091 y.push_back(3);
nham63615772014-07-27 03:18:562092 assert!(x < y);
2093 assert!(y > x);
2094 assert!(x <= x);
2095 assert!(x >= x);
2096 }
2097
2098 #[test]
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042099 fn test_show() {
Niko Matsakis9e3d0b02014-04-21 21:58:522100 let ringbuf: RingBuf<int> = range(0i, 10).collect();
Jorge Apariciof2af07e2014-11-27 16:45:502101 assert!(format!("{}", ringbuf) == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042102
2103 let ringbuf: RingBuf<&str> = vec!["just", "one", "test", "more"].iter()
2104 .map(|&s| s)
2105 .collect();
Jorge Apariciof2af07e2014-11-27 16:45:502106 assert!(format!("{}", ringbuf) == "[just, one, test, more]");
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042107 }
Colin Sherratt7a666df2014-10-19 20:19:072108
2109 #[test]
2110 fn test_drop() {
2111 static mut drops: uint = 0;
2112 struct Elem;
2113 impl Drop for Elem {
2114 fn drop(&mut self) {
2115 unsafe { drops += 1; }
2116 }
2117 }
2118
2119 let mut ring = RingBuf::new();
2120 ring.push_back(Elem);
2121 ring.push_front(Elem);
2122 ring.push_back(Elem);
2123 ring.push_front(Elem);
2124 drop(ring);
2125
2126 assert_eq!(unsafe {drops}, 4);
2127 }
2128
2129 #[test]
2130 fn test_drop_with_pop() {
2131 static mut drops: uint = 0;
2132 struct Elem;
2133 impl Drop for Elem {
2134 fn drop(&mut self) {
2135 unsafe { drops += 1; }
2136 }
2137 }
2138
2139 let mut ring = RingBuf::new();
2140 ring.push_back(Elem);
2141 ring.push_front(Elem);
2142 ring.push_back(Elem);
2143 ring.push_front(Elem);
2144
2145 drop(ring.pop_back());
2146 drop(ring.pop_front());
2147 assert_eq!(unsafe {drops}, 2);
2148
2149 drop(ring);
2150 assert_eq!(unsafe {drops}, 4);
2151 }
2152
2153 #[test]
2154 fn test_drop_clear() {
2155 static mut drops: uint = 0;
2156 struct Elem;
2157 impl Drop for Elem {
2158 fn drop(&mut self) {
2159 unsafe { drops += 1; }
2160 }
2161 }
2162
2163 let mut ring = RingBuf::new();
2164 ring.push_back(Elem);
2165 ring.push_front(Elem);
2166 ring.push_back(Elem);
2167 ring.push_front(Elem);
2168 ring.clear();
2169 assert_eq!(unsafe {drops}, 4);
2170
2171 drop(ring);
2172 assert_eq!(unsafe {drops}, 4);
2173 }
2174
2175 #[test]
2176 fn test_reserve_grow() {
2177 // test growth path A
2178 // [T o o H] -> [T o o H . . . . ]
2179 let mut ring = RingBuf::with_capacity(4);
2180 for i in range(0i, 3) {
2181 ring.push_back(i);
2182 }
2183 ring.reserve(7);
2184 for i in range(0i, 3) {
2185 assert_eq!(ring.pop_front(), Some(i));
2186 }
2187
2188 // test growth path B
2189 // [H T o o] -> [. T o o H . . . ]
2190 let mut ring = RingBuf::with_capacity(4);
2191 for i in range(0i, 1) {
2192 ring.push_back(i);
2193 assert_eq!(ring.pop_front(), Some(i));
2194 }
2195 for i in range(0i, 3) {
2196 ring.push_back(i);
2197 }
2198 ring.reserve(7);
2199 for i in range(0i, 3) {
2200 assert_eq!(ring.pop_front(), Some(i));
2201 }
2202
2203 // test growth path C
2204 // [o o H T] -> [o o H . . . . T ]
2205 let mut ring = RingBuf::with_capacity(4);
2206 for i in range(0i, 3) {
2207 ring.push_back(i);
2208 assert_eq!(ring.pop_front(), Some(i));
2209 }
2210 for i in range(0i, 3) {
2211 ring.push_back(i);
2212 }
2213 ring.reserve(7);
2214 for i in range(0i, 3) {
2215 assert_eq!(ring.pop_front(), Some(i));
2216 }
2217 }
2218
2219 #[test]
2220 fn test_get() {
2221 let mut ring = RingBuf::new();
2222 ring.push_back(0i);
2223 assert_eq!(ring.get(0), Some(&0));
2224 assert_eq!(ring.get(1), None);
2225
2226 ring.push_back(1);
2227 assert_eq!(ring.get(0), Some(&0));
2228 assert_eq!(ring.get(1), Some(&1));
2229 assert_eq!(ring.get(2), None);
2230
2231 ring.push_back(2);
2232 assert_eq!(ring.get(0), Some(&0));
2233 assert_eq!(ring.get(1), Some(&1));
2234 assert_eq!(ring.get(2), Some(&2));
2235 assert_eq!(ring.get(3), None);
2236
2237 assert_eq!(ring.pop_front(), Some(0));
2238 assert_eq!(ring.get(0), Some(&1));
2239 assert_eq!(ring.get(1), Some(&2));
2240 assert_eq!(ring.get(2), None);
2241
2242 assert_eq!(ring.pop_front(), Some(1));
2243 assert_eq!(ring.get(0), Some(&2));
2244 assert_eq!(ring.get(1), None);
2245
2246 assert_eq!(ring.pop_front(), Some(2));
2247 assert_eq!(ring.get(0), None);
2248 assert_eq!(ring.get(1), None);
2249 }
2250
2251 #[test]
2252 fn test_get_mut() {
2253 let mut ring = RingBuf::new();
2254 for i in range(0i, 3) {
2255 ring.push_back(i);
2256 }
2257
2258 match ring.get_mut(1) {
2259 Some(x) => *x = -1,
2260 None => ()
2261 };
2262
2263 assert_eq!(ring.get_mut(0), Some(&mut 0));
2264 assert_eq!(ring.get_mut(1), Some(&mut -1));
2265 assert_eq!(ring.get_mut(2), Some(&mut 2));
2266 assert_eq!(ring.get_mut(3), None);
2267
2268 assert_eq!(ring.pop_front(), Some(0));
2269 assert_eq!(ring.get_mut(0), Some(&mut -1));
2270 assert_eq!(ring.get_mut(1), Some(&mut 2));
2271 assert_eq!(ring.get_mut(2), None);
2272 }
Matt Murphy40f28c72014-12-03 17:12:302273
2274 #[test]
2275 fn test_insert() {
2276 // This test checks that every single combination of tail position, length, and
Piotr Czarnecki59d41532014-12-16 23:37:552277 // insertion position is tested. Capacity 15 should be large enough to cover every case.
Matt Murphy40f28c72014-12-03 17:12:302278
Piotr Czarnecki59d41532014-12-16 23:37:552279 let mut tester = RingBuf::with_capacity(15);
2280 // can't guarantee we got 15, so have to get what we got.
2281 // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
Matt Murphy40f28c72014-12-03 17:12:302282 // this test isn't covering what it wants to
2283 let cap = tester.capacity();
2284
2285
2286 // len is the length *after* insertion
2287 for len in range(1, cap) {
2288 // 0, 1, 2, .., len - 1
2289 let expected = iter::count(0, 1).take(len).collect();
2290 for tail_pos in range(0, cap) {
2291 for to_insert in range(0, len) {
2292 tester.tail = tail_pos;
2293 tester.head = tail_pos;
2294 for i in range(0, len) {
2295 if i != to_insert {
2296 tester.push_back(i);
2297 }
2298 }
2299 tester.insert(to_insert, to_insert);
Piotr Czarnecki59d41532014-12-16 23:37:552300 assert!(tester.tail < tester.cap);
2301 assert!(tester.head < tester.cap);
2302 assert_eq!(tester, expected);
2303 }
2304 }
2305 }
2306 }
2307
2308 #[test]
2309 fn test_remove() {
2310 // This test checks that every single combination of tail position, length, and
2311 // removal position is tested. Capacity 15 should be large enough to cover every case.
2312
2313 let mut tester = RingBuf::with_capacity(15);
2314 // can't guarantee we got 15, so have to get what we got.
2315 // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
2316 // this test isn't covering what it wants to
2317 let cap = tester.capacity();
2318
2319 // len is the length *after* removal
2320 for len in range(0, cap - 1) {
2321 // 0, 1, 2, .., len - 1
2322 let expected = iter::count(0, 1).take(len).collect();
2323 for tail_pos in range(0, cap) {
2324 for to_remove in range(0, len + 1) {
2325 tester.tail = tail_pos;
2326 tester.head = tail_pos;
2327 for i in range(0, len) {
2328 if i == to_remove {
2329 tester.push_back(1234);
2330 }
2331 tester.push_back(i);
2332 }
2333 if to_remove == len {
2334 tester.push_back(1234);
2335 }
2336 tester.remove(to_remove);
2337 assert!(tester.tail < tester.cap);
2338 assert!(tester.head < tester.cap);
Matt Murphy40f28c72014-12-03 17:12:302339 assert_eq!(tester, expected);
2340 }
2341 }
2342 }
2343 }
2344
2345 #[test]
2346 fn test_front() {
2347 let mut ring = RingBuf::new();
2348 ring.push_back(10i);
2349 ring.push_back(20i);
2350 assert_eq!(ring.front(), Some(&10));
2351 ring.pop_front();
2352 assert_eq!(ring.front(), Some(&20));
2353 ring.pop_front();
2354 assert_eq!(ring.front(), None);
2355 }
Clark Gaebel525f65e2014-12-16 04:01:582356
2357 #[test]
2358 fn test_as_slices() {
2359 let mut ring: RingBuf<int> = RingBuf::with_capacity(127);
2360 let cap = ring.capacity() as int;
2361 let first = cap/2;
2362 let last = cap - first;
2363 for i in range(0, first) {
2364 ring.push_back(i);
2365
2366 let (left, right) = ring.as_slices();
2367 let expected: Vec<_> = range(0, i+1).collect();
2368 assert_eq!(left, expected);
2369 assert_eq!(right, []);
2370 }
2371
2372 for j in range(-last, 0) {
2373 ring.push_front(j);
2374 let (left, right) = ring.as_slices();
2375 let expected_left: Vec<_> = range(-last, j+1).rev().collect();
2376 let expected_right: Vec<_> = range(0, first).collect();
2377 assert_eq!(left, expected_left);
2378 assert_eq!(right, expected_right);
2379 }
2380
2381 assert_eq!(ring.len() as int, cap);
2382 assert_eq!(ring.capacity() as int, cap);
2383 }
2384
2385 #[test]
2386 fn test_as_mut_slices() {
2387 let mut ring: RingBuf<int> = RingBuf::with_capacity(127);
2388 let cap = ring.capacity() as int;
2389 let first = cap/2;
2390 let last = cap - first;
2391 for i in range(0, first) {
2392 ring.push_back(i);
2393
2394 let (left, right) = ring.as_mut_slices();
2395 let expected: Vec<_> = range(0, i+1).collect();
2396 assert_eq!(left, expected);
2397 assert_eq!(right, []);
2398 }
2399
2400 for j in range(-last, 0) {
2401 ring.push_front(j);
2402 let (left, right) = ring.as_mut_slices();
2403 let expected_left: Vec<_> = range(-last, j+1).rev().collect();
2404 let expected_right: Vec<_> = range(0, first).collect();
2405 assert_eq!(left, expected_left);
2406 assert_eq!(right, expected_right);
2407 }
2408
2409 assert_eq!(ring.len() as int, cap);
2410 assert_eq!(ring.capacity() as int, cap);
2411 }
Michael Sullivanc854d6e2012-07-03 17:52:322412}