blob: f5df7018153c4a039955460a061e122ae2405183 [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
Brian Andersonb44ee372015-01-24 05:48:2015#![stable(feature = "rust1", since = "1.0.0")]
Aaron Turoncb765ce2015-01-05 00:35:2016
Alex Crichton6a585372014-05-30 01:50:1217use core::prelude::*;
18
Alex Crichton56290a02014-12-22 17:04:2319use core::cmp::Ordering;
Tom Jakubowskid6a39412014-06-09 07:30:0420use core::default::Default;
Alex Crichton6a585372014-05-30 01:50:1221use core::fmt;
Jorge Aparicioa65d3f52015-01-08 03:01:0522use core::iter::{self, repeat, FromIterator, IntoIterator, RandomAccessIterator};
Nick Cameron9f07d052015-01-06 22:33:4223use core::marker;
Colin Sherratt7a666df2014-10-19 20:19:0724use core::mem;
Colin Sherratt6277e3b2014-11-14 09:21:4425use core::num::{Int, UnsignedInt};
Alex Crichton56290a02014-12-22 17:04:2326use core::ops::{Index, IndexMut};
27use core::ptr;
28use core::raw::Slice as RawSlice;
Alex Crichton998fece2013-05-06 04:42:5429
Alex Crichton511f0b82014-12-09 20:37:2330use std::hash::{Writer, Hash, Hasher};
Colin Sherratt7a666df2014-10-19 20:19:0731use std::cmp;
32
33use alloc::heap;
blake2-ppc70523712013-07-10 13:27:1434
Alexis15fb06d2015-02-05 20:08:3335static INITIAL_CAPACITY: usize = 7; // 2^3 - 1
36static MINIMUM_CAPACITY: usize = 1; // 2 - 1
Alexis Beingessnercf3b2e42014-11-06 17:24:4737
Tobias Bucher4a46f5e2014-12-09 22:05:1638/// `RingBuf` is a circular buffer, which can be used as a double-ended queue efficiently.
Brian Andersonb44ee372015-01-24 05:48:2039#[stable(feature = "rust1", since = "1.0.0")]
blake2-ppc70523712013-07-10 13:27:1440pub struct RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:0741 // tail and head are pointers into the buffer. Tail always points
42 // to the first element that could be read, Head always points
43 // to where data should be written.
44 // If tail == head the buffer is empty. The length of the ringbuf
45 // is defined as the distance between the two.
46
Alexise250fe32015-02-05 02:17:1947 tail: usize,
48 head: usize,
49 cap: usize,
Colin Sherratt7a666df2014-10-19 20:19:0750 ptr: *mut T
51}
52
Brian Andersonb44ee372015-01-24 05:48:2053#[stable(feature = "rust1", since = "1.0.0")]
Rohit Joshi8fb25ab2014-12-30 09:20:2454unsafe impl<T: Send> Send for RingBuf<T> {}
55
Brian Andersonb44ee372015-01-24 05:48:2056#[stable(feature = "rust1", since = "1.0.0")]
Rohit Joshi8fb25ab2014-12-30 09:20:2457unsafe impl<T: Sync> Sync for RingBuf<T> {}
58
Brian Andersonb44ee372015-01-24 05:48:2059#[stable(feature = "rust1", since = "1.0.0")]
Colin Sherratt7a666df2014-10-19 20:19:0760impl<T: Clone> Clone for RingBuf<T> {
61 fn clone(&self) -> RingBuf<T> {
Alexise250fe32015-02-05 02:17:1962 self.iter().cloned().collect()
Colin Sherratt7a666df2014-10-19 20:19:0763 }
64}
65
66#[unsafe_destructor]
Brian Andersonb44ee372015-01-24 05:48:2067#[stable(feature = "rust1", since = "1.0.0")]
Colin Sherratt7a666df2014-10-19 20:19:0768impl<T> Drop for RingBuf<T> {
69 fn drop(&mut self) {
70 self.clear();
71 unsafe {
72 if mem::size_of::<T>() != 0 {
73 heap::deallocate(self.ptr as *mut u8,
74 self.cap * mem::size_of::<T>(),
75 mem::min_align_of::<T>())
76 }
77 }
78 }
Marijn Haverbeke26610db2012-01-11 11:49:3379}
Roy Frostig9c818892010-07-21 01:03:0980
Brian Andersonb44ee372015-01-24 05:48:2081#[stable(feature = "rust1", since = "1.0.0")]
Tom Jakubowskid6a39412014-06-09 07:30:0482impl<T> Default for RingBuf<T> {
83 #[inline]
84 fn default() -> RingBuf<T> { RingBuf::new() }
85}
86
blake2-ppc70523712013-07-10 13:27:1487impl<T> RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:0788 /// Turn ptr into a slice
89 #[inline]
Alexis Beingessner8dbaa712014-12-31 00:07:5390 unsafe fn buffer_as_slice(&self) -> &[T] {
we812ce6c2015-01-17 04:34:1091 mem::transmute(RawSlice { data: self.ptr, len: self.cap })
Clark Gaebel525f65e2014-12-16 04:01:5892 }
93
94 /// Turn ptr into a mut slice
95 #[inline]
Alexis Beingessner8dbaa712014-12-31 00:07:5396 unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] {
we812ce6c2015-01-17 04:34:1097 mem::transmute(RawSlice { data: self.ptr, len: self.cap })
Colin Sherratt7a666df2014-10-19 20:19:0798 }
99
100 /// Moves an element out of the buffer
101 #[inline]
Alexise250fe32015-02-05 02:17:19102 unsafe fn buffer_read(&mut self, off: usize) -> T {
103 ptr::read(self.ptr.offset(off as isize))
Colin Sherratt7a666df2014-10-19 20:19:07104 }
105
106 /// Writes an element into the buffer, moving it.
107 #[inline]
Alexise250fe32015-02-05 02:17:19108 unsafe fn buffer_write(&mut self, off: usize, t: T) {
109 ptr::write(self.ptr.offset(off as isize), t);
Colin Sherratt7a666df2014-10-19 20:19:07110 }
111
112 /// Returns true iff the buffer is at capacity
113 #[inline]
114 fn is_full(&self) -> bool { self.cap - self.len() == 1 }
Colin Sherratt40191182014-11-12 01:22:07115
116 /// Returns the index in the underlying buffer for a given logical element index.
117 #[inline]
Alexise250fe32015-02-05 02:17:19118 fn wrap_index(&self, idx: usize) -> usize { wrap_index(idx, self.cap) }
Matt Murphy40f28c72014-12-03 17:12:30119
120 /// Copies a contiguous block of memory len long from src to dst
121 #[inline]
Alexise250fe32015-02-05 02:17:19122 unsafe fn copy(&self, dst: usize, src: usize, len: usize) {
Piotr Czarnecki59d41532014-12-16 23:37:55123 debug_assert!(dst + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
124 self.cap);
125 debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
126 self.cap);
127 ptr::copy_memory(
Alexise250fe32015-02-05 02:17:19128 self.ptr.offset(dst as isize),
129 self.ptr.offset(src as isize),
Piotr Czarnecki156a1c32015-01-05 14:48:58130 len);
131 }
132
133 /// Copies a contiguous block of memory len long from src to dst
134 #[inline]
Alexise250fe32015-02-05 02:17:19135 unsafe fn copy_nonoverlapping(&self, dst: usize, src: usize, len: usize) {
Piotr Czarnecki156a1c32015-01-05 14:48:58136 debug_assert!(dst + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
137 self.cap);
138 debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
139 self.cap);
140 ptr::copy_nonoverlapping_memory(
Alexise250fe32015-02-05 02:17:19141 self.ptr.offset(dst as isize),
142 self.ptr.offset(src as isize),
Piotr Czarnecki59d41532014-12-16 23:37:55143 len);
Matt Murphy40f28c72014-12-03 17:12:30144 }
Colin Sherratt7a666df2014-10-19 20:19:07145}
146
147impl<T> RingBuf<T> {
P1startf2aa88c2014-08-04 10:48:39148 /// Creates an empty `RingBuf`.
Brian Andersonb44ee372015-01-24 05:48:20149 #[stable(feature = "rust1", since = "1.0.0")]
blake2-ppc70523712013-07-10 13:27:14150 pub fn new() -> RingBuf<T> {
151 RingBuf::with_capacity(INITIAL_CAPACITY)
152 }
153
P1startf2aa88c2014-08-04 10:48:39154 /// Creates an empty `RingBuf` with space for at least `n` elements.
Brian Andersonb44ee372015-01-24 05:48:20155 #[stable(feature = "rust1", since = "1.0.0")]
Alexise250fe32015-02-05 02:17:19156 pub fn with_capacity(n: usize) -> RingBuf<T> {
Colin Sherratt7a666df2014-10-19 20:19:07157 // +1 since the ringbuffer always leaves one space empty
Piotr Czarnecki156a1c32015-01-05 14:48:58158 let cap = cmp::max(n + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
159 assert!(cap > n, "capacity overflow");
Colin Sherratt6277e3b2014-11-14 09:21:44160 let size = cap.checked_mul(mem::size_of::<T>())
Colin Sherratt7a666df2014-10-19 20:19:07161 .expect("capacity overflow");
162
Colin Sherrattba24e332014-11-10 03:34:53163 let ptr = if mem::size_of::<T>() != 0 {
164 unsafe {
165 let ptr = heap::allocate(size, mem::min_align_of::<T>()) as *mut T;;
166 if ptr.is_null() { ::alloc::oom() }
167 ptr
168 }
169 } else {
170 heap::EMPTY as *mut T
171 };
172
Colin Sherratt7a666df2014-10-19 20:19:07173 RingBuf {
174 tail: 0,
175 head: 0,
176 cap: cap,
Colin Sherrattba24e332014-11-10 03:34:53177 ptr: ptr
Colin Sherratt7a666df2014-10-19 20:19:07178 }
blake2-ppc70523712013-07-10 13:27:14179 }
180
P1startf2aa88c2014-08-04 10:48:39181 /// Retrieves an element in the `RingBuf` by index.
blake2-ppc70523712013-07-10 13:27:14182 ///
jbranchaudc09defa2014-12-09 05:28:07183 /// # Examples
Alexis Beingessnercf3b2e42014-11-06 17:24:47184 ///
185 /// ```rust
186 /// use std::collections::RingBuf;
187 ///
188 /// let mut buf = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:03189 /// buf.push_back(3);
Alexis Beingessnercf3b2e42014-11-06 17:24:47190 /// buf.push_back(4);
191 /// buf.push_back(5);
192 /// assert_eq!(buf.get(1).unwrap(), &4);
193 /// ```
Brian Andersonb44ee372015-01-24 05:48:20194 #[stable(feature = "rust1", since = "1.0.0")]
Alexise250fe32015-02-05 02:17:19195 pub fn get(&self, i: usize) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07196 if i < self.len() {
Colin Sherratt40191182014-11-12 01:22:07197 let idx = self.wrap_index(self.tail + i);
Alexise250fe32015-02-05 02:17:19198 unsafe { Some(&*self.ptr.offset(idx as isize)) }
Colin Sherratt7a666df2014-10-19 20:19:07199 } else {
200 None
Alexis Beingessnercf3b2e42014-11-06 17:24:47201 }
202 }
203
204 /// Retrieves an element in the `RingBuf` mutably by index.
nhamebe80972014-07-17 23:19:51205 ///
jbranchaudc09defa2014-12-09 05:28:07206 /// # Examples
nhamebe80972014-07-17 23:19:51207 ///
208 /// ```rust
209 /// use std::collections::RingBuf;
210 ///
211 /// let mut buf = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:03212 /// buf.push_back(3);
Alexis Beingessnercf3b2e42014-11-06 17:24:47213 /// buf.push_back(4);
214 /// buf.push_back(5);
215 /// match buf.get_mut(1) {
216 /// None => {}
217 /// Some(elem) => {
218 /// *elem = 7;
219 /// }
220 /// }
221 ///
P1startfd10d202014-08-02 06:39:39222 /// assert_eq!(buf[1], 7);
nhamebe80972014-07-17 23:19:51223 /// ```
Brian Andersonb44ee372015-01-24 05:48:20224 #[stable(feature = "rust1", since = "1.0.0")]
Alexise250fe32015-02-05 02:17:19225 pub fn get_mut(&mut self, i: usize) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07226 if i < self.len() {
Colin Sherratt40191182014-11-12 01:22:07227 let idx = self.wrap_index(self.tail + i);
Alexise250fe32015-02-05 02:17:19228 unsafe { Some(&mut *self.ptr.offset(idx as isize)) }
Colin Sherratt7a666df2014-10-19 20:19:07229 } else {
230 None
Alexis Beingessnercf3b2e42014-11-06 17:24:47231 }
blake2-ppc70523712013-07-10 13:27:14232 }
233
P1startf2aa88c2014-08-04 10:48:39234 /// Swaps elements at indices `i` and `j`.
blake2-ppc57757a82013-09-26 07:19:26235 ///
236 /// `i` and `j` may be equal.
237 ///
P1startf2aa88c2014-08-04 10:48:39238 /// Fails if there is no element with either index.
nhamebe80972014-07-17 23:19:51239 ///
jbranchaudc09defa2014-12-09 05:28:07240 /// # Examples
nhamebe80972014-07-17 23:19:51241 ///
242 /// ```rust
243 /// use std::collections::RingBuf;
244 ///
245 /// let mut buf = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:03246 /// buf.push_back(3);
Alexis Beingessnercf3b2e42014-11-06 17:24:47247 /// buf.push_back(4);
248 /// buf.push_back(5);
nhamebe80972014-07-17 23:19:51249 /// buf.swap(0, 2);
P1startfd10d202014-08-02 06:39:39250 /// assert_eq!(buf[0], 5);
251 /// assert_eq!(buf[2], 3);
nhamebe80972014-07-17 23:19:51252 /// ```
Brian Andersonb44ee372015-01-24 05:48:20253 #[stable(feature = "rust1", since = "1.0.0")]
Alexise250fe32015-02-05 02:17:19254 pub fn swap(&mut self, i: usize, j: usize) {
blake2-ppc57757a82013-09-26 07:19:26255 assert!(i < self.len());
256 assert!(j < self.len());
Colin Sherratt40191182014-11-12 01:22:07257 let ri = self.wrap_index(self.tail + i);
258 let rj = self.wrap_index(self.tail + j);
Colin Sherratt7a666df2014-10-19 20:19:07259 unsafe {
Alexise250fe32015-02-05 02:17:19260 ptr::swap(self.ptr.offset(ri as isize), self.ptr.offset(rj as isize))
Colin Sherratt7a666df2014-10-19 20:19:07261 }
blake2-ppc70523712013-07-10 13:27:14262 }
263
Alexis Beingessnercf3b2e42014-11-06 17:24:47264 /// Returns the number of elements the `RingBuf` can hold without
265 /// reallocating.
266 ///
jbranchaudc09defa2014-12-09 05:28:07267 /// # Examples
Alexis Beingessnercf3b2e42014-11-06 17:24:47268 ///
269 /// ```
270 /// use std::collections::RingBuf;
271 ///
Tobias Bucher7f64fe42015-01-25 21:05:03272 /// let buf: RingBuf<i32> = RingBuf::with_capacity(10);
Colin Sherratt7a666df2014-10-19 20:19:07273 /// assert!(buf.capacity() >= 10);
Alexis Beingessnercf3b2e42014-11-06 17:24:47274 /// ```
275 #[inline]
Brian Andersonb44ee372015-01-24 05:48:20276 #[stable(feature = "rust1", since = "1.0.0")]
Alexise250fe32015-02-05 02:17:19277 pub fn capacity(&self) -> usize { self.cap - 1 }
Tim Chevalier77de84b2013-05-27 18:47:38278
Alexis Beingessnercf3b2e42014-11-06 17:24:47279 /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
280 /// given `RingBuf`. Does nothing if the capacity is already sufficient.
Tim Chevalier77de84b2013-05-27 18:47:38281 ///
Alexis Beingessnercf3b2e42014-11-06 17:24:47282 /// Note that the allocator may give the collection more space than it requests. Therefore
283 /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
284 /// insertions are expected.
285 ///
286 /// # Panics
287 ///
Alexise250fe32015-02-05 02:17:19288 /// Panics if the new capacity overflows `usize`.
Alexis Beingessnercf3b2e42014-11-06 17:24:47289 ///
jbranchaudc09defa2014-12-09 05:28:07290 /// # Examples
Alexis Beingessnercf3b2e42014-11-06 17:24:47291 ///
292 /// ```
293 /// use std::collections::RingBuf;
294 ///
Tobias Bucher7f64fe42015-01-25 21:05:03295 /// let mut buf: RingBuf<i32> = vec![1].into_iter().collect();
Alexis Beingessnercf3b2e42014-11-06 17:24:47296 /// buf.reserve_exact(10);
297 /// assert!(buf.capacity() >= 11);
298 /// ```
Brian Andersonb44ee372015-01-24 05:48:20299 #[stable(feature = "rust1", since = "1.0.0")]
Alexise250fe32015-02-05 02:17:19300 pub fn reserve_exact(&mut self, additional: usize) {
Colin Sherratt7a666df2014-10-19 20:19:07301 self.reserve(additional);
Alexis Beingessnercf3b2e42014-11-06 17:24:47302 }
303
304 /// Reserves capacity for at least `additional` more elements to be inserted in the given
305 /// `Ringbuf`. The collection may reserve more space to avoid frequent reallocations.
306 ///
307 /// # Panics
308 ///
Alexise250fe32015-02-05 02:17:19309 /// Panics if the new capacity overflows `usize`.
Alexis Beingessnercf3b2e42014-11-06 17:24:47310 ///
jbranchaudc09defa2014-12-09 05:28:07311 /// # Examples
Alexis Beingessnercf3b2e42014-11-06 17:24:47312 ///
313 /// ```
314 /// use std::collections::RingBuf;
315 ///
Tobias Bucher7f64fe42015-01-25 21:05:03316 /// let mut buf: RingBuf<i32> = vec![1].into_iter().collect();
Alexis Beingessnercf3b2e42014-11-06 17:24:47317 /// buf.reserve(10);
318 /// assert!(buf.capacity() >= 11);
319 /// ```
Brian Andersonb44ee372015-01-24 05:48:20320 #[stable(feature = "rust1", since = "1.0.0")]
Alexise250fe32015-02-05 02:17:19321 pub fn reserve(&mut self, additional: usize) {
Colin Sherratt7a666df2014-10-19 20:19:07322 let new_len = self.len() + additional;
323 assert!(new_len + 1 > self.len(), "capacity overflow");
324 if new_len > self.capacity() {
Colin Sherratt6277e3b2014-11-14 09:21:44325 let count = (new_len + 1).next_power_of_two();
Colin Sherratt7a666df2014-10-19 20:19:07326 assert!(count >= new_len + 1);
327
328 if mem::size_of::<T>() != 0 {
329 let old = self.cap * mem::size_of::<T>();
Colin Sherratt6277e3b2014-11-14 09:21:44330 let new = count.checked_mul(mem::size_of::<T>())
Colin Sherratt7a666df2014-10-19 20:19:07331 .expect("capacity overflow");
332 unsafe {
333 self.ptr = heap::reallocate(self.ptr as *mut u8,
334 old,
335 new,
336 mem::min_align_of::<T>()) as *mut T;
Colin Sherrattba24e332014-11-10 03:34:53337 if self.ptr.is_null() { ::alloc::oom() }
Colin Sherratt7a666df2014-10-19 20:19:07338 }
339 }
340
341 // Move the shortest contiguous section of the ring buffer
342 // T H
343 // [o o o o o o o . ]
344 // T H
345 // A [o o o o o o o . . . . . . . . . ]
346 // H T
347 // [o o . o o o o o ]
348 // T H
349 // B [. . . o o o o o o o . . . . . . ]
350 // H T
351 // [o o o o o . o o ]
352 // H T
353 // C [o o o o o . . . . . . . . . o o ]
354
355 let oldcap = self.cap;
356 self.cap = count;
357
358 if self.tail <= self.head { // A
359 // Nop
360 } else if self.head < oldcap - self.tail { // B
361 unsafe {
Piotr Czarnecki156a1c32015-01-05 14:48:58362 self.copy_nonoverlapping(oldcap, 0, self.head);
Colin Sherratt7a666df2014-10-19 20:19:07363 }
364 self.head += oldcap;
Colin Sherratt4cae9ad2014-11-11 02:16:29365 debug_assert!(self.head > self.tail);
Colin Sherratt7a666df2014-10-19 20:19:07366 } else { // C
Piotr Czarnecki156a1c32015-01-05 14:48:58367 let new_tail = count - (oldcap - self.tail);
Colin Sherratt7a666df2014-10-19 20:19:07368 unsafe {
Piotr Czarnecki156a1c32015-01-05 14:48:58369 self.copy_nonoverlapping(new_tail, self.tail, oldcap - self.tail);
Colin Sherratt7a666df2014-10-19 20:19:07370 }
Piotr Czarnecki156a1c32015-01-05 14:48:58371 self.tail = new_tail;
Colin Sherratt4cae9ad2014-11-11 02:16:29372 debug_assert!(self.head < self.tail);
Colin Sherratt7a666df2014-10-19 20:19:07373 }
Colin Sherratt4cae9ad2014-11-11 02:16:29374 debug_assert!(self.head < self.cap);
375 debug_assert!(self.tail < self.cap);
Colin Sherratt40191182014-11-12 01:22:07376 debug_assert!(self.cap.count_ones() == 1);
Colin Sherratt7a666df2014-10-19 20:19:07377 }
Tim Chevalier77de84b2013-05-27 18:47:38378 }
Jed Estep4f7a7422013-06-25 19:08:47379
Piotr Czarnecki156a1c32015-01-05 14:48:58380 /// Shrinks the capacity of the ringbuf as much as possible.
381 ///
382 /// It will drop down as close as possible to the length but the allocator may still inform the
383 /// ringbuf that there is space for a few more elements.
384 ///
385 /// # Examples
386 ///
387 /// ```
388 /// use std::collections::RingBuf;
389 ///
390 /// let mut buf = RingBuf::with_capacity(15);
Alexise15538d2015-02-06 18:57:13391 /// buf.extend(0..4);
Piotr Czarnecki156a1c32015-01-05 14:48:58392 /// assert_eq!(buf.capacity(), 15);
393 /// buf.shrink_to_fit();
394 /// assert!(buf.capacity() >= 4);
395 /// ```
396 pub fn shrink_to_fit(&mut self) {
397 // +1 since the ringbuffer always leaves one space empty
398 // len + 1 can't overflow for an existing, well-formed ringbuf.
399 let target_cap = cmp::max(self.len() + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
400 if target_cap < self.cap {
401 // There are three cases of interest:
402 // All elements are out of desired bounds
403 // Elements are contiguous, and head is out of desired bounds
404 // Elements are discontiguous, and tail is out of desired bounds
405 //
406 // At all other times, element positions are unaffected.
407 //
408 // Indicates that elements at the head should be moved.
409 let head_outside = self.head == 0 || self.head >= target_cap;
410 // Move elements from out of desired bounds (positions after target_cap)
411 if self.tail >= target_cap && head_outside {
412 // T H
413 // [. . . . . . . . o o o o o o o . ]
414 // T H
415 // [o o o o o o o . ]
416 unsafe {
417 self.copy_nonoverlapping(0, self.tail, self.len());
418 }
419 self.head = self.len();
420 self.tail = 0;
421 } else if self.tail != 0 && self.tail < target_cap && head_outside {
422 // T H
423 // [. . . o o o o o o o . . . . . . ]
424 // H T
425 // [o o . o o o o o ]
426 let len = self.wrap_index(self.head - target_cap);
427 unsafe {
428 self.copy_nonoverlapping(0, target_cap, len);
429 }
430 self.head = len;
431 debug_assert!(self.head < self.tail);
432 } else if self.tail >= target_cap {
433 // H T
434 // [o o o o o . . . . . . . . . o o ]
435 // H T
436 // [o o o o o . o o ]
437 debug_assert!(self.wrap_index(self.head - 1) < target_cap);
438 let len = self.cap - self.tail;
439 let new_tail = target_cap - len;
440 unsafe {
441 self.copy_nonoverlapping(new_tail, self.tail, len);
442 }
443 self.tail = new_tail;
444 debug_assert!(self.head < self.tail);
445 }
446
447 if mem::size_of::<T>() != 0 {
448 let old = self.cap * mem::size_of::<T>();
449 let new_size = target_cap * mem::size_of::<T>();
450 unsafe {
451 self.ptr = heap::reallocate(self.ptr as *mut u8,
452 old,
453 new_size,
454 mem::min_align_of::<T>()) as *mut T;
455 if self.ptr.is_null() { ::alloc::oom() }
456 }
457 }
458 self.cap = target_cap;
459 debug_assert!(self.head < self.cap);
460 debug_assert!(self.tail < self.cap);
461 debug_assert!(self.cap.count_ones() == 1);
462 }
463 }
464
465 /// Shorten a ringbuf, dropping excess elements from the back.
466 ///
467 /// If `len` is greater than the ringbuf's current length, this has no
468 /// effect.
469 ///
470 /// # Examples
471 ///
472 /// ```
473 /// use std::collections::RingBuf;
474 ///
475 /// let mut buf = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:03476 /// buf.push_back(5);
477 /// buf.push_back(10);
Piotr Czarnecki156a1c32015-01-05 14:48:58478 /// buf.push_back(15);
479 /// buf.truncate(1);
480 /// assert_eq!(buf.len(), 1);
481 /// assert_eq!(Some(&5), buf.get(0));
482 /// ```
Brian Andersoncd6d9ea2015-01-23 02:22:03483 #[unstable(feature = "collections",
Brian Anderson94ca8a32015-01-13 02:40:19484 reason = "matches collection reform specification; waiting on panic semantics")]
Alexise250fe32015-02-05 02:17:19485 pub fn truncate(&mut self, len: usize) {
Jorge Aparicioefc97a52015-01-26 21:05:07486 for _ in len..self.len() {
Piotr Czarnecki156a1c32015-01-05 14:48:58487 self.pop_back();
488 }
489 }
490
P1startf2aa88c2014-08-04 10:48:39491 /// Returns a front-to-back iterator.
nhamebe80972014-07-17 23:19:51492 ///
jbranchaudc09defa2014-12-09 05:28:07493 /// # Examples
nhamebe80972014-07-17 23:19:51494 ///
495 /// ```rust
496 /// use std::collections::RingBuf;
497 ///
498 /// let mut buf = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:03499 /// buf.push_back(5);
Alexis Beingessnercf3b2e42014-11-06 17:24:47500 /// buf.push_back(3);
501 /// buf.push_back(4);
Nick Cameron52ef4622014-08-06 09:59:40502 /// let b: &[_] = &[&5, &3, &4];
Tobias Bucher7f64fe42015-01-25 21:05:03503 /// assert_eq!(buf.iter().collect::<Vec<&i32>>().as_slice(), b);
nhamebe80972014-07-17 23:19:51504 /// ```
Brian Andersonb44ee372015-01-24 05:48:20505 #[stable(feature = "rust1", since = "1.0.0")]
Florian Wilkensf8cfd242014-12-19 20:52:10506 pub fn iter(&self) -> Iter<T> {
507 Iter {
Colin Sherratt7a666df2014-10-19 20:19:07508 tail: self.tail,
509 head: self.head,
510 ring: unsafe { self.buffer_as_slice() }
511 }
blake2-ppc3385e792013-07-15 23:13:26512 }
513
Andrew Wagner8fcc8322014-12-15 09:22:49514 /// Returns a front-to-back iterator that returns mutable references.
nhamebe80972014-07-17 23:19:51515 ///
jbranchaudc09defa2014-12-09 05:28:07516 /// # Examples
nhamebe80972014-07-17 23:19:51517 ///
518 /// ```rust
519 /// use std::collections::RingBuf;
520 ///
521 /// let mut buf = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:03522 /// buf.push_back(5);
Alexis Beingessnercf3b2e42014-11-06 17:24:47523 /// buf.push_back(3);
524 /// buf.push_back(4);
Aaron Turonfc525ee2014-09-15 03:27:36525 /// for num in buf.iter_mut() {
nhamebe80972014-07-17 23:19:51526 /// *num = *num - 2;
527 /// }
Nick Cameron52ef4622014-08-06 09:59:40528 /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
Tobias Bucher7f64fe42015-01-25 21:05:03529 /// assert_eq!(&buf.iter_mut().collect::<Vec<&mut i32>>()[], b);
nhamebe80972014-07-17 23:19:51530 /// ```
Brian Andersonb44ee372015-01-24 05:48:20531 #[stable(feature = "rust1", since = "1.0.0")]
Alexis1420ceb2015-02-05 18:48:20532 pub fn iter_mut(&mut self) -> IterMut<T> {
Florian Wilkensf8cfd242014-12-19 20:52:10533 IterMut {
Colin Sherratt7a666df2014-10-19 20:19:07534 tail: self.tail,
535 head: self.head,
536 cap: self.cap,
537 ptr: self.ptr,
Alexis1420ceb2015-02-05 18:48:20538 marker: marker::ContravariantLifetime,
Niko Matsakisbc4164d2013-11-16 22:29:39539 }
Jed Estep4f7a7422013-06-25 19:08:47540 }
Alex Crichton21ac9852014-10-30 20:43:24541
Alexis Beingessner865c2db2014-11-23 02:34:11542 /// Consumes the list into an iterator yielding elements by value.
Brian Andersonb44ee372015-01-24 05:48:20543 #[stable(feature = "rust1", since = "1.0.0")]
Florian Wilkensf8cfd242014-12-19 20:52:10544 pub fn into_iter(self) -> IntoIter<T> {
545 IntoIter {
Alexis Beingessner865c2db2014-11-23 02:34:11546 inner: self,
547 }
548 }
549
Clark Gaebel525f65e2014-12-16 04:01:58550 /// Returns a pair of slices which contain, in order, the contents of the
551 /// `RingBuf`.
552 #[inline]
Brian Andersoncd6d9ea2015-01-23 02:22:03553 #[unstable(feature = "collections",
Brian Anderson94ca8a32015-01-13 02:40:19554 reason = "matches collection reform specification, waiting for dust to settle")]
Alexis1420ceb2015-02-05 18:48:20555 pub fn as_slices(&self) -> (&[T], &[T]) {
Clark Gaebel525f65e2014-12-16 04:01:58556 unsafe {
557 let contiguous = self.is_contiguous();
558 let buf = self.buffer_as_slice();
559 if contiguous {
560 let (empty, buf) = buf.split_at(0);
Jorge Aparicio517f1cc2015-01-07 16:58:31561 (&buf[self.tail..self.head], empty)
Clark Gaebel525f65e2014-12-16 04:01:58562 } else {
563 let (mid, right) = buf.split_at(self.tail);
564 let (left, _) = mid.split_at(self.head);
565 (right, left)
566 }
567 }
568 }
569
570 /// Returns a pair of slices which contain, in order, the contents of the
571 /// `RingBuf`.
572 #[inline]
Brian Andersoncd6d9ea2015-01-23 02:22:03573 #[unstable(feature = "collections",
Brian Anderson94ca8a32015-01-13 02:40:19574 reason = "matches collection reform specification, waiting for dust to settle")]
Alexis1420ceb2015-02-05 18:48:20575 pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
Clark Gaebel525f65e2014-12-16 04:01:58576 unsafe {
577 let contiguous = self.is_contiguous();
578 let head = self.head;
579 let tail = self.tail;
580 let buf = self.buffer_as_mut_slice();
581
582 if contiguous {
583 let (empty, buf) = buf.split_at_mut(0);
Aaron Turona506d4c2015-01-18 00:15:52584 (&mut buf[tail .. head], empty)
Clark Gaebel525f65e2014-12-16 04:01:58585 } else {
586 let (mid, right) = buf.split_at_mut(tail);
587 let (left, _) = mid.split_at_mut(head);
588
589 (right, left)
590 }
591 }
592 }
593
Alex Crichton21ac9852014-10-30 20:43:24594 /// Returns the number of elements in the `RingBuf`.
595 ///
jbranchaudc09defa2014-12-09 05:28:07596 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24597 ///
598 /// ```
599 /// use std::collections::RingBuf;
600 ///
601 /// let mut v = RingBuf::new();
602 /// assert_eq!(v.len(), 0);
Tobias Bucher7f64fe42015-01-25 21:05:03603 /// v.push_back(1);
Alex Crichton21ac9852014-10-30 20:43:24604 /// assert_eq!(v.len(), 1);
605 /// ```
Brian Andersonb44ee372015-01-24 05:48:20606 #[stable(feature = "rust1", since = "1.0.0")]
Alexise250fe32015-02-05 02:17:19607 pub fn len(&self) -> usize { count(self.tail, self.head, self.cap) }
Alex Crichton21ac9852014-10-30 20:43:24608
609 /// Returns true if the buffer contains no elements
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 v = RingBuf::new();
617 /// assert!(v.is_empty());
Tobias Bucher7f64fe42015-01-25 21:05:03618 /// v.push_front(1);
Alex Crichton21ac9852014-10-30 20:43:24619 /// assert!(!v.is_empty());
620 /// ```
Brian Andersonb44ee372015-01-24 05:48:20621 #[stable(feature = "rust1", since = "1.0.0")]
Alex Crichton21ac9852014-10-30 20:43:24622 pub fn is_empty(&self) -> bool { self.len() == 0 }
623
Clark Gaebeld57f2592014-12-16 22:45:03624 /// Creates a draining iterator that clears the `RingBuf` and iterates over
625 /// the removed items from start to end.
626 ///
627 /// # Examples
628 ///
629 /// ```
630 /// use std::collections::RingBuf;
631 ///
632 /// let mut v = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:03633 /// v.push_back(1);
Clark Gaebeld57f2592014-12-16 22:45:03634 /// assert_eq!(v.drain().next(), Some(1));
635 /// assert!(v.is_empty());
636 /// ```
637 #[inline]
Brian Andersoncd6d9ea2015-01-23 02:22:03638 #[unstable(feature = "collections",
Brian Anderson94ca8a32015-01-13 02:40:19639 reason = "matches collection reform specification, waiting for dust to settle")]
Alexis Beingessner8dbaa712014-12-31 00:07:53640 pub fn drain(&mut self) -> Drain<T> {
Clark Gaebeld57f2592014-12-16 22:45:03641 Drain {
642 inner: self,
643 }
644 }
645
Alex Crichton21ac9852014-10-30 20:43:24646 /// Clears the buffer, removing all values.
647 ///
jbranchaudc09defa2014-12-09 05:28:07648 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24649 ///
650 /// ```
651 /// use std::collections::RingBuf;
652 ///
653 /// let mut v = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:03654 /// v.push_back(1);
Alex Crichton21ac9852014-10-30 20:43:24655 /// v.clear();
656 /// assert!(v.is_empty());
657 /// ```
Brian Andersonb44ee372015-01-24 05:48:20658 #[stable(feature = "rust1", since = "1.0.0")]
Clark Gaebeld57f2592014-12-16 22:45:03659 #[inline]
Alex Crichton21ac9852014-10-30 20:43:24660 pub fn clear(&mut self) {
Clark Gaebeld57f2592014-12-16 22:45:03661 self.drain();
Alex Crichton21ac9852014-10-30 20:43:24662 }
663
664 /// Provides a reference to the front element, or `None` if the sequence is
665 /// empty.
666 ///
jbranchaudc09defa2014-12-09 05:28:07667 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24668 ///
669 /// ```
670 /// use std::collections::RingBuf;
671 ///
672 /// let mut d = RingBuf::new();
673 /// assert_eq!(d.front(), None);
674 ///
Tobias Bucher7f64fe42015-01-25 21:05:03675 /// d.push_back(1);
676 /// d.push_back(2);
677 /// assert_eq!(d.front(), Some(&1));
Alex Crichton21ac9852014-10-30 20:43:24678 /// ```
Brian Andersonb44ee372015-01-24 05:48:20679 #[stable(feature = "rust1", since = "1.0.0")]
Alex Crichton21ac9852014-10-30 20:43:24680 pub fn front(&self) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07681 if !self.is_empty() { Some(&self[0]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24682 }
683
684 /// Provides a mutable reference to the front element, or `None` if the
685 /// sequence is empty.
686 ///
jbranchaudc09defa2014-12-09 05:28:07687 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24688 ///
689 /// ```
690 /// use std::collections::RingBuf;
691 ///
692 /// let mut d = RingBuf::new();
693 /// assert_eq!(d.front_mut(), None);
694 ///
Tobias Bucher7f64fe42015-01-25 21:05:03695 /// d.push_back(1);
696 /// d.push_back(2);
Alex Crichton21ac9852014-10-30 20:43:24697 /// match d.front_mut() {
Tobias Bucher7f64fe42015-01-25 21:05:03698 /// Some(x) => *x = 9,
Alex Crichton21ac9852014-10-30 20:43:24699 /// None => (),
700 /// }
Tobias Bucher7f64fe42015-01-25 21:05:03701 /// assert_eq!(d.front(), Some(&9));
Alex Crichton21ac9852014-10-30 20:43:24702 /// ```
Brian Andersonb44ee372015-01-24 05:48:20703 #[stable(feature = "rust1", since = "1.0.0")]
Alex Crichton21ac9852014-10-30 20:43:24704 pub fn front_mut(&mut self) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07705 if !self.is_empty() { Some(&mut self[0]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24706 }
707
708 /// Provides a reference to the back element, or `None` if the sequence is
709 /// empty.
710 ///
jbranchaudc09defa2014-12-09 05:28:07711 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24712 ///
713 /// ```
714 /// use std::collections::RingBuf;
715 ///
716 /// let mut d = RingBuf::new();
717 /// assert_eq!(d.back(), None);
718 ///
Tobias Bucher7f64fe42015-01-25 21:05:03719 /// d.push_back(1);
720 /// d.push_back(2);
721 /// assert_eq!(d.back(), Some(&2));
Alex Crichton21ac9852014-10-30 20:43:24722 /// ```
Brian Andersonb44ee372015-01-24 05:48:20723 #[stable(feature = "rust1", since = "1.0.0")]
Alex Crichton21ac9852014-10-30 20:43:24724 pub fn back(&self) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07725 if !self.is_empty() { Some(&self[self.len() - 1]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24726 }
727
728 /// Provides a mutable reference to the back element, or `None` if the
729 /// sequence is empty.
730 ///
jbranchaudc09defa2014-12-09 05:28:07731 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24732 ///
733 /// ```
734 /// use std::collections::RingBuf;
735 ///
736 /// let mut d = RingBuf::new();
737 /// assert_eq!(d.back(), None);
738 ///
Tobias Bucher7f64fe42015-01-25 21:05:03739 /// d.push_back(1);
740 /// d.push_back(2);
Alex Crichton21ac9852014-10-30 20:43:24741 /// match d.back_mut() {
Tobias Bucher7f64fe42015-01-25 21:05:03742 /// Some(x) => *x = 9,
Alex Crichton21ac9852014-10-30 20:43:24743 /// None => (),
744 /// }
Tobias Bucher7f64fe42015-01-25 21:05:03745 /// assert_eq!(d.back(), Some(&9));
Alex Crichton21ac9852014-10-30 20:43:24746 /// ```
Brian Andersonb44ee372015-01-24 05:48:20747 #[stable(feature = "rust1", since = "1.0.0")]
Alex Crichton21ac9852014-10-30 20:43:24748 pub fn back_mut(&mut self) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07749 let len = self.len();
750 if !self.is_empty() { Some(&mut self[len - 1]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24751 }
752
753 /// Removes the first element and returns it, or `None` if the sequence is
754 /// empty.
755 ///
jbranchaudc09defa2014-12-09 05:28:07756 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24757 ///
758 /// ```
759 /// use std::collections::RingBuf;
760 ///
761 /// let mut d = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:03762 /// d.push_back(1);
763 /// d.push_back(2);
Alex Crichton21ac9852014-10-30 20:43:24764 ///
Tobias Bucher7f64fe42015-01-25 21:05:03765 /// assert_eq!(d.pop_front(), Some(1));
766 /// assert_eq!(d.pop_front(), Some(2));
Alex Crichton21ac9852014-10-30 20:43:24767 /// assert_eq!(d.pop_front(), None);
768 /// ```
Brian Andersonb44ee372015-01-24 05:48:20769 #[stable(feature = "rust1", since = "1.0.0")]
Alex Crichton21ac9852014-10-30 20:43:24770 pub fn pop_front(&mut self) -> Option<T> {
Colin Sherratt7a666df2014-10-19 20:19:07771 if self.is_empty() {
772 None
773 } else {
774 let tail = self.tail;
Colin Sherratt40191182014-11-12 01:22:07775 self.tail = self.wrap_index(self.tail + 1);
Colin Sherratt7a666df2014-10-19 20:19:07776 unsafe { Some(self.buffer_read(tail)) }
Alex Crichton21ac9852014-10-30 20:43:24777 }
Alex Crichton21ac9852014-10-30 20:43:24778 }
779
780 /// Inserts an element first in the sequence.
781 ///
jbranchaudc09defa2014-12-09 05:28:07782 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24783 ///
784 /// ```
785 /// use std::collections::RingBuf;
786 ///
787 /// let mut d = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:03788 /// d.push_front(1);
789 /// d.push_front(2);
790 /// assert_eq!(d.front(), Some(&2));
Alex Crichton21ac9852014-10-30 20:43:24791 /// ```
Brian Andersonb44ee372015-01-24 05:48:20792 #[stable(feature = "rust1", since = "1.0.0")]
Alex Crichton21ac9852014-10-30 20:43:24793 pub fn push_front(&mut self, t: T) {
Colin Sherratt4cae9ad2014-11-11 02:16:29794 if self.is_full() {
795 self.reserve(1);
796 debug_assert!(!self.is_full());
797 }
Colin Sherratt7a666df2014-10-19 20:19:07798
Colin Sherratt40191182014-11-12 01:22:07799 self.tail = self.wrap_index(self.tail - 1);
Colin Sherratt7a666df2014-10-19 20:19:07800 let tail = self.tail;
801 unsafe { self.buffer_write(tail, t); }
Alex Crichton21ac9852014-10-30 20:43:24802 }
803
804 /// Appends an element to the back of a buffer
805 ///
jbranchaudc09defa2014-12-09 05:28:07806 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24807 ///
808 /// ```rust
809 /// use std::collections::RingBuf;
810 ///
811 /// let mut buf = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:03812 /// buf.push_back(1);
Alexis Beingessnercf3b2e42014-11-06 17:24:47813 /// buf.push_back(3);
Alex Crichton21ac9852014-10-30 20:43:24814 /// assert_eq!(3, *buf.back().unwrap());
815 /// ```
Brian Andersonb44ee372015-01-24 05:48:20816 #[stable(feature = "rust1", since = "1.0.0")]
Alexis Beingessnercf3b2e42014-11-06 17:24:47817 pub fn push_back(&mut self, t: T) {
Colin Sherratt4cae9ad2014-11-11 02:16:29818 if self.is_full() {
819 self.reserve(1);
820 debug_assert!(!self.is_full());
821 }
Colin Sherratt7a666df2014-10-19 20:19:07822
823 let head = self.head;
Colin Sherratt40191182014-11-12 01:22:07824 self.head = self.wrap_index(self.head + 1);
Colin Sherratt7a666df2014-10-19 20:19:07825 unsafe { self.buffer_write(head, t) }
Alex Crichton21ac9852014-10-30 20:43:24826 }
827
828 /// Removes the last element from a buffer and returns it, or `None` if
829 /// it is empty.
830 ///
jbranchaudc09defa2014-12-09 05:28:07831 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24832 ///
833 /// ```rust
834 /// use std::collections::RingBuf;
835 ///
836 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47837 /// assert_eq!(buf.pop_back(), None);
Tobias Bucher7f64fe42015-01-25 21:05:03838 /// buf.push_back(1);
Alexis Beingessnercf3b2e42014-11-06 17:24:47839 /// buf.push_back(3);
840 /// assert_eq!(buf.pop_back(), Some(3));
Alex Crichton21ac9852014-10-30 20:43:24841 /// ```
Brian Andersonb44ee372015-01-24 05:48:20842 #[stable(feature = "rust1", since = "1.0.0")]
Alexis Beingessnercf3b2e42014-11-06 17:24:47843 pub fn pop_back(&mut self) -> Option<T> {
Colin Sherratt7a666df2014-10-19 20:19:07844 if self.is_empty() {
Alex Crichton21ac9852014-10-30 20:43:24845 None
Colin Sherratt7a666df2014-10-19 20:19:07846 } else {
Colin Sherratt40191182014-11-12 01:22:07847 self.head = self.wrap_index(self.head - 1);
Colin Sherratt7a666df2014-10-19 20:19:07848 let head = self.head;
849 unsafe { Some(self.buffer_read(head)) }
Alex Crichton21ac9852014-10-30 20:43:24850 }
851 }
Matt Murphy40f28c72014-12-03 17:12:30852
Clark Gaebel525f65e2014-12-16 04:01:58853 #[inline]
854 fn is_contiguous(&self) -> bool {
855 self.tail <= self.head
856 }
857
Piotr Czarnecki156a1c32015-01-05 14:48:58858 /// Removes an element from anywhere in the ringbuf and returns it, replacing it with the last
859 /// element.
860 ///
861 /// This does not preserve ordering, but is O(1).
862 ///
863 /// Returns `None` if `index` is out of bounds.
864 ///
865 /// # Examples
866 ///
867 /// ```
868 /// use std::collections::RingBuf;
869 ///
870 /// let mut buf = RingBuf::new();
871 /// assert_eq!(buf.swap_back_remove(0), None);
Tobias Bucher7f64fe42015-01-25 21:05:03872 /// buf.push_back(5);
Piotr Czarnecki156a1c32015-01-05 14:48:58873 /// buf.push_back(99);
874 /// buf.push_back(15);
875 /// buf.push_back(20);
876 /// buf.push_back(10);
877 /// assert_eq!(buf.swap_back_remove(1), Some(99));
878 /// ```
Brian Andersoncd6d9ea2015-01-23 02:22:03879 #[unstable(feature = "collections",
Brian Anderson94ca8a32015-01-13 02:40:19880 reason = "the naming of this function may be altered")]
Alexise250fe32015-02-05 02:17:19881 pub fn swap_back_remove(&mut self, index: usize) -> Option<T> {
Piotr Czarnecki156a1c32015-01-05 14:48:58882 let length = self.len();
883 if length > 0 && index < length - 1 {
884 self.swap(index, length - 1);
885 } else if index >= length {
886 return None;
887 }
888 self.pop_back()
889 }
890
891 /// Removes an element from anywhere in the ringbuf and returns it, replacing it with the first
892 /// element.
893 ///
894 /// This does not preserve ordering, but is O(1).
895 ///
896 /// Returns `None` if `index` is out of bounds.
897 ///
898 /// # Examples
899 ///
900 /// ```
901 /// use std::collections::RingBuf;
902 ///
903 /// let mut buf = RingBuf::new();
904 /// assert_eq!(buf.swap_front_remove(0), None);
Tobias Bucher7f64fe42015-01-25 21:05:03905 /// buf.push_back(15);
Piotr Czarnecki156a1c32015-01-05 14:48:58906 /// buf.push_back(5);
907 /// buf.push_back(10);
908 /// buf.push_back(99);
Tobias Bucher7f64fe42015-01-25 21:05:03909 /// buf.push_back(20);
Piotr Czarnecki156a1c32015-01-05 14:48:58910 /// assert_eq!(buf.swap_front_remove(3), Some(99));
911 /// ```
Brian Andersoncd6d9ea2015-01-23 02:22:03912 #[unstable(feature = "collections",
Brian Anderson94ca8a32015-01-13 02:40:19913 reason = "the naming of this function may be altered")]
Alexise250fe32015-02-05 02:17:19914 pub fn swap_front_remove(&mut self, index: usize) -> Option<T> {
Piotr Czarnecki156a1c32015-01-05 14:48:58915 let length = self.len();
916 if length > 0 && index < length && index != 0 {
917 self.swap(index, 0);
918 } else if index >= length {
919 return None;
920 }
921 self.pop_front()
922 }
923
Matt Murphy40f28c72014-12-03 17:12:30924 /// Inserts an element at position `i` within the ringbuf. Whichever
925 /// end is closer to the insertion point will be moved to make room,
926 /// and all the affected elements will be moved to new positions.
927 ///
928 /// # Panics
929 ///
930 /// Panics if `i` is greater than ringbuf's length
931 ///
Piotr Czarnecki156a1c32015-01-05 14:48:58932 /// # Examples
Matt Murphy40f28c72014-12-03 17:12:30933 /// ```rust
934 /// use std::collections::RingBuf;
935 ///
936 /// let mut buf = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:03937 /// buf.push_back(10);
Matt Murphy40f28c72014-12-03 17:12:30938 /// buf.push_back(12);
939 /// buf.insert(1,11);
940 /// assert_eq!(Some(&11), buf.get(1));
941 /// ```
Alexise250fe32015-02-05 02:17:19942 pub fn insert(&mut self, i: usize, t: T) {
Matt Murphy40f28c72014-12-03 17:12:30943 assert!(i <= self.len(), "index out of bounds");
944 if self.is_full() {
945 self.reserve(1);
946 debug_assert!(!self.is_full());
947 }
948
949 // Move the least number of elements in the ring buffer and insert
950 // the given object
951 //
952 // At most len/2 - 1 elements will be moved. O(min(n, n-i))
953 //
954 // There are three main cases:
955 // Elements are contiguous
956 // - special case when tail is 0
957 // Elements are discontiguous and the insert is in the tail section
958 // Elements are discontiguous and the insert is in the head section
959 //
960 // For each of those there are two more cases:
961 // Insert is closer to tail
962 // Insert is closer to head
963 //
964 // Key: H - self.head
965 // T - self.tail
966 // o - Valid element
967 // I - Insertion element
968 // A - The element that should be after the insertion point
969 // M - Indicates element was moved
970
971 let idx = self.wrap_index(self.tail + i);
972
973 let distance_to_tail = i;
974 let distance_to_head = self.len() - i;
975
Clark Gaebel525f65e2014-12-16 04:01:58976 let contiguous = self.is_contiguous();
Matt Murphy40f28c72014-12-03 17:12:30977
978 match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
979 (true, true, _) if i == 0 => {
980 // push_front
981 //
982 // T
983 // I H
984 // [A o o o o o o . . . . . . . . .]
985 //
986 // H T
987 // [A o o o o o o o . . . . . I]
988 //
989
990 self.tail = self.wrap_index(self.tail - 1);
991 },
Piotr Czarnecki59d41532014-12-16 23:37:55992 (true, true, _) => unsafe {
Matt Murphy40f28c72014-12-03 17:12:30993 // contiguous, insert closer to tail:
994 //
995 // T I H
996 // [. . . o o A o o o o . . . . . .]
997 //
998 // T H
999 // [. . o o I A o o o o . . . . . .]
1000 // M M
1001 //
1002 // contiguous, insert closer to tail and tail is 0:
1003 //
1004 //
1005 // T I H
1006 // [o o A o o o o . . . . . . . . .]
1007 //
1008 // H T
1009 // [o I A o o o o o . . . . . . . o]
1010 // M M
1011
Piotr Czarnecki59d41532014-12-16 23:37:551012 let new_tail = self.wrap_index(self.tail - 1);
Matt Murphy40f28c72014-12-03 17:12:301013
Piotr Czarnecki59d41532014-12-16 23:37:551014 self.copy(new_tail, self.tail, 1);
1015 // Already moved the tail, so we only copy `i - 1` elements.
1016 self.copy(self.tail, self.tail + 1, i - 1);
1017
1018 self.tail = new_tail;
Matt Murphy40f28c72014-12-03 17:12:301019 },
Piotr Czarnecki59d41532014-12-16 23:37:551020 (true, false, _) => unsafe {
Matt Murphy40f28c72014-12-03 17:12:301021 // contiguous, insert closer to head:
1022 //
1023 // T I H
1024 // [. . . o o o o A o o . . . . . .]
1025 //
1026 // T H
1027 // [. . . o o o o I A o o . . . . .]
1028 // M M M
1029
Piotr Czarnecki59d41532014-12-16 23:37:551030 self.copy(idx + 1, idx, self.head - idx);
Matt Murphy40f28c72014-12-03 17:12:301031 self.head = self.wrap_index(self.head + 1);
Matt Murphy40f28c72014-12-03 17:12:301032 },
Piotr Czarnecki59d41532014-12-16 23:37:551033 (false, true, true) => unsafe {
1034 // discontiguous, insert closer to tail, tail section:
Matt Murphy40f28c72014-12-03 17:12:301035 //
1036 // H T I
1037 // [o o o o o o . . . . . o o A o o]
1038 //
1039 // H T
1040 // [o o o o o o . . . . o o I A o o]
1041 // M M
1042
Piotr Czarnecki59d41532014-12-16 23:37:551043 self.copy(self.tail - 1, self.tail, i);
1044 self.tail -= 1;
Matt Murphy40f28c72014-12-03 17:12:301045 },
Piotr Czarnecki59d41532014-12-16 23:37:551046 (false, false, true) => unsafe {
1047 // discontiguous, insert closer to head, tail section:
Matt Murphy40f28c72014-12-03 17:12:301048 //
1049 // H T I
1050 // [o o . . . . . . . o o o o o A o]
1051 //
1052 // H T
1053 // [o o o . . . . . . o o o o o I A]
1054 // M M M M
1055
Matt Murphy40f28c72014-12-03 17:12:301056 // copy elements up to new head
Piotr Czarnecki59d41532014-12-16 23:37:551057 self.copy(1, 0, self.head);
Matt Murphy40f28c72014-12-03 17:12:301058
1059 // copy last element into empty spot at bottom of buffer
1060 self.copy(0, self.cap - 1, 1);
1061
1062 // move elements from idx to end forward not including ^ element
1063 self.copy(idx + 1, idx, self.cap - 1 - idx);
Piotr Czarnecki59d41532014-12-16 23:37:551064
1065 self.head += 1;
Matt Murphy40f28c72014-12-03 17:12:301066 },
Piotr Czarnecki59d41532014-12-16 23:37:551067 (false, true, false) if idx == 0 => unsafe {
1068 // discontiguous, insert is closer to tail, head section,
Matt Murphy40f28c72014-12-03 17:12:301069 // and is at index zero in the internal buffer:
1070 //
1071 // I H T
1072 // [A o o o o o o o o o . . . o o o]
1073 //
1074 // H T
1075 // [A o o o o o o o o o . . o o o I]
1076 // M M M
1077
Matt Murphy40f28c72014-12-03 17:12:301078 // copy elements up to new tail
Piotr Czarnecki59d41532014-12-16 23:37:551079 self.copy(self.tail - 1, self.tail, self.cap - self.tail);
Matt Murphy40f28c72014-12-03 17:12:301080
1081 // copy last element into empty spot at bottom of buffer
1082 self.copy(self.cap - 1, 0, 1);
Piotr Czarnecki59d41532014-12-16 23:37:551083
1084 self.tail -= 1;
Matt Murphy40f28c72014-12-03 17:12:301085 },
Piotr Czarnecki59d41532014-12-16 23:37:551086 (false, true, false) => unsafe {
1087 // discontiguous, insert closer to tail, head section:
Matt Murphy40f28c72014-12-03 17:12:301088 //
1089 // I H T
1090 // [o o o A o o o o o o . . . o o o]
1091 //
1092 // H T
1093 // [o o I A o o o o o o . . o o o o]
1094 // M M M M M M
1095
Matt Murphy40f28c72014-12-03 17:12:301096 // copy elements up to new tail
Piotr Czarnecki59d41532014-12-16 23:37:551097 self.copy(self.tail - 1, self.tail, self.cap - self.tail);
Matt Murphy40f28c72014-12-03 17:12:301098
1099 // copy last element into empty spot at bottom of buffer
1100 self.copy(self.cap - 1, 0, 1);
1101
1102 // move elements from idx-1 to end forward not including ^ element
1103 self.copy(0, 1, idx - 1);
Piotr Czarnecki59d41532014-12-16 23:37:551104
1105 self.tail -= 1;
1106 },
1107 (false, false, false) => unsafe {
1108 // discontiguous, insert closer to head, head section:
Matt Murphy40f28c72014-12-03 17:12:301109 //
1110 // I H T
1111 // [o o o o A o o . . . . . . o o o]
1112 //
1113 // H T
1114 // [o o o o I A o o . . . . . o o o]
1115 // M M M
1116
Piotr Czarnecki59d41532014-12-16 23:37:551117 self.copy(idx + 1, idx, self.head - idx);
1118 self.head += 1;
Matt Murphy40f28c72014-12-03 17:12:301119 }
1120 }
1121
1122 // tail might've been changed so we need to recalculate
1123 let new_idx = self.wrap_index(self.tail + i);
1124 unsafe {
1125 self.buffer_write(new_idx, t);
1126 }
1127 }
Piotr Czarnecki59d41532014-12-16 23:37:551128
1129 /// Removes and returns the element at position `i` from the ringbuf.
1130 /// Whichever end is closer to the removal point will be moved to make
1131 /// room, and all the affected elements will be moved to new positions.
1132 /// Returns `None` if `i` is out of bounds.
1133 ///
Piotr Czarnecki156a1c32015-01-05 14:48:581134 /// # Examples
Piotr Czarnecki59d41532014-12-16 23:37:551135 /// ```rust
1136 /// use std::collections::RingBuf;
1137 ///
1138 /// let mut buf = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:031139 /// buf.push_back(5);
1140 /// buf.push_back(10);
1141 /// buf.push_back(12);
Piotr Czarnecki59d41532014-12-16 23:37:551142 /// buf.push_back(15);
1143 /// buf.remove(2);
1144 /// assert_eq!(Some(&15), buf.get(2));
1145 /// ```
Brian Andersonb44ee372015-01-24 05:48:201146 #[stable(feature = "rust1", since = "1.0.0")]
Alexise250fe32015-02-05 02:17:191147 pub fn remove(&mut self, i: usize) -> Option<T> {
Piotr Czarnecki59d41532014-12-16 23:37:551148 if self.is_empty() || self.len() <= i {
1149 return None;
1150 }
1151
1152 // There are three main cases:
1153 // Elements are contiguous
1154 // Elements are discontiguous and the removal is in the tail section
1155 // Elements are discontiguous and the removal is in the head section
1156 // - special case when elements are technically contiguous,
1157 // but self.head = 0
1158 //
1159 // For each of those there are two more cases:
1160 // Insert is closer to tail
1161 // Insert is closer to head
1162 //
1163 // Key: H - self.head
1164 // T - self.tail
1165 // o - Valid element
1166 // x - Element marked for removal
1167 // R - Indicates element that is being removed
1168 // M - Indicates element was moved
1169
1170 let idx = self.wrap_index(self.tail + i);
1171
1172 let elem = unsafe {
1173 Some(self.buffer_read(idx))
1174 };
1175
1176 let distance_to_tail = i;
1177 let distance_to_head = self.len() - i;
1178
Piotr Czarnecki156a1c32015-01-05 14:48:581179 let contiguous = self.is_contiguous();
Piotr Czarnecki59d41532014-12-16 23:37:551180
1181 match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
1182 (true, true, _) => unsafe {
1183 // contiguous, remove closer to tail:
1184 //
1185 // T R H
1186 // [. . . o o x o o o o . . . . . .]
1187 //
1188 // T H
1189 // [. . . . o o o o o o . . . . . .]
1190 // M M
1191
1192 self.copy(self.tail + 1, self.tail, i);
1193 self.tail += 1;
1194 },
1195 (true, false, _) => unsafe {
1196 // contiguous, remove closer to head:
1197 //
1198 // T R H
1199 // [. . . o o o o x o o . . . . . .]
1200 //
1201 // T H
1202 // [. . . o o o o o o . . . . . . .]
1203 // M M
1204
1205 self.copy(idx, idx + 1, self.head - idx - 1);
1206 self.head -= 1;
1207 },
1208 (false, true, true) => unsafe {
1209 // discontiguous, remove closer to tail, tail section:
1210 //
1211 // H T R
1212 // [o o o o o o . . . . . o o x o o]
1213 //
1214 // H T
1215 // [o o o o o o . . . . . . o o o o]
1216 // M M
1217
1218 self.copy(self.tail + 1, self.tail, i);
1219 self.tail = self.wrap_index(self.tail + 1);
1220 },
1221 (false, false, false) => unsafe {
1222 // discontiguous, remove closer to head, head section:
1223 //
1224 // R H T
1225 // [o o o o x o o . . . . . . o o o]
1226 //
1227 // H T
1228 // [o o o o o o . . . . . . . o o o]
1229 // M M
1230
1231 self.copy(idx, idx + 1, self.head - idx - 1);
1232 self.head -= 1;
1233 },
1234 (false, false, true) => unsafe {
1235 // discontiguous, remove closer to head, tail section:
1236 //
1237 // H T R
1238 // [o o o . . . . . . o o o o o x o]
1239 //
1240 // H T
1241 // [o o . . . . . . . o o o o o o o]
1242 // M M M M
1243 //
1244 // or quasi-discontiguous, remove next to head, tail section:
1245 //
1246 // H T R
1247 // [. . . . . . . . . o o o o o x o]
1248 //
1249 // T H
1250 // [. . . . . . . . . o o o o o o .]
1251 // M
1252
1253 // draw in elements in the tail section
1254 self.copy(idx, idx + 1, self.cap - idx - 1);
1255
1256 // Prevents underflow.
1257 if self.head != 0 {
1258 // copy first element into empty spot
1259 self.copy(self.cap - 1, 0, 1);
1260
1261 // move elements in the head section backwards
1262 self.copy(0, 1, self.head - 1);
1263 }
1264
1265 self.head = self.wrap_index(self.head - 1);
1266 },
1267 (false, true, false) => unsafe {
1268 // discontiguous, remove closer to tail, head section:
1269 //
1270 // R H T
1271 // [o o x o o o o o o o . . . o o o]
1272 //
1273 // H T
1274 // [o o o o o o o o o o . . . . o o]
1275 // M M M M M
1276
1277 // draw in elements up to idx
1278 self.copy(1, 0, idx);
1279
1280 // copy last element into empty spot
1281 self.copy(0, self.cap - 1, 1);
1282
1283 // move elements from tail to end forward, excluding the last one
1284 self.copy(self.tail + 1, self.tail, self.cap - self.tail - 1);
1285
1286 self.tail = self.wrap_index(self.tail + 1);
1287 }
1288 }
1289
1290 return elem;
1291 }
Jed Estep4f7a7422013-06-25 19:08:471292}
1293
Piotr Czarnecki156a1c32015-01-05 14:48:581294impl<T: Clone> RingBuf<T> {
1295 /// Modifies the ringbuf in-place so that `len()` is equal to new_len,
1296 /// either by removing excess elements or by appending copies of a value to the back.
1297 ///
1298 /// # Examples
1299 ///
1300 /// ```
1301 /// use std::collections::RingBuf;
1302 ///
1303 /// let mut buf = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:031304 /// buf.push_back(5);
1305 /// buf.push_back(10);
Piotr Czarnecki156a1c32015-01-05 14:48:581306 /// buf.push_back(15);
1307 /// buf.resize(2, 0);
1308 /// buf.resize(6, 20);
1309 /// for (a, b) in [5, 10, 20, 20, 20, 20].iter().zip(buf.iter()) {
1310 /// assert_eq!(a, b);
1311 /// }
1312 /// ```
Brian Andersoncd6d9ea2015-01-23 02:22:031313 #[unstable(feature = "collections",
Brian Anderson94ca8a32015-01-13 02:40:191314 reason = "matches collection reform specification; waiting on panic semantics")]
Alexise250fe32015-02-05 02:17:191315 pub fn resize(&mut self, new_len: usize, value: T) {
Piotr Czarnecki156a1c32015-01-05 14:48:581316 let len = self.len();
1317
1318 if new_len > len {
1319 self.extend(repeat(value).take(new_len - len))
1320 } else {
1321 self.truncate(new_len);
1322 }
1323 }
1324}
1325
Colin Sherratt7a666df2014-10-19 20:19:071326/// Returns the index in the underlying buffer for a given logical element index.
1327#[inline]
Alexise250fe32015-02-05 02:17:191328fn wrap_index(index: usize, size: usize) -> usize {
Colin Sherratt7a666df2014-10-19 20:19:071329 // size is always a power of 2
Colin Sherratt40191182014-11-12 01:22:071330 index & (size - 1)
Colin Sherratt7a666df2014-10-19 20:19:071331}
1332
1333/// Calculate the number of elements left to be read in the buffer
1334#[inline]
Alexise250fe32015-02-05 02:17:191335fn count(tail: usize, head: usize, size: usize) -> usize {
Colin Sherratt7a666df2014-10-19 20:19:071336 // size is always a power of 2
1337 (head - tail) & (size - 1)
1338}
1339
Niko Matsakis1b487a82014-08-28 01:46:521340/// `RingBuf` iterator.
Brian Andersonb44ee372015-01-24 05:48:201341#[stable(feature = "rust1", since = "1.0.0")]
Florian Wilkensf8cfd242014-12-19 20:52:101342pub struct Iter<'a, T:'a> {
Colin Sherratt7a666df2014-10-19 20:19:071343 ring: &'a [T],
Alexise250fe32015-02-05 02:17:191344 tail: usize,
1345 head: usize
Niko Matsakis1b487a82014-08-28 01:46:521346}
1347
Jorge Aparicio351409a2015-01-04 03:54:181348// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
Huon Wilsonb7832ed2014-12-30 10:01:361349impl<'a, T> Clone for Iter<'a, T> {
1350 fn clone(&self) -> Iter<'a, T> {
1351 Iter {
1352 ring: self.ring,
1353 tail: self.tail,
1354 head: self.head
1355 }
1356 }
1357}
1358
Brian Andersonb44ee372015-01-24 05:48:201359#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351360impl<'a, T> Iterator for Iter<'a, T> {
1361 type Item = &'a T;
1362
Niko Matsakisbc4164d2013-11-16 22:29:391363 #[inline]
Erik Price5731ca32013-12-10 07:16:181364 fn next(&mut self) -> Option<&'a T> {
Colin Sherratt7a666df2014-10-19 20:19:071365 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:391366 return None;
1367 }
Colin Sherratt7a666df2014-10-19 20:19:071368 let tail = self.tail;
1369 self.tail = wrap_index(self.tail + 1, self.ring.len());
Aaron Turon6abfac02014-12-30 18:51:181370 unsafe { Some(self.ring.get_unchecked(tail)) }
Niko Matsakisbc4164d2013-11-16 22:29:391371 }
1372
1373 #[inline]
Alexise250fe32015-02-05 02:17:191374 fn size_hint(&self) -> (usize, Option<usize>) {
Colin Sherratt7a666df2014-10-19 20:19:071375 let len = count(self.tail, self.head, self.ring.len());
Niko Matsakisbc4164d2013-11-16 22:29:391376 (len, Some(len))
1377 }
1378}
1379
Brian Andersonb44ee372015-01-24 05:48:201380#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351381impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:391382 #[inline]
Erik Price5731ca32013-12-10 07:16:181383 fn next_back(&mut self) -> Option<&'a T> {
Colin Sherratt7a666df2014-10-19 20:19:071384 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:391385 return None;
1386 }
Colin Sherratt7a666df2014-10-19 20:19:071387 self.head = wrap_index(self.head - 1, self.ring.len());
Aaron Turon6abfac02014-12-30 18:51:181388 unsafe { Some(self.ring.get_unchecked(self.head)) }
Niko Matsakisbc4164d2013-11-16 22:29:391389 }
1390}
Jed Estep35314c92013-06-26 15:38:291391
Brian Andersonb44ee372015-01-24 05:48:201392#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351393impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
blake2-ppc7c369ee72013-09-01 16:20:241394
Brian Andersonb44ee372015-01-24 05:48:201395#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351396impl<'a, T> RandomAccessIterator for Iter<'a, T> {
blake2-ppcf6862132013-07-29 18:16:261397 #[inline]
Alexise250fe32015-02-05 02:17:191398 fn indexable(&self) -> usize {
Colin Sherratt7a666df2014-10-19 20:19:071399 let (len, _) = self.size_hint();
1400 len
1401 }
blake2-ppcf6862132013-07-29 18:16:261402
1403 #[inline]
Alexise250fe32015-02-05 02:17:191404 fn idx(&mut self, j: usize) -> Option<&'a T> {
blake2-ppcf6862132013-07-29 18:16:261405 if j >= self.indexable() {
1406 None
1407 } else {
Colin Sherratt7a666df2014-10-19 20:19:071408 let idx = wrap_index(self.tail + j, self.ring.len());
Aaron Turon6abfac02014-12-30 18:51:181409 unsafe { Some(self.ring.get_unchecked(idx)) }
blake2-ppcf6862132013-07-29 18:16:261410 }
1411 }
1412}
1413
Florian Wilkensf8cfd242014-12-19 20:52:101414// FIXME This was implemented differently from Iter because of a problem
Colin Sherratt7a666df2014-10-19 20:19:071415// with returning the mutable reference. I couldn't find a way to
1416// make the lifetime checker happy so, but there should be a way.
Niko Matsakis1b487a82014-08-28 01:46:521417/// `RingBuf` mutable iterator.
Brian Andersonb44ee372015-01-24 05:48:201418#[stable(feature = "rust1", since = "1.0.0")]
Florian Wilkensf8cfd242014-12-19 20:52:101419pub struct IterMut<'a, T:'a> {
Colin Sherratt7a666df2014-10-19 20:19:071420 ptr: *mut T,
Alexise250fe32015-02-05 02:17:191421 tail: usize,
1422 head: usize,
1423 cap: usize,
Colin Sherratt7a666df2014-10-19 20:19:071424 marker: marker::ContravariantLifetime<'a>,
Niko Matsakis1b487a82014-08-28 01:46:521425}
1426
Brian Andersonb44ee372015-01-24 05:48:201427#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351428impl<'a, T> Iterator for IterMut<'a, T> {
1429 type Item = &'a mut T;
1430
Niko Matsakisbc4164d2013-11-16 22:29:391431 #[inline]
Erik Price5731ca32013-12-10 07:16:181432 fn next(&mut self) -> Option<&'a mut T> {
Colin Sherratt7a666df2014-10-19 20:19:071433 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:391434 return None;
1435 }
Colin Sherratt7a666df2014-10-19 20:19:071436 let tail = self.tail;
1437 self.tail = wrap_index(self.tail + 1, self.cap);
Alexis Beingessner865c2db2014-11-23 02:34:111438
1439 unsafe {
Alexise250fe32015-02-05 02:17:191440 Some(&mut *self.ptr.offset(tail as isize))
Alex Crichton9d5d97b2014-10-15 06:05:011441 }
Niko Matsakisbc4164d2013-11-16 22:29:391442 }
1443
1444 #[inline]
Alexise250fe32015-02-05 02:17:191445 fn size_hint(&self) -> (usize, Option<usize>) {
Colin Sherratt7a666df2014-10-19 20:19:071446 let len = count(self.tail, self.head, self.cap);
1447 (len, Some(len))
Niko Matsakisbc4164d2013-11-16 22:29:391448 }
1449}
1450
Brian Andersonb44ee372015-01-24 05:48:201451#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351452impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:391453 #[inline]
Erik Price5731ca32013-12-10 07:16:181454 fn next_back(&mut self) -> Option<&'a mut T> {
Colin Sherratt7a666df2014-10-19 20:19:071455 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:391456 return None;
1457 }
Colin Sherratt7a666df2014-10-19 20:19:071458 self.head = wrap_index(self.head - 1, self.cap);
Alexis Beingessner865c2db2014-11-23 02:34:111459
1460 unsafe {
Alexise250fe32015-02-05 02:17:191461 Some(&mut *self.ptr.offset(self.head as isize))
Alexis Beingessner865c2db2014-11-23 02:34:111462 }
Niko Matsakisbc4164d2013-11-16 22:29:391463 }
1464}
Daniel Micayb47e1e92013-02-16 22:55:551465
Brian Andersonb44ee372015-01-24 05:48:201466#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351467impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
blake2-ppc7c369ee72013-09-01 16:20:241468
Alexis Beingessner8dbaa712014-12-31 00:07:531469/// A by-value RingBuf iterator
Brian Andersonb44ee372015-01-24 05:48:201470#[stable(feature = "rust1", since = "1.0.0")]
Florian Wilkensf8cfd242014-12-19 20:52:101471pub struct IntoIter<T> {
Alexis Beingessner865c2db2014-11-23 02:34:111472 inner: RingBuf<T>,
1473}
1474
Brian Andersonb44ee372015-01-24 05:48:201475#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351476impl<T> Iterator for IntoIter<T> {
1477 type Item = T;
1478
Alexis Beingessner865c2db2014-11-23 02:34:111479 #[inline]
1480 fn next(&mut self) -> Option<T> {
1481 self.inner.pop_front()
1482 }
1483
1484 #[inline]
Alexise250fe32015-02-05 02:17:191485 fn size_hint(&self) -> (usize, Option<usize>) {
Alexis Beingessner865c2db2014-11-23 02:34:111486 let len = self.inner.len();
1487 (len, Some(len))
1488 }
1489}
1490
Brian Andersonb44ee372015-01-24 05:48:201491#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351492impl<T> DoubleEndedIterator for IntoIter<T> {
Alexis Beingessner865c2db2014-11-23 02:34:111493 #[inline]
1494 fn next_back(&mut self) -> Option<T> {
1495 self.inner.pop_back()
1496 }
1497}
1498
Brian Andersonb44ee372015-01-24 05:48:201499#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351500impl<T> ExactSizeIterator for IntoIter<T> {}
Alexis Beingessner865c2db2014-11-23 02:34:111501
Clark Gaebeld57f2592014-12-16 22:45:031502/// A draining RingBuf iterator
Brian Andersoncd6d9ea2015-01-23 02:22:031503#[unstable(feature = "collections",
Brian Anderson94ca8a32015-01-13 02:40:191504 reason = "matches collection reform specification, waiting for dust to settle")]
Clark Gaebeld57f2592014-12-16 22:45:031505pub struct Drain<'a, T: 'a> {
1506 inner: &'a mut RingBuf<T>,
1507}
1508
1509#[unsafe_destructor]
Brian Andersonb44ee372015-01-24 05:48:201510#[stable(feature = "rust1", since = "1.0.0")]
Clark Gaebeld57f2592014-12-16 22:45:031511impl<'a, T: 'a> Drop for Drain<'a, T> {
1512 fn drop(&mut self) {
Jorge Apariciof9865ea2015-01-11 02:50:071513 for _ in self.by_ref() {}
Clark Gaebeld57f2592014-12-16 22:45:031514 self.inner.head = 0;
1515 self.inner.tail = 0;
1516 }
1517}
1518
Brian Andersonb44ee372015-01-24 05:48:201519#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351520impl<'a, T: 'a> Iterator for Drain<'a, T> {
1521 type Item = T;
1522
Clark Gaebeld57f2592014-12-16 22:45:031523 #[inline]
1524 fn next(&mut self) -> Option<T> {
1525 self.inner.pop_front()
1526 }
1527
1528 #[inline]
Alexise250fe32015-02-05 02:17:191529 fn size_hint(&self) -> (usize, Option<usize>) {
Clark Gaebeld57f2592014-12-16 22:45:031530 let len = self.inner.len();
1531 (len, Some(len))
1532 }
1533}
1534
Brian Andersonb44ee372015-01-24 05:48:201535#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351536impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
Clark Gaebeld57f2592014-12-16 22:45:031537 #[inline]
1538 fn next_back(&mut self) -> Option<T> {
1539 self.inner.pop_back()
1540 }
1541}
1542
Brian Andersonb44ee372015-01-24 05:48:201543#[stable(feature = "rust1", since = "1.0.0")]
Jorge Aparicio6b116be2015-01-02 04:15:351544impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
Clark Gaebeld57f2592014-12-16 22:45:031545
Brian Andersonb44ee372015-01-24 05:48:201546#[stable(feature = "rust1", since = "1.0.0")]
Alex Crichton748bc3c2014-05-30 00:45:071547impl<A: PartialEq> PartialEq for RingBuf<A> {
blake2-ppc70523712013-07-10 13:27:141548 fn eq(&self, other: &RingBuf<A>) -> bool {
Colin Sherratt7a666df2014-10-19 20:19:071549 self.len() == other.len() &&
blake2-ppc10c76982013-07-06 13:27:321550 self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
1551 }
blake2-ppc10c76982013-07-06 13:27:321552}
1553
Brian Andersonb44ee372015-01-24 05:48:201554#[stable(feature = "rust1", since = "1.0.0")]
nham25acfde2014-08-01 20:05:031555impl<A: Eq> Eq for RingBuf<A> {}
1556
Brian Andersonb44ee372015-01-24 05:48:201557#[stable(feature = "rust1", since = "1.0.0")]
nham63615772014-07-27 03:18:561558impl<A: PartialOrd> PartialOrd for RingBuf<A> {
1559 fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
1560 iter::order::partial_cmp(self.iter(), other.iter())
1561 }
1562}
1563
Brian Andersonb44ee372015-01-24 05:48:201564#[stable(feature = "rust1", since = "1.0.0")]
nham3737c532014-08-01 20:22:481565impl<A: Ord> Ord for RingBuf<A> {
1566 #[inline]
1567 fn cmp(&self, other: &RingBuf<A>) -> Ordering {
1568 iter::order::cmp(self.iter(), other.iter())
1569 }
1570}
1571
Brian Andersonb44ee372015-01-24 05:48:201572#[stable(feature = "rust1", since = "1.0.0")]
Alex Crichton511f0b82014-12-09 20:37:231573impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for RingBuf<A> {
nham1cfa6562014-07-27 02:33:471574 fn hash(&self, state: &mut S) {
nham9fa44242014-07-27 16:37:321575 self.len().hash(state);
Jorge Apariciod5d7e652015-01-31 17:20:461576 for elt in self {
nham1cfa6562014-07-27 02:33:471577 elt.hash(state);
1578 }
1579 }
1580}
1581
Brian Andersonb44ee372015-01-24 05:48:201582#[stable(feature = "rust1", since = "1.0.0")]
Alexise250fe32015-02-05 02:17:191583impl<A> Index<usize> for RingBuf<A> {
Jorge Aparicio32dd5922015-01-03 15:40:101584 type Output = A;
1585
1586 #[inline]
Alexis1420ceb2015-02-05 18:48:201587 fn index(&self, i: &usize) -> &A {
Jorge Aparicio32dd5922015-01-03 15:40:101588 self.get(*i).expect("Out of bounds access")
1589 }
1590}
1591
Brian Andersonb44ee372015-01-24 05:48:201592#[stable(feature = "rust1", since = "1.0.0")]
Alexise250fe32015-02-05 02:17:191593impl<A> IndexMut<usize> for RingBuf<A> {
Jorge Aparicio32dd5922015-01-03 15:40:101594 type Output = A;
1595
1596 #[inline]
Alexis1420ceb2015-02-05 18:48:201597 fn index_mut(&mut self, i: &usize) -> &mut A {
Jorge Aparicio32dd5922015-01-03 15:40:101598 self.get_mut(*i).expect("Out of bounds access")
1599 }
1600}
1601
Brian Andersonb44ee372015-01-24 05:48:201602#[stable(feature = "rust1", since = "1.0.0")]
Huon Wilson53487a02013-08-13 13:08:141603impl<A> FromIterator<A> for RingBuf<A> {
Jorge Aparicio6b116be2015-01-02 04:15:351604 fn from_iter<T: Iterator<Item=A>>(iterator: T) -> RingBuf<A> {
blake2-ppcf8ae5262013-07-30 00:06:491605 let (lower, _) = iterator.size_hint();
1606 let mut deq = RingBuf::with_capacity(lower);
1607 deq.extend(iterator);
blake2-ppc08dc72f2013-07-06 03:42:451608 deq
1609 }
1610}
1611
Jorge Aparicioa65d3f52015-01-08 03:01:051612impl<T> IntoIterator for RingBuf<T> {
1613 type Iter = IntoIter<T>;
1614
1615 fn into_iter(self) -> IntoIter<T> {
1616 self.into_iter()
1617 }
1618}
1619
1620impl<'a, T> IntoIterator for &'a RingBuf<T> {
1621 type Iter = Iter<'a, T>;
1622
1623 fn into_iter(self) -> Iter<'a, T> {
1624 self.iter()
1625 }
1626}
1627
1628impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
1629 type Iter = IterMut<'a, T>;
1630
1631 fn into_iter(mut self) -> IterMut<'a, T> {
1632 self.iter_mut()
1633 }
1634}
1635
Brian Andersonb44ee372015-01-24 05:48:201636#[stable(feature = "rust1", since = "1.0.0")]
gamazeps16c8cd92014-11-08 00:39:391637impl<A> Extend<A> for RingBuf<A> {
Jorge Aparicio34847062015-01-31 14:17:501638 fn extend<T: Iterator<Item=A>>(&mut self, iterator: T) {
Marvin Löbel6200e762014-03-20 13:12:561639 for elt in iterator {
Alexis Beingessnercf3b2e42014-11-06 17:24:471640 self.push_back(elt);
blake2-ppcf8ae5262013-07-30 00:06:491641 }
1642 }
1643}
1644
Brian Andersonb44ee372015-01-24 05:48:201645#[stable(feature = "rust1", since = "1.0.0")]
Alex Crichton3cb9fa22015-01-20 23:45:071646impl<T: fmt::Debug> fmt::Debug for RingBuf<T> {
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041647 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Sean McArthur44440e52014-12-20 08:09:351648 try!(write!(f, "RingBuf ["));
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041649
1650 for (i, e) in self.iter().enumerate() {
1651 if i != 0 { try!(write!(f, ", ")); }
Sean McArthur44440e52014-12-20 08:09:351652 try!(write!(f, "{:?}", *e));
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041653 }
1654
1655 write!(f, "]")
1656 }
1657}
1658
Brian Anderson6e27b272012-01-18 03:05:071659#[cfg(test)]
1660mod tests {
Steven Fackler3dcd2152014-11-06 08:05:531661 use self::Taggy::*;
1662 use self::Taggypar::*;
Eduard Burtescub45d30d2014-12-19 12:02:221663 use prelude::*;
Eduard Burtescub45d30d2014-12-19 12:02:221664 use core::iter;
Alex Crichton3cb9fa22015-01-20 23:45:071665 use std::fmt::Debug;
Alex Crichton511f0b82014-12-09 20:37:231666 use std::hash::{self, SipHasher};
Alex Crichton760b93a2014-05-30 02:03:061667 use test::Bencher;
1668 use test;
1669
Alex Crichtonf47e4b22014-01-07 06:33:501670 use super::RingBuf;
Patrick Waltonfa5ee932012-12-28 02:24:181671
Brian Anderson6e27b272012-01-18 03:05:071672 #[test]
Victor Berger52ea83d2014-09-22 17:30:061673 #[allow(deprecated)]
Brian Anderson6e27b272012-01-18 03:05:071674 fn test_simple() {
blake2-ppc70523712013-07-10 13:27:141675 let mut d = RingBuf::new();
Alexise250fe32015-02-05 02:17:191676 assert_eq!(d.len(), 0);
Tobias Bucher7f64fe42015-01-25 21:05:031677 d.push_front(17);
1678 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:471679 d.push_back(137);
Alexise250fe32015-02-05 02:17:191680 assert_eq!(d.len(), 3);
Alexis Beingessnercf3b2e42014-11-06 17:24:471681 d.push_back(137);
Alexise250fe32015-02-05 02:17:191682 assert_eq!(d.len(), 4);
blake2-ppc70523712013-07-10 13:27:141683 assert_eq!(*d.front().unwrap(), 42);
blake2-ppc70523712013-07-10 13:27:141684 assert_eq!(*d.back().unwrap(), 137);
1685 let mut i = d.pop_front();
blake2-ppc70523712013-07-10 13:27:141686 assert_eq!(i, Some(42));
Alexis Beingessnercf3b2e42014-11-06 17:24:471687 i = d.pop_back();
blake2-ppc70523712013-07-10 13:27:141688 assert_eq!(i, Some(137));
Alexis Beingessnercf3b2e42014-11-06 17:24:471689 i = d.pop_back();
blake2-ppc70523712013-07-10 13:27:141690 assert_eq!(i, Some(137));
Alexis Beingessnercf3b2e42014-11-06 17:24:471691 i = d.pop_back();
blake2-ppc70523712013-07-10 13:27:141692 assert_eq!(i, Some(17));
Alexise250fe32015-02-05 02:17:191693 assert_eq!(d.len(), 0);
Alexis Beingessnercf3b2e42014-11-06 17:24:471694 d.push_back(3);
Alexise250fe32015-02-05 02:17:191695 assert_eq!(d.len(), 1);
blake2-ppc70523712013-07-10 13:27:141696 d.push_front(2);
Alexise250fe32015-02-05 02:17:191697 assert_eq!(d.len(), 2);
Alexis Beingessnercf3b2e42014-11-06 17:24:471698 d.push_back(4);
Alexise250fe32015-02-05 02:17:191699 assert_eq!(d.len(), 3);
blake2-ppc70523712013-07-10 13:27:141700 d.push_front(1);
Alexise250fe32015-02-05 02:17:191701 assert_eq!(d.len(), 4);
Alex Crichton9d5d97b2014-10-15 06:05:011702 debug!("{}", d[0]);
1703 debug!("{}", d[1]);
1704 debug!("{}", d[2]);
1705 debug!("{}", d[3]);
1706 assert_eq!(d[0], 1);
1707 assert_eq!(d[1], 2);
1708 assert_eq!(d[2], 3);
1709 assert_eq!(d[3], 4);
Brian Anderson6e27b272012-01-18 03:05:071710 }
1711
Felix S. Klock IIa636f512013-05-01 23:32:371712 #[cfg(test)]
Alex Crichton3cb9fa22015-01-20 23:45:071713 fn test_parameterized<T:Clone + PartialEq + Debug>(a: T, b: T, c: T, d: T) {
Patrick Waltondc4bf172013-07-13 04:05:591714 let mut deq = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:451715 assert_eq!(deq.len(), 0);
Patrick Waltondc4bf172013-07-13 04:05:591716 deq.push_front(a.clone());
1717 deq.push_front(b.clone());
Alexis Beingessnercf3b2e42014-11-06 17:24:471718 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451719 assert_eq!(deq.len(), 3);
Alexis Beingessnercf3b2e42014-11-06 17:24:471720 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451721 assert_eq!(deq.len(), 4);
Marvin Löbel0ac7a212013-08-03 23:59:241722 assert_eq!((*deq.front().unwrap()).clone(), b.clone());
1723 assert_eq!((*deq.back().unwrap()).clone(), d.clone());
1724 assert_eq!(deq.pop_front().unwrap(), b.clone());
Alexis Beingessnercf3b2e42014-11-06 17:24:471725 assert_eq!(deq.pop_back().unwrap(), d.clone());
1726 assert_eq!(deq.pop_back().unwrap(), c.clone());
1727 assert_eq!(deq.pop_back().unwrap(), a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451728 assert_eq!(deq.len(), 0);
Alexis Beingessnercf3b2e42014-11-06 17:24:471729 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451730 assert_eq!(deq.len(), 1);
Patrick Waltondc4bf172013-07-13 04:05:591731 deq.push_front(b.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451732 assert_eq!(deq.len(), 2);
Alexis Beingessnercf3b2e42014-11-06 17:24:471733 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451734 assert_eq!(deq.len(), 3);
Patrick Waltondc4bf172013-07-13 04:05:591735 deq.push_front(a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451736 assert_eq!(deq.len(), 4);
NODA, Kaif27ad3d2014-10-05 10:11:171737 assert_eq!(deq[0].clone(), a.clone());
1738 assert_eq!(deq[1].clone(), b.clone());
1739 assert_eq!(deq[2].clone(), c.clone());
1740 assert_eq!(deq[3].clone(), d.clone());
Brian Anderson6e27b272012-01-18 03:05:071741 }
1742
blake2-ppc81933ed2013-07-06 03:42:451743 #[test]
blake2-ppc70523712013-07-10 13:27:141744 fn test_push_front_grow() {
1745 let mut deq = RingBuf::new();
Alexise250fe32015-02-05 02:17:191746 for i in 0..66 {
blake2-ppc70523712013-07-10 13:27:141747 deq.push_front(i);
blake2-ppc81933ed2013-07-06 03:42:451748 }
1749 assert_eq!(deq.len(), 66);
1750
Alexise250fe32015-02-05 02:17:191751 for i in 0..66 {
NODA, Kaif27ad3d2014-10-05 10:11:171752 assert_eq!(deq[i], 65 - i);
blake2-ppc81933ed2013-07-06 03:42:451753 }
1754
blake2-ppc70523712013-07-10 13:27:141755 let mut deq = RingBuf::new();
Alexise250fe32015-02-05 02:17:191756 for i in 0..66 {
Alexis Beingessnercf3b2e42014-11-06 17:24:471757 deq.push_back(i);
blake2-ppc81933ed2013-07-06 03:42:451758 }
1759
Alexise250fe32015-02-05 02:17:191760 for i in 0..66 {
NODA, Kaif27ad3d2014-10-05 10:11:171761 assert_eq!(deq[i], i);
blake2-ppc81933ed2013-07-06 03:42:451762 }
1763 }
1764
P1startfd10d202014-08-02 06:39:391765 #[test]
1766 fn test_index() {
1767 let mut deq = RingBuf::new();
Alexise250fe32015-02-05 02:17:191768 for i in 1..4 {
P1startfd10d202014-08-02 06:39:391769 deq.push_front(i);
1770 }
1771 assert_eq!(deq[1], 2);
1772 }
1773
1774 #[test]
1775 #[should_fail]
1776 fn test_index_out_of_bounds() {
1777 let mut deq = RingBuf::new();
Alexise250fe32015-02-05 02:17:191778 for i in 1..4 {
P1startfd10d202014-08-02 06:39:391779 deq.push_front(i);
1780 }
1781 deq[3];
1782 }
1783
blake2-ppc81933ed2013-07-06 03:42:451784 #[bench]
Liigo Zhuang408f4842014-04-01 01:16:351785 fn bench_new(b: &mut test::Bencher) {
Patrick Walton38efa172013-11-22 03:20:481786 b.iter(|| {
Alexise250fe32015-02-05 02:17:191787 let ring: RingBuf<i32> = RingBuf::new();
Colin Sherratt5e549d82014-11-11 02:57:521788 test::black_box(ring);
Patrick Walton38efa172013-11-22 03:20:481789 })
blake2-ppc81933ed2013-07-06 03:42:451790 }
1791
1792 #[bench]
Colin Sherratt7a666df2014-10-19 20:19:071793 fn bench_push_back_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521794 let mut deq = RingBuf::with_capacity(101);
Patrick Walton38efa172013-11-22 03:20:481795 b.iter(|| {
Tobias Bucher7f64fe42015-01-25 21:05:031796 for i in 0..100 {
Colin Sherratt7a666df2014-10-19 20:19:071797 deq.push_back(i);
1798 }
Colin Sherratt5e549d82014-11-11 02:57:521799 deq.head = 0;
1800 deq.tail = 0;
Patrick Walton38efa172013-11-22 03:20:481801 })
blake2-ppc81933ed2013-07-06 03:42:451802 }
1803
1804 #[bench]
Colin Sherratt7a666df2014-10-19 20:19:071805 fn bench_push_front_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521806 let mut deq = RingBuf::with_capacity(101);
Patrick Walton38efa172013-11-22 03:20:481807 b.iter(|| {
Tobias Bucher7f64fe42015-01-25 21:05:031808 for i in 0..100 {
Colin Sherratt7a666df2014-10-19 20:19:071809 deq.push_front(i);
1810 }
Colin Sherratt5e549d82014-11-11 02:57:521811 deq.head = 0;
1812 deq.tail = 0;
Patrick Walton38efa172013-11-22 03:20:481813 })
blake2-ppc81933ed2013-07-06 03:42:451814 }
1815
1816 #[bench]
Colin Sherratt5e549d82014-11-11 02:57:521817 fn bench_pop_back_100(b: &mut test::Bencher) {
Alexise250fe32015-02-05 02:17:191818 let mut deq= RingBuf::<i32>::with_capacity(101);
Colin Sherratt7a666df2014-10-19 20:19:071819
Patrick Walton38efa172013-11-22 03:20:481820 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521821 deq.head = 100;
1822 deq.tail = 0;
1823 while !deq.is_empty() {
1824 test::black_box(deq.pop_back());
Colin Sherratt7a666df2014-10-19 20:19:071825 }
Colin Sherratt7a666df2014-10-19 20:19:071826 })
1827 }
1828
1829 #[bench]
1830 fn bench_pop_front_100(b: &mut test::Bencher) {
Alexise250fe32015-02-05 02:17:191831 let mut deq = RingBuf::<i32>::with_capacity(101);
Colin Sherratt7a666df2014-10-19 20:19:071832
1833 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521834 deq.head = 100;
1835 deq.tail = 0;
1836 while !deq.is_empty() {
1837 test::black_box(deq.pop_front());
Colin Sherratt7a666df2014-10-19 20:19:071838 }
Colin Sherratt7a666df2014-10-19 20:19:071839 })
1840 }
1841
1842 #[bench]
1843 fn bench_grow_1025(b: &mut test::Bencher) {
1844 b.iter(|| {
1845 let mut deq = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:031846 for i in 0..1025 {
Colin Sherratt7a666df2014-10-19 20:19:071847 deq.push_front(i);
Brendan Zabarauskas729060d2014-01-30 00:20:341848 }
Colin Sherratt5e549d82014-11-11 02:57:521849 test::black_box(deq);
Patrick Walton38efa172013-11-22 03:20:481850 })
blake2-ppc81933ed2013-07-06 03:42:451851 }
1852
Colin Sherratt7a666df2014-10-19 20:19:071853 #[bench]
1854 fn bench_iter_1000(b: &mut test::Bencher) {
Alexise250fe32015-02-05 02:17:191855 let ring: RingBuf<_> = (0..1000).collect();
Colin Sherratt7a666df2014-10-19 20:19:071856
1857 b.iter(|| {
1858 let mut sum = 0;
Jorge Apariciod5d7e652015-01-31 17:20:461859 for &i in &ring {
Colin Sherratt7a666df2014-10-19 20:19:071860 sum += i;
1861 }
Colin Sherratt5e549d82014-11-11 02:57:521862 test::black_box(sum);
Colin Sherratt7a666df2014-10-19 20:19:071863 })
1864 }
1865
1866 #[bench]
1867 fn bench_mut_iter_1000(b: &mut test::Bencher) {
Alexise250fe32015-02-05 02:17:191868 let mut ring: RingBuf<_> = (0..1000).collect();
Colin Sherratt7a666df2014-10-19 20:19:071869
1870 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521871 let mut sum = 0;
Jorge Apariciod5f61b42015-02-01 01:02:001872 for i in &mut ring {
Colin Sherratt5e549d82014-11-11 02:57:521873 sum += *i;
Colin Sherratt7a666df2014-10-19 20:19:071874 }
Colin Sherratt5e549d82014-11-11 02:57:521875 test::black_box(sum);
Colin Sherratt7a666df2014-10-19 20:19:071876 })
1877 }
1878
Jorge Aparicio788181d2015-01-28 13:34:181879 #[derive(Clone, PartialEq, Debug)]
Patrick Walton99b33f72013-07-02 19:47:321880 enum Taggy {
Tobias Bucher7f64fe42015-01-25 21:05:031881 One(i32),
1882 Two(i32, i32),
1883 Three(i32, i32, i32),
Brian Anderson6e27b272012-01-18 03:05:071884 }
1885
Jorge Aparicio788181d2015-01-28 13:34:181886 #[derive(Clone, PartialEq, Debug)]
Patrick Walton99b33f72013-07-02 19:47:321887 enum Taggypar<T> {
Tobias Bucher7f64fe42015-01-25 21:05:031888 Onepar(i32),
1889 Twopar(i32, i32),
1890 Threepar(i32, i32, i32),
Patrick Walton99b33f72013-07-02 19:47:321891 }
1892
Jorge Aparicio788181d2015-01-28 13:34:181893 #[derive(Clone, PartialEq, Debug)]
Erick Tryzelaare84576b2013-01-22 16:44:241894 struct RecCy {
Tobias Bucher7f64fe42015-01-25 21:05:031895 x: i32,
1896 y: i32,
Patrick Waltoneb4d39e2013-01-26 00:57:391897 t: Taggy
Patrick Walton9117dcb2012-09-20 01:00:261898 }
Kevin Cantuc43426e2012-09-13 05:09:551899
1900 #[test]
1901 fn test_param_int() {
Tobias Bucher7f64fe42015-01-25 21:05:031902 test_parameterized::<i32>(5, 72, 64, 175);
Kevin Cantuc43426e2012-09-13 05:09:551903 }
1904
1905 #[test]
Kevin Cantuc43426e2012-09-13 05:09:551906 fn test_param_taggy() {
Corey Richardsonf8ae9b02013-06-26 22:14:351907 test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:551908 }
1909
1910 #[test]
1911 fn test_param_taggypar() {
Tobias Bucher7f64fe42015-01-25 21:05:031912 test_parameterized::<Taggypar<i32>>(Onepar::<i32>(1),
1913 Twopar::<i32>(1, 2),
1914 Threepar::<i32>(1, 2, 3),
1915 Twopar::<i32>(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:551916 }
Brian Anderson6e27b272012-01-18 03:05:071917
Kevin Cantuc43426e2012-09-13 05:09:551918 #[test]
1919 fn test_param_reccy() {
Erick Tryzelaare84576b2013-01-22 16:44:241920 let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
1921 let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
1922 let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
1923 let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
Kevin Cantuc43426e2012-09-13 05:09:551924 test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
Brian Anderson6e27b272012-01-18 03:05:071925 }
Erick Tryzelaar909d8f02013-03-30 01:02:441926
1927 #[test]
blake2-ppc0ff5c172013-07-06 03:42:451928 fn test_with_capacity() {
blake2-ppc70523712013-07-10 13:27:141929 let mut d = RingBuf::with_capacity(0);
Tobias Bucher7f64fe42015-01-25 21:05:031930 d.push_back(1);
blake2-ppc0ff5c172013-07-06 03:42:451931 assert_eq!(d.len(), 1);
blake2-ppc70523712013-07-10 13:27:141932 let mut d = RingBuf::with_capacity(50);
Tobias Bucher7f64fe42015-01-25 21:05:031933 d.push_back(1);
blake2-ppc0ff5c172013-07-06 03:42:451934 assert_eq!(d.len(), 1);
1935 }
1936
1937 #[test]
Kevin Butler64896d62014-08-07 01:11:131938 fn test_with_capacity_non_power_two() {
1939 let mut d3 = RingBuf::with_capacity(3);
Tobias Bucher7f64fe42015-01-25 21:05:031940 d3.push_back(1);
Kevin Butler64896d62014-08-07 01:11:131941
1942 // X = None, | = lo
1943 // [|1, X, X]
1944 assert_eq!(d3.pop_front(), Some(1));
1945 // [X, |X, X]
1946 assert_eq!(d3.front(), None);
1947
1948 // [X, |3, X]
Alexis Beingessnercf3b2e42014-11-06 17:24:471949 d3.push_back(3);
Kevin Butler64896d62014-08-07 01:11:131950 // [X, |3, 6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471951 d3.push_back(6);
Kevin Butler64896d62014-08-07 01:11:131952 // [X, X, |6]
1953 assert_eq!(d3.pop_front(), Some(3));
1954
1955 // Pushing the lo past half way point to trigger
1956 // the 'B' scenario for growth
1957 // [9, X, |6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471958 d3.push_back(9);
Kevin Butler64896d62014-08-07 01:11:131959 // [9, 12, |6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471960 d3.push_back(12);
Kevin Butler64896d62014-08-07 01:11:131961
Alexis Beingessnercf3b2e42014-11-06 17:24:471962 d3.push_back(15);
Kevin Butler64896d62014-08-07 01:11:131963 // There used to be a bug here about how the
1964 // RingBuf made growth assumptions about the
1965 // underlying Vec which didn't hold and lead
1966 // to corruption.
1967 // (Vec grows to next power of two)
1968 //good- [9, 12, 15, X, X, X, X, |6]
1969 //bug- [15, 12, X, X, X, |6, X, X]
1970 assert_eq!(d3.pop_front(), Some(6));
1971
1972 // Which leads us to the following state which
1973 // would be a failure case.
1974 //bug- [15, 12, X, X, X, X, |X, X]
1975 assert_eq!(d3.front(), Some(&9));
1976 }
1977
1978 #[test]
David Manescu65f35782014-01-31 13:03:201979 fn test_reserve_exact() {
blake2-ppc70523712013-07-10 13:27:141980 let mut d = RingBuf::new();
Alexise250fe32015-02-05 02:17:191981 d.push_back(0);
David Manescu65f35782014-01-31 13:03:201982 d.reserve_exact(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471983 assert!(d.capacity() >= 51);
Tim Chevalier77de84b2013-05-27 18:47:381984 }
1985
1986 #[test]
David Manescu65f35782014-01-31 13:03:201987 fn test_reserve() {
blake2-ppc70523712013-07-10 13:27:141988 let mut d = RingBuf::new();
Alexise250fe32015-02-05 02:17:191989 d.push_back(0);
David Manescu65f35782014-01-31 13:03:201990 d.reserve(50);
Colin Sherratt7a666df2014-10-19 20:19:071991 assert!(d.capacity() >= 51);
Tim Chevalier77de84b2013-05-27 18:47:381992 }
1993
Jed Estep096fb792013-06-26 14:04:441994 #[test]
blake2-ppc57757a82013-09-26 07:19:261995 fn test_swap() {
Alexise250fe32015-02-05 02:17:191996 let mut d: RingBuf<_> = (0..5).collect();
blake2-ppc57757a82013-09-26 07:19:261997 d.pop_front();
1998 d.swap(0, 3);
Alexise250fe32015-02-05 02:17:191999 assert_eq!(d.iter().cloned().collect::<Vec<_>>(), vec!(4, 2, 3, 1));
blake2-ppc57757a82013-09-26 07:19:262000 }
2001
2002 #[test]
Jed Estep096fb792013-06-26 14:04:442003 fn test_iter() {
blake2-ppc70523712013-07-10 13:27:142004 let mut d = RingBuf::new();
blake2-ppcf88d5322013-07-06 03:42:452005 assert_eq!(d.iter().next(), None);
blake2-ppc9ccf4432013-07-14 20:30:222006 assert_eq!(d.iter().size_hint(), (0, Some(0)));
blake2-ppcf88d5322013-07-06 03:42:452007
Tobias Bucher7f64fe42015-01-25 21:05:032008 for i in 0..5 {
Alexis Beingessnercf3b2e42014-11-06 17:24:472009 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:442010 }
Nick Cameron37a94b82014-08-04 12:19:022011 {
2012 let b: &[_] = &[&0,&1,&2,&3,&4];
Alexise250fe32015-02-05 02:17:192013 assert_eq!(d.iter().collect::<Vec<_>>(), b);
Nick Cameron37a94b82014-08-04 12:19:022014 }
Corey Richardsonf8ae9b02013-06-26 22:14:352015
Tobias Bucher7f64fe42015-01-25 21:05:032016 for i in 6..9 {
blake2-ppc70523712013-07-10 13:27:142017 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:442018 }
Nick Cameron37a94b82014-08-04 12:19:022019 {
2020 let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
Alexise250fe32015-02-05 02:17:192021 assert_eq!(d.iter().collect::<Vec<_>>(), b);
Nick Cameron37a94b82014-08-04 12:19:022022 }
blake2-ppc9ccf4432013-07-14 20:30:222023
2024 let mut it = d.iter();
2025 let mut len = d.len();
2026 loop {
2027 match it.next() {
2028 None => break,
2029 _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
2030 }
2031 }
Jed Estep096fb792013-06-26 14:04:442032 }
2033
2034 #[test]
2035 fn test_rev_iter() {
blake2-ppc70523712013-07-10 13:27:142036 let mut d = RingBuf::new();
Jonathan S03609e52014-04-21 04:59:122037 assert_eq!(d.iter().rev().next(), None);
blake2-ppcf88d5322013-07-06 03:42:452038
Tobias Bucher7f64fe42015-01-25 21:05:032039 for i in 0..5 {
Alexis Beingessnercf3b2e42014-11-06 17:24:472040 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:442041 }
Nick Cameron37a94b82014-08-04 12:19:022042 {
2043 let b: &[_] = &[&4,&3,&2,&1,&0];
Alexise250fe32015-02-05 02:17:192044 assert_eq!(d.iter().rev().collect::<Vec<_>>(), b);
Nick Cameron37a94b82014-08-04 12:19:022045 }
Corey Richardsonf8ae9b02013-06-26 22:14:352046
Tobias Bucher7f64fe42015-01-25 21:05:032047 for i in 6..9 {
blake2-ppc70523712013-07-10 13:27:142048 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:442049 }
Nick Cameron37a94b82014-08-04 12:19:022050 let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
Alexise250fe32015-02-05 02:17:192051 assert_eq!(d.iter().rev().collect::<Vec<_>>(), b);
Jed Estep096fb792013-06-26 14:04:442052 }
blake2-ppc08dc72f2013-07-06 03:42:452053
2054 #[test]
Niko Matsakisbc4164d2013-11-16 22:29:392055 fn test_mut_rev_iter_wrap() {
2056 let mut d = RingBuf::with_capacity(3);
Aaron Turonfc525ee2014-09-15 03:27:362057 assert!(d.iter_mut().rev().next().is_none());
Niko Matsakisbc4164d2013-11-16 22:29:392058
Tobias Bucher7f64fe42015-01-25 21:05:032059 d.push_back(1);
Alexis Beingessnercf3b2e42014-11-06 17:24:472060 d.push_back(2);
2061 d.push_back(3);
Niko Matsakisbc4164d2013-11-16 22:29:392062 assert_eq!(d.pop_front(), Some(1));
Alexis Beingessnercf3b2e42014-11-06 17:24:472063 d.push_back(4);
Niko Matsakisbc4164d2013-11-16 22:29:392064
Alexise250fe32015-02-05 02:17:192065 assert_eq!(d.iter_mut().rev().cloned().collect::<Vec<_>>(),
2066 vec![4, 3, 2]);
Niko Matsakisbc4164d2013-11-16 22:29:392067 }
2068
2069 #[test]
blake2-ppcf88d5322013-07-06 03:42:452070 fn test_mut_iter() {
blake2-ppc70523712013-07-10 13:27:142071 let mut d = RingBuf::new();
Aaron Turonfc525ee2014-09-15 03:27:362072 assert!(d.iter_mut().next().is_none());
blake2-ppcf88d5322013-07-06 03:42:452073
Alexise250fe32015-02-05 02:17:192074 for i in 0..3 {
blake2-ppc70523712013-07-10 13:27:142075 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:452076 }
2077
Aaron Turonfc525ee2014-09-15 03:27:362078 for (i, elt) in d.iter_mut().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:452079 assert_eq!(*elt, 2 - i);
2080 *elt = i;
2081 }
2082
2083 {
Aaron Turonfc525ee2014-09-15 03:27:362084 let mut it = d.iter_mut();
blake2-ppcf88d5322013-07-06 03:42:452085 assert_eq!(*it.next().unwrap(), 0);
2086 assert_eq!(*it.next().unwrap(), 1);
2087 assert_eq!(*it.next().unwrap(), 2);
2088 assert!(it.next().is_none());
2089 }
2090 }
2091
2092 #[test]
2093 fn test_mut_rev_iter() {
blake2-ppc70523712013-07-10 13:27:142094 let mut d = RingBuf::new();
Aaron Turonfc525ee2014-09-15 03:27:362095 assert!(d.iter_mut().rev().next().is_none());
blake2-ppcf88d5322013-07-06 03:42:452096
Alexise250fe32015-02-05 02:17:192097 for i in 0..3 {
blake2-ppc70523712013-07-10 13:27:142098 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:452099 }
2100
Aaron Turonfc525ee2014-09-15 03:27:362101 for (i, elt) in d.iter_mut().rev().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:452102 assert_eq!(*elt, i);
2103 *elt = i;
2104 }
2105
2106 {
Aaron Turonfc525ee2014-09-15 03:27:362107 let mut it = d.iter_mut().rev();
blake2-ppcf88d5322013-07-06 03:42:452108 assert_eq!(*it.next().unwrap(), 0);
2109 assert_eq!(*it.next().unwrap(), 1);
2110 assert_eq!(*it.next().unwrap(), 2);
2111 assert!(it.next().is_none());
2112 }
2113 }
2114
2115 #[test]
Alexis Beingessner865c2db2014-11-23 02:34:112116 fn test_into_iter() {
2117
2118 // Empty iter
2119 {
Tobias Bucher7f64fe42015-01-25 21:05:032120 let d: RingBuf<i32> = RingBuf::new();
Alexis Beingessner865c2db2014-11-23 02:34:112121 let mut iter = d.into_iter();
2122
2123 assert_eq!(iter.size_hint(), (0, Some(0)));
2124 assert_eq!(iter.next(), None);
2125 assert_eq!(iter.size_hint(), (0, Some(0)));
2126 }
2127
2128 // simple iter
2129 {
2130 let mut d = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:032131 for i in 0..5 {
Alexis Beingessner865c2db2014-11-23 02:34:112132 d.push_back(i);
2133 }
2134
2135 let b = vec![0,1,2,3,4];
Alexise250fe32015-02-05 02:17:192136 assert_eq!(d.into_iter().collect::<Vec<_>>(), b);
Alexis Beingessner865c2db2014-11-23 02:34:112137 }
2138
2139 // wrapped iter
2140 {
2141 let mut d = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:032142 for i in 0..5 {
Alexis Beingessner865c2db2014-11-23 02:34:112143 d.push_back(i);
2144 }
Tobias Bucher7f64fe42015-01-25 21:05:032145 for i in 6..9 {
Alexis Beingessner865c2db2014-11-23 02:34:112146 d.push_front(i);
2147 }
2148
2149 let b = vec![8,7,6,0,1,2,3,4];
Alexise250fe32015-02-05 02:17:192150 assert_eq!(d.into_iter().collect::<Vec<_>>(), b);
Alexis Beingessner865c2db2014-11-23 02:34:112151 }
2152
2153 // partially used
2154 {
2155 let mut d = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:032156 for i in 0..5 {
Alexis Beingessner865c2db2014-11-23 02:34:112157 d.push_back(i);
2158 }
Tobias Bucher7f64fe42015-01-25 21:05:032159 for i in 6..9 {
Alexis Beingessner865c2db2014-11-23 02:34:112160 d.push_front(i);
2161 }
2162
2163 let mut it = d.into_iter();
2164 assert_eq!(it.size_hint(), (8, Some(8)));
2165 assert_eq!(it.next(), Some(8));
2166 assert_eq!(it.size_hint(), (7, Some(7)));
2167 assert_eq!(it.next_back(), Some(4));
2168 assert_eq!(it.size_hint(), (6, Some(6)));
2169 assert_eq!(it.next(), Some(7));
2170 assert_eq!(it.size_hint(), (5, Some(5)));
2171 }
2172 }
2173
2174 #[test]
Clark Gaebeld57f2592014-12-16 22:45:032175 fn test_drain() {
2176
2177 // Empty iter
2178 {
Tobias Bucher7f64fe42015-01-25 21:05:032179 let mut d: RingBuf<i32> = RingBuf::new();
Clark Gaebeld57f2592014-12-16 22:45:032180
2181 {
2182 let mut iter = d.drain();
2183
2184 assert_eq!(iter.size_hint(), (0, Some(0)));
2185 assert_eq!(iter.next(), None);
2186 assert_eq!(iter.size_hint(), (0, Some(0)));
2187 }
2188
2189 assert!(d.is_empty());
2190 }
2191
2192 // simple iter
2193 {
2194 let mut d = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:032195 for i in 0..5 {
Clark Gaebeld57f2592014-12-16 22:45:032196 d.push_back(i);
2197 }
2198
Alex Crichton3a2530d2015-01-30 20:26:442199 assert_eq!(d.drain().collect::<Vec<_>>(), [0, 1, 2, 3, 4]);
Clark Gaebeld57f2592014-12-16 22:45:032200 assert!(d.is_empty());
2201 }
2202
2203 // wrapped iter
2204 {
2205 let mut d = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:032206 for i in 0..5 {
Clark Gaebeld57f2592014-12-16 22:45:032207 d.push_back(i);
2208 }
Alex Crichton3a2530d2015-01-30 20:26:442209 for i in 6..9 {
Clark Gaebeld57f2592014-12-16 22:45:032210 d.push_front(i);
2211 }
2212
Alex Crichton3a2530d2015-01-30 20:26:442213 assert_eq!(d.drain().collect::<Vec<_>>(), [8,7,6,0,1,2,3,4]);
Clark Gaebeld57f2592014-12-16 22:45:032214 assert!(d.is_empty());
2215 }
2216
2217 // partially used
2218 {
Alexise250fe32015-02-05 02:17:192219 let mut d: RingBuf<_> = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:032220 for i in 0..5 {
Clark Gaebeld57f2592014-12-16 22:45:032221 d.push_back(i);
2222 }
Alex Crichton3a2530d2015-01-30 20:26:442223 for i in 6..9 {
Clark Gaebeld57f2592014-12-16 22:45:032224 d.push_front(i);
2225 }
2226
2227 {
2228 let mut it = d.drain();
2229 assert_eq!(it.size_hint(), (8, Some(8)));
2230 assert_eq!(it.next(), Some(8));
2231 assert_eq!(it.size_hint(), (7, Some(7)));
2232 assert_eq!(it.next_back(), Some(4));
2233 assert_eq!(it.size_hint(), (6, Some(6)));
2234 assert_eq!(it.next(), Some(7));
2235 assert_eq!(it.size_hint(), (5, Some(5)));
2236 }
2237 assert!(d.is_empty());
2238 }
2239 }
2240
2241 #[test]
Brian Andersonee052192014-03-31 04:45:552242 fn test_from_iter() {
Eduard Burtescub45d30d2014-12-19 12:02:222243 use core::iter;
Tobias Bucher7f64fe42015-01-25 21:05:032244 let v = vec!(1,2,3,4,5,6,7);
Alexise250fe32015-02-05 02:17:192245 let deq: RingBuf<_> = v.iter().cloned().collect();
2246 let u: Vec<_> = deq.iter().cloned().collect();
blake2-ppc08dc72f2013-07-06 03:42:452247 assert_eq!(u, v);
2248
Alexise250fe32015-02-05 02:17:192249 let seq = iter::count(0, 2).take(256);
2250 let deq: RingBuf<_> = seq.collect();
Daniel Micay100894552013-08-03 16:45:232251 for (i, &x) in deq.iter().enumerate() {
blake2-ppc08dc72f2013-07-06 03:42:452252 assert_eq!(2*i, x);
2253 }
2254 assert_eq!(deq.len(), 256);
2255 }
blake2-ppc10c76982013-07-06 13:27:322256
2257 #[test]
2258 fn test_clone() {
blake2-ppc70523712013-07-10 13:27:142259 let mut d = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:032260 d.push_front(17);
blake2-ppc70523712013-07-10 13:27:142261 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:472262 d.push_back(137);
2263 d.push_back(137);
Alexise250fe32015-02-05 02:17:192264 assert_eq!(d.len(), 4);
blake2-ppc10c76982013-07-06 13:27:322265 let mut e = d.clone();
Alexise250fe32015-02-05 02:17:192266 assert_eq!(e.len(), 4);
blake2-ppc10c76982013-07-06 13:27:322267 while !d.is_empty() {
Alexis Beingessnercf3b2e42014-11-06 17:24:472268 assert_eq!(d.pop_back(), e.pop_back());
blake2-ppc10c76982013-07-06 13:27:322269 }
Alexise250fe32015-02-05 02:17:192270 assert_eq!(d.len(), 0);
2271 assert_eq!(e.len(), 0);
blake2-ppc10c76982013-07-06 13:27:322272 }
2273
2274 #[test]
2275 fn test_eq() {
blake2-ppc70523712013-07-10 13:27:142276 let mut d = RingBuf::new();
Alex Crichton02882fb2014-02-28 09:23:062277 assert!(d == RingBuf::with_capacity(0));
Tobias Bucher7f64fe42015-01-25 21:05:032278 d.push_front(137);
blake2-ppc70523712013-07-10 13:27:142279 d.push_front(17);
2280 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:472281 d.push_back(137);
blake2-ppc70523712013-07-10 13:27:142282 let mut e = RingBuf::with_capacity(0);
Alexis Beingessnercf3b2e42014-11-06 17:24:472283 e.push_back(42);
2284 e.push_back(17);
2285 e.push_back(137);
2286 e.push_back(137);
Alex Crichton02882fb2014-02-28 09:23:062287 assert!(&e == &d);
Alexis Beingessnercf3b2e42014-11-06 17:24:472288 e.pop_back();
2289 e.push_back(0);
blake2-ppc10c76982013-07-06 13:27:322290 assert!(e != d);
2291 e.clear();
Alex Crichton02882fb2014-02-28 09:23:062292 assert!(e == RingBuf::new());
blake2-ppc10c76982013-07-06 13:27:322293 }
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042294
2295 #[test]
nham1cfa6562014-07-27 02:33:472296 fn test_hash() {
2297 let mut x = RingBuf::new();
2298 let mut y = RingBuf::new();
2299
Tobias Bucher7f64fe42015-01-25 21:05:032300 x.push_back(1);
Alexis Beingessnercf3b2e42014-11-06 17:24:472301 x.push_back(2);
2302 x.push_back(3);
nham1cfa6562014-07-27 02:33:472303
Tobias Bucher7f64fe42015-01-25 21:05:032304 y.push_back(0);
2305 y.push_back(1);
nham1cfa6562014-07-27 02:33:472306 y.pop_front();
Alexis Beingessnercf3b2e42014-11-06 17:24:472307 y.push_back(2);
2308 y.push_back(3);
nham1cfa6562014-07-27 02:33:472309
Alex Crichton511f0b82014-12-09 20:37:232310 assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
nham1cfa6562014-07-27 02:33:472311 }
2312
2313 #[test]
nham63615772014-07-27 03:18:562314 fn test_ord() {
2315 let x = RingBuf::new();
2316 let mut y = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:032317 y.push_back(1);
Alexis Beingessnercf3b2e42014-11-06 17:24:472318 y.push_back(2);
2319 y.push_back(3);
nham63615772014-07-27 03:18:562320 assert!(x < y);
2321 assert!(y > x);
2322 assert!(x <= x);
2323 assert!(x >= x);
2324 }
2325
2326 #[test]
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042327 fn test_show() {
Alexise250fe32015-02-05 02:17:192328 let ringbuf: RingBuf<_> = (0..10).collect();
Alex Crichton3cb9fa22015-01-20 23:45:072329 assert_eq!(format!("{:?}", ringbuf), "RingBuf [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042330
Alexise250fe32015-02-05 02:17:192331 let ringbuf: RingBuf<_> = vec!["just", "one", "test", "more"].iter()
2332 .cloned()
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042333 .collect();
Alex Crichtona6400082015-01-07 00:16:352334 assert_eq!(format!("{:?}", ringbuf), "RingBuf [\"just\", \"one\", \"test\", \"more\"]");
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042335 }
Colin Sherratt7a666df2014-10-19 20:19:072336
2337 #[test]
2338 fn test_drop() {
Alexise250fe32015-02-05 02:17:192339 static mut drops: i32 = 0;
Colin Sherratt7a666df2014-10-19 20:19:072340 struct Elem;
2341 impl Drop for Elem {
2342 fn drop(&mut self) {
2343 unsafe { drops += 1; }
2344 }
2345 }
2346
2347 let mut ring = RingBuf::new();
2348 ring.push_back(Elem);
2349 ring.push_front(Elem);
2350 ring.push_back(Elem);
2351 ring.push_front(Elem);
2352 drop(ring);
2353
2354 assert_eq!(unsafe {drops}, 4);
2355 }
2356
2357 #[test]
2358 fn test_drop_with_pop() {
Alexise250fe32015-02-05 02:17:192359 static mut drops: i32 = 0;
Colin Sherratt7a666df2014-10-19 20:19:072360 struct Elem;
2361 impl Drop for Elem {
2362 fn drop(&mut self) {
2363 unsafe { drops += 1; }
2364 }
2365 }
2366
2367 let mut ring = RingBuf::new();
2368 ring.push_back(Elem);
2369 ring.push_front(Elem);
2370 ring.push_back(Elem);
2371 ring.push_front(Elem);
2372
2373 drop(ring.pop_back());
2374 drop(ring.pop_front());
2375 assert_eq!(unsafe {drops}, 2);
2376
2377 drop(ring);
2378 assert_eq!(unsafe {drops}, 4);
2379 }
2380
2381 #[test]
2382 fn test_drop_clear() {
Alexise250fe32015-02-05 02:17:192383 static mut drops: i32 = 0;
Colin Sherratt7a666df2014-10-19 20:19:072384 struct Elem;
2385 impl Drop for Elem {
2386 fn drop(&mut self) {
2387 unsafe { drops += 1; }
2388 }
2389 }
2390
2391 let mut ring = RingBuf::new();
2392 ring.push_back(Elem);
2393 ring.push_front(Elem);
2394 ring.push_back(Elem);
2395 ring.push_front(Elem);
2396 ring.clear();
2397 assert_eq!(unsafe {drops}, 4);
2398
2399 drop(ring);
2400 assert_eq!(unsafe {drops}, 4);
2401 }
2402
2403 #[test]
2404 fn test_reserve_grow() {
2405 // test growth path A
2406 // [T o o H] -> [T o o H . . . . ]
2407 let mut ring = RingBuf::with_capacity(4);
Tobias Bucher7f64fe42015-01-25 21:05:032408 for i in 0..3 {
Colin Sherratt7a666df2014-10-19 20:19:072409 ring.push_back(i);
2410 }
2411 ring.reserve(7);
Tobias Bucher7f64fe42015-01-25 21:05:032412 for i in 0..3 {
Colin Sherratt7a666df2014-10-19 20:19:072413 assert_eq!(ring.pop_front(), Some(i));
2414 }
2415
2416 // test growth path B
2417 // [H T o o] -> [. T o o H . . . ]
2418 let mut ring = RingBuf::with_capacity(4);
Tobias Bucher7f64fe42015-01-25 21:05:032419 for i in 0..1 {
Colin Sherratt7a666df2014-10-19 20:19:072420 ring.push_back(i);
2421 assert_eq!(ring.pop_front(), Some(i));
2422 }
Tobias Bucher7f64fe42015-01-25 21:05:032423 for i in 0..3 {
Colin Sherratt7a666df2014-10-19 20:19:072424 ring.push_back(i);
2425 }
2426 ring.reserve(7);
Tobias Bucher7f64fe42015-01-25 21:05:032427 for i in 0..3 {
Colin Sherratt7a666df2014-10-19 20:19:072428 assert_eq!(ring.pop_front(), Some(i));
2429 }
2430
2431 // test growth path C
2432 // [o o H T] -> [o o H . . . . T ]
2433 let mut ring = RingBuf::with_capacity(4);
Tobias Bucher7f64fe42015-01-25 21:05:032434 for i in 0..3 {
Colin Sherratt7a666df2014-10-19 20:19:072435 ring.push_back(i);
2436 assert_eq!(ring.pop_front(), Some(i));
2437 }
Tobias Bucher7f64fe42015-01-25 21:05:032438 for i in 0..3 {
Colin Sherratt7a666df2014-10-19 20:19:072439 ring.push_back(i);
2440 }
2441 ring.reserve(7);
Tobias Bucher7f64fe42015-01-25 21:05:032442 for i in 0..3 {
Colin Sherratt7a666df2014-10-19 20:19:072443 assert_eq!(ring.pop_front(), Some(i));
2444 }
2445 }
2446
2447 #[test]
2448 fn test_get() {
2449 let mut ring = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:032450 ring.push_back(0);
Colin Sherratt7a666df2014-10-19 20:19:072451 assert_eq!(ring.get(0), Some(&0));
2452 assert_eq!(ring.get(1), None);
2453
2454 ring.push_back(1);
2455 assert_eq!(ring.get(0), Some(&0));
2456 assert_eq!(ring.get(1), Some(&1));
2457 assert_eq!(ring.get(2), None);
2458
2459 ring.push_back(2);
2460 assert_eq!(ring.get(0), Some(&0));
2461 assert_eq!(ring.get(1), Some(&1));
2462 assert_eq!(ring.get(2), Some(&2));
2463 assert_eq!(ring.get(3), None);
2464
2465 assert_eq!(ring.pop_front(), Some(0));
2466 assert_eq!(ring.get(0), Some(&1));
2467 assert_eq!(ring.get(1), Some(&2));
2468 assert_eq!(ring.get(2), None);
2469
2470 assert_eq!(ring.pop_front(), Some(1));
2471 assert_eq!(ring.get(0), Some(&2));
2472 assert_eq!(ring.get(1), None);
2473
2474 assert_eq!(ring.pop_front(), Some(2));
2475 assert_eq!(ring.get(0), None);
2476 assert_eq!(ring.get(1), None);
2477 }
2478
2479 #[test]
2480 fn test_get_mut() {
2481 let mut ring = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:032482 for i in 0..3 {
Colin Sherratt7a666df2014-10-19 20:19:072483 ring.push_back(i);
2484 }
2485
2486 match ring.get_mut(1) {
2487 Some(x) => *x = -1,
2488 None => ()
2489 };
2490
2491 assert_eq!(ring.get_mut(0), Some(&mut 0));
2492 assert_eq!(ring.get_mut(1), Some(&mut -1));
2493 assert_eq!(ring.get_mut(2), Some(&mut 2));
2494 assert_eq!(ring.get_mut(3), None);
2495
2496 assert_eq!(ring.pop_front(), Some(0));
2497 assert_eq!(ring.get_mut(0), Some(&mut -1));
2498 assert_eq!(ring.get_mut(1), Some(&mut 2));
2499 assert_eq!(ring.get_mut(2), None);
2500 }
Matt Murphy40f28c72014-12-03 17:12:302501
2502 #[test]
Piotr Czarnecki156a1c32015-01-05 14:48:582503 fn test_swap_front_back_remove() {
2504 fn test(back: bool) {
2505 // This test checks that every single combination of tail position and length is tested.
2506 // Capacity 15 should be large enough to cover every case.
2507 let mut tester = RingBuf::with_capacity(15);
2508 let usable_cap = tester.capacity();
2509 let final_len = usable_cap / 2;
2510
Jorge Aparicio7d661af2015-01-26 20:46:122511 for len in 0..final_len {
Piotr Czarnecki156a1c32015-01-05 14:48:582512 let expected = if back {
Jorge Aparicioc300d682015-01-26 20:44:222513 (0..len).collect()
Piotr Czarnecki156a1c32015-01-05 14:48:582514 } else {
Jorge Aparicioc300d682015-01-26 20:44:222515 (0..len).rev().collect()
Piotr Czarnecki156a1c32015-01-05 14:48:582516 };
Jorge Aparicio7d661af2015-01-26 20:46:122517 for tail_pos in 0..usable_cap {
Piotr Czarnecki156a1c32015-01-05 14:48:582518 tester.tail = tail_pos;
2519 tester.head = tail_pos;
2520 if back {
Jorge Aparicio7d661af2015-01-26 20:46:122521 for i in 0..len * 2 {
Piotr Czarnecki156a1c32015-01-05 14:48:582522 tester.push_front(i);
2523 }
Jorge Aparicio7d661af2015-01-26 20:46:122524 for i in 0..len {
Piotr Czarnecki156a1c32015-01-05 14:48:582525 assert_eq!(tester.swap_back_remove(i), Some(len * 2 - 1 - i));
2526 }
2527 } else {
Jorge Aparicio7d661af2015-01-26 20:46:122528 for i in 0..len * 2 {
Piotr Czarnecki156a1c32015-01-05 14:48:582529 tester.push_back(i);
2530 }
Jorge Aparicio7d661af2015-01-26 20:46:122531 for i in 0..len {
Piotr Czarnecki156a1c32015-01-05 14:48:582532 let idx = tester.len() - 1 - i;
2533 assert_eq!(tester.swap_front_remove(idx), Some(len * 2 - 1 - i));
2534 }
2535 }
2536 assert!(tester.tail < tester.cap);
2537 assert!(tester.head < tester.cap);
2538 assert_eq!(tester, expected);
2539 }
2540 }
2541 }
2542 test(true);
2543 test(false);
2544 }
2545
2546 #[test]
Matt Murphy40f28c72014-12-03 17:12:302547 fn test_insert() {
2548 // This test checks that every single combination of tail position, length, and
Piotr Czarnecki59d41532014-12-16 23:37:552549 // insertion position is tested. Capacity 15 should be large enough to cover every case.
Matt Murphy40f28c72014-12-03 17:12:302550
Piotr Czarnecki59d41532014-12-16 23:37:552551 let mut tester = RingBuf::with_capacity(15);
2552 // can't guarantee we got 15, so have to get what we got.
2553 // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
Matt Murphy40f28c72014-12-03 17:12:302554 // this test isn't covering what it wants to
2555 let cap = tester.capacity();
2556
2557
2558 // len is the length *after* insertion
Jorge Aparicio7d661af2015-01-26 20:46:122559 for len in 1..cap {
Matt Murphy40f28c72014-12-03 17:12:302560 // 0, 1, 2, .., len - 1
2561 let expected = iter::count(0, 1).take(len).collect();
Jorge Aparicio7d661af2015-01-26 20:46:122562 for tail_pos in 0..cap {
2563 for to_insert in 0..len {
Matt Murphy40f28c72014-12-03 17:12:302564 tester.tail = tail_pos;
2565 tester.head = tail_pos;
Jorge Aparicio7d661af2015-01-26 20:46:122566 for i in 0..len {
Matt Murphy40f28c72014-12-03 17:12:302567 if i != to_insert {
2568 tester.push_back(i);
2569 }
2570 }
2571 tester.insert(to_insert, to_insert);
Piotr Czarnecki59d41532014-12-16 23:37:552572 assert!(tester.tail < tester.cap);
2573 assert!(tester.head < tester.cap);
2574 assert_eq!(tester, expected);
2575 }
2576 }
2577 }
2578 }
2579
2580 #[test]
2581 fn test_remove() {
2582 // This test checks that every single combination of tail position, length, and
2583 // removal position is tested. Capacity 15 should be large enough to cover every case.
2584
2585 let mut tester = RingBuf::with_capacity(15);
2586 // can't guarantee we got 15, so have to get what we got.
2587 // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
2588 // this test isn't covering what it wants to
2589 let cap = tester.capacity();
2590
2591 // len is the length *after* removal
Jorge Aparicio7d661af2015-01-26 20:46:122592 for len in 0..cap - 1 {
Piotr Czarnecki59d41532014-12-16 23:37:552593 // 0, 1, 2, .., len - 1
2594 let expected = iter::count(0, 1).take(len).collect();
Jorge Aparicio7d661af2015-01-26 20:46:122595 for tail_pos in 0..cap {
2596 for to_remove in 0..len + 1 {
Piotr Czarnecki59d41532014-12-16 23:37:552597 tester.tail = tail_pos;
2598 tester.head = tail_pos;
Jorge Aparicio7d661af2015-01-26 20:46:122599 for i in 0..len {
Piotr Czarnecki59d41532014-12-16 23:37:552600 if i == to_remove {
2601 tester.push_back(1234);
2602 }
2603 tester.push_back(i);
2604 }
2605 if to_remove == len {
2606 tester.push_back(1234);
2607 }
2608 tester.remove(to_remove);
2609 assert!(tester.tail < tester.cap);
2610 assert!(tester.head < tester.cap);
Matt Murphy40f28c72014-12-03 17:12:302611 assert_eq!(tester, expected);
2612 }
2613 }
2614 }
2615 }
2616
2617 #[test]
Piotr Czarnecki156a1c32015-01-05 14:48:582618 fn test_shrink_to_fit() {
2619 // This test checks that every single combination of head and tail position,
2620 // is tested. Capacity 15 should be large enough to cover every case.
2621
2622 let mut tester = RingBuf::with_capacity(15);
2623 // can't guarantee we got 15, so have to get what we got.
2624 // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
2625 // this test isn't covering what it wants to
2626 let cap = tester.capacity();
2627 tester.reserve(63);
2628 let max_cap = tester.capacity();
2629
Jorge Aparicio7d661af2015-01-26 20:46:122630 for len in 0..cap + 1 {
Piotr Czarnecki156a1c32015-01-05 14:48:582631 // 0, 1, 2, .., len - 1
2632 let expected = iter::count(0, 1).take(len).collect();
Jorge Aparicio7d661af2015-01-26 20:46:122633 for tail_pos in 0..max_cap + 1 {
Piotr Czarnecki156a1c32015-01-05 14:48:582634 tester.tail = tail_pos;
2635 tester.head = tail_pos;
2636 tester.reserve(63);
Jorge Aparicio7d661af2015-01-26 20:46:122637 for i in 0..len {
Piotr Czarnecki156a1c32015-01-05 14:48:582638 tester.push_back(i);
2639 }
2640 tester.shrink_to_fit();
2641 assert!(tester.capacity() <= cap);
2642 assert!(tester.tail < tester.cap);
2643 assert!(tester.head < tester.cap);
2644 assert_eq!(tester, expected);
2645 }
2646 }
2647 }
2648
2649 #[test]
Matt Murphy40f28c72014-12-03 17:12:302650 fn test_front() {
2651 let mut ring = RingBuf::new();
Tobias Bucher7f64fe42015-01-25 21:05:032652 ring.push_back(10);
2653 ring.push_back(20);
Matt Murphy40f28c72014-12-03 17:12:302654 assert_eq!(ring.front(), Some(&10));
2655 ring.pop_front();
2656 assert_eq!(ring.front(), Some(&20));
2657 ring.pop_front();
2658 assert_eq!(ring.front(), None);
2659 }
Clark Gaebel525f65e2014-12-16 04:01:582660
2661 #[test]
2662 fn test_as_slices() {
Tobias Bucher7f64fe42015-01-25 21:05:032663 let mut ring: RingBuf<i32> = RingBuf::with_capacity(127);
Alex Crichton3a2530d2015-01-30 20:26:442664 let cap = ring.capacity() as i32;
Clark Gaebel525f65e2014-12-16 04:01:582665 let first = cap/2;
2666 let last = cap - first;
Jorge Aparicio7d661af2015-01-26 20:46:122667 for i in 0..first {
Clark Gaebel525f65e2014-12-16 04:01:582668 ring.push_back(i);
2669
2670 let (left, right) = ring.as_slices();
Jorge Aparicioc300d682015-01-26 20:44:222671 let expected: Vec<_> = (0..i+1).collect();
Clark Gaebel525f65e2014-12-16 04:01:582672 assert_eq!(left, expected);
2673 assert_eq!(right, []);
2674 }
2675
Jorge Aparicio7d661af2015-01-26 20:46:122676 for j in -last..0 {
Clark Gaebel525f65e2014-12-16 04:01:582677 ring.push_front(j);
2678 let (left, right) = ring.as_slices();
Jorge Aparicioc300d682015-01-26 20:44:222679 let expected_left: Vec<_> = (-last..j+1).rev().collect();
2680 let expected_right: Vec<_> = (0..first).collect();
Clark Gaebel525f65e2014-12-16 04:01:582681 assert_eq!(left, expected_left);
2682 assert_eq!(right, expected_right);
2683 }
2684
Alex Crichton3a2530d2015-01-30 20:26:442685 assert_eq!(ring.len() as i32, cap);
2686 assert_eq!(ring.capacity() as i32, cap);
Clark Gaebel525f65e2014-12-16 04:01:582687 }
2688
2689 #[test]
2690 fn test_as_mut_slices() {
Tobias Bucher7f64fe42015-01-25 21:05:032691 let mut ring: RingBuf<i32> = RingBuf::with_capacity(127);
Alex Crichton3a2530d2015-01-30 20:26:442692 let cap = ring.capacity() as i32;
Clark Gaebel525f65e2014-12-16 04:01:582693 let first = cap/2;
2694 let last = cap - first;
Jorge Aparicio7d661af2015-01-26 20:46:122695 for i in 0..first {
Clark Gaebel525f65e2014-12-16 04:01:582696 ring.push_back(i);
2697
2698 let (left, right) = ring.as_mut_slices();
Jorge Aparicioc300d682015-01-26 20:44:222699 let expected: Vec<_> = (0..i+1).collect();
Clark Gaebel525f65e2014-12-16 04:01:582700 assert_eq!(left, expected);
2701 assert_eq!(right, []);
2702 }
2703
Jorge Aparicio7d661af2015-01-26 20:46:122704 for j in -last..0 {
Clark Gaebel525f65e2014-12-16 04:01:582705 ring.push_front(j);
2706 let (left, right) = ring.as_mut_slices();
Jorge Aparicioc300d682015-01-26 20:44:222707 let expected_left: Vec<_> = (-last..j+1).rev().collect();
2708 let expected_right: Vec<_> = (0..first).collect();
Clark Gaebel525f65e2014-12-16 04:01:582709 assert_eq!(left, expected_left);
2710 assert_eq!(right, expected_right);
2711 }
2712
Alex Crichton3a2530d2015-01-30 20:26:442713 assert_eq!(ring.len() as i32, cap);
2714 assert_eq!(ring.capacity() as i32, cap);
Clark Gaebel525f65e2014-12-16 04:01:582715 }
Michael Sullivanc854d6e2012-07-03 17:52:322716}