blob: 0f04c86b7b0a273b94fdc8afeb2343116176b23a [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
Aaron Turoncb765ce2015-01-05 00:35:2015#![stable]
16
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;
Piotr Czarnecki156a1c32015-01-05 14:48:5822use core::iter::{self, repeat, FromIterator, RandomAccessIterator};
Colin Sherratt7a666df2014-10-19 20:19:0723use core::kinds::marker;
24use 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
Colin Sherratt7a666df2014-10-19 20:19:0730use std::hash::{Writer, Hash};
31use std::cmp;
32
33use alloc::heap;
blake2-ppc70523712013-07-10 13:27:1434
Piotr Czarnecki156a1c32015-01-05 14:48:5835static INITIAL_CAPACITY: uint = 7u; // 2^3 - 1
36static MINIMUM_CAPACITY: uint = 1u; // 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.
Alexis Beingessner8dbaa712014-12-31 00:07:5339#[stable]
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
47 tail: uint,
48 head: uint,
49 cap: uint,
50 ptr: *mut T
51}
52
Aaron Turon92ccc072014-12-20 08:35:0653#[stable]
Rohit Joshi8fb25ab2014-12-30 09:20:2454unsafe impl<T: Send> Send for RingBuf<T> {}
55
56#[stable]
57unsafe impl<T: Sync> Sync for RingBuf<T> {}
58
59#[stable]
Colin Sherratt7a666df2014-10-19 20:19:0760impl<T: Clone> Clone for RingBuf<T> {
61 fn clone(&self) -> RingBuf<T> {
62 self.iter().map(|t| t.clone()).collect()
63 }
64}
65
66#[unsafe_destructor]
Alexis Beingessner8dbaa712014-12-31 00:07:5367#[stable]
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
Alex Crichton9021f612014-12-16 04:04:5281#[stable]
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] {
Clark Gaebel525f65e2014-12-16 04:01:5891 mem::transmute(RawSlice { data: self.ptr as *const T, len: self.cap })
92 }
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] {
Colin Sherratt7a666df2014-10-19 20:19:0797 mem::transmute(RawSlice { data: self.ptr as *const T, len: self.cap })
98 }
99
100 /// Moves an element out of the buffer
101 #[inline]
102 unsafe fn buffer_read(&mut self, off: uint) -> T {
103 ptr::read(self.ptr.offset(off as int) as *const T)
104 }
105
106 /// Writes an element into the buffer, moving it.
107 #[inline]
108 unsafe fn buffer_write(&mut self, off: uint, t: T) {
109 ptr::write(self.ptr.offset(off as int), t);
110 }
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]
118 fn wrap_index(&self, idx: uint) -> uint { 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]
Piotr Czarnecki59d41532014-12-16 23:37:55122 unsafe fn copy(&self, dst: uint, src: uint, len: uint) {
123 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(
128 self.ptr.offset(dst as int),
Piotr Czarnecki156a1c32015-01-05 14:48:58129 self.ptr.offset(src as int),
130 len);
131 }
132
133 /// Copies a contiguous block of memory len long from src to dst
134 #[inline]
135 unsafe fn copy_nonoverlapping(&self, dst: uint, src: uint, len: uint) {
136 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(
141 self.ptr.offset(dst as int),
142 self.ptr.offset(src as int),
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`.
Alexis Beingessner8dbaa712014-12-31 00:07:53149 #[stable]
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.
Alexis Beingessner8dbaa712014-12-31 00:07:53155 #[stable]
blake2-ppc70523712013-07-10 13:27:14156 pub fn with_capacity(n: uint) -> 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();
Alex Crichtonee9921a2015-01-06 03:08:37189 /// buf.push_back(3i);
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 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53194 #[stable]
Alexis Beingessnercf3b2e42014-11-06 17:24:47195 pub fn get(&self, i: uint) -> 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);
Colin Sherratt7a666df2014-10-19 20:19:07198 unsafe { Some(&*self.ptr.offset(idx as int)) }
199 } 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();
Alex Crichtonee9921a2015-01-06 03:08:37212 /// buf.push_back(3i);
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 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53224 #[stable]
Alexis Beingessnercf3b2e42014-11-06 17:24:47225 pub fn get_mut(&mut self, i: uint) -> 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);
Colin Sherratt7a666df2014-10-19 20:19:07228 unsafe { Some(&mut *self.ptr.offset(idx as int)) }
229 } 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();
Alex Crichtonee9921a2015-01-06 03:08:37246 /// buf.push_back(3i);
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 /// ```
Chase Southwoodabf492d2014-12-19 23:53:40253 #[stable]
blake2-ppc57757a82013-09-26 07:19:26254 pub fn swap(&mut self, i: uint, j: uint) {
255 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 {
260 ptr::swap(self.ptr.offset(ri as int), self.ptr.offset(rj as int))
261 }
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 ///
272 /// let buf: RingBuf<int> = RingBuf::with_capacity(10);
Colin Sherratt7a666df2014-10-19 20:19:07273 /// assert!(buf.capacity() >= 10);
Alexis Beingessnercf3b2e42014-11-06 17:24:47274 /// ```
275 #[inline]
Alexis Beingessner8dbaa712014-12-31 00:07:53276 #[stable]
Colin Sherratt7a666df2014-10-19 20:19:07277 pub fn capacity(&self) -> uint { 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 ///
288 /// Panics if the new capacity overflows `uint`.
289 ///
jbranchaudc09defa2014-12-09 05:28:07290 /// # Examples
Alexis Beingessnercf3b2e42014-11-06 17:24:47291 ///
292 /// ```
293 /// use std::collections::RingBuf;
294 ///
295 /// let mut buf: RingBuf<int> = vec![1].into_iter().collect();
296 /// buf.reserve_exact(10);
297 /// assert!(buf.capacity() >= 11);
298 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53299 #[stable]
Alexis Beingessnercf3b2e42014-11-06 17:24:47300 pub fn reserve_exact(&mut self, additional: uint) {
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 ///
309 /// Panics if the new capacity overflows `uint`.
310 ///
jbranchaudc09defa2014-12-09 05:28:07311 /// # Examples
Alexis Beingessnercf3b2e42014-11-06 17:24:47312 ///
313 /// ```
314 /// use std::collections::RingBuf;
315 ///
316 /// let mut buf: RingBuf<int> = vec![1].into_iter().collect();
317 /// buf.reserve(10);
318 /// assert!(buf.capacity() >= 11);
319 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53320 #[stable]
Alexis Beingessnercf3b2e42014-11-06 17:24:47321 pub fn reserve(&mut self, additional: uint) {
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);
391 /// buf.extend(range(0u, 4));
392 /// 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();
476 /// buf.push_back(5i);
477 /// buf.push_back(10i);
478 /// buf.push_back(15);
479 /// buf.truncate(1);
480 /// assert_eq!(buf.len(), 1);
481 /// assert_eq!(Some(&5), buf.get(0));
482 /// ```
483 #[unstable = "matches collection reform specification; waiting on panic semantics"]
484 pub fn truncate(&mut self, len: uint) {
485 for _ in range(len, self.len()) {
486 self.pop_back();
487 }
488 }
489
P1startf2aa88c2014-08-04 10:48:39490 /// Returns a front-to-back iterator.
nhamebe80972014-07-17 23:19:51491 ///
jbranchaudc09defa2014-12-09 05:28:07492 /// # Examples
nhamebe80972014-07-17 23:19:51493 ///
494 /// ```rust
495 /// use std::collections::RingBuf;
496 ///
497 /// let mut buf = RingBuf::new();
Alex Crichtonee9921a2015-01-06 03:08:37498 /// buf.push_back(5i);
Alexis Beingessnercf3b2e42014-11-06 17:24:47499 /// buf.push_back(3);
500 /// buf.push_back(4);
Nick Cameron52ef4622014-08-06 09:59:40501 /// let b: &[_] = &[&5, &3, &4];
502 /// assert_eq!(buf.iter().collect::<Vec<&int>>().as_slice(), b);
nhamebe80972014-07-17 23:19:51503 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53504 #[stable]
Florian Wilkensf8cfd242014-12-19 20:52:10505 pub fn iter(&self) -> Iter<T> {
506 Iter {
Colin Sherratt7a666df2014-10-19 20:19:07507 tail: self.tail,
508 head: self.head,
509 ring: unsafe { self.buffer_as_slice() }
510 }
blake2-ppc3385e792013-07-15 23:13:26511 }
512
Andrew Wagner8fcc8322014-12-15 09:22:49513 /// Returns a front-to-back iterator that returns mutable references.
nhamebe80972014-07-17 23:19:51514 ///
jbranchaudc09defa2014-12-09 05:28:07515 /// # Examples
nhamebe80972014-07-17 23:19:51516 ///
517 /// ```rust
518 /// use std::collections::RingBuf;
519 ///
520 /// let mut buf = RingBuf::new();
Alex Crichtonee9921a2015-01-06 03:08:37521 /// buf.push_back(5i);
Alexis Beingessnercf3b2e42014-11-06 17:24:47522 /// buf.push_back(3);
523 /// buf.push_back(4);
Aaron Turonfc525ee2014-09-15 03:27:36524 /// for num in buf.iter_mut() {
nhamebe80972014-07-17 23:19:51525 /// *num = *num - 2;
526 /// }
Nick Cameron52ef4622014-08-06 09:59:40527 /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
Nick Cameron59976942014-09-24 11:41:09528 /// assert_eq!(buf.iter_mut().collect::<Vec<&mut int>>()[], b);
nhamebe80972014-07-17 23:19:51529 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53530 #[stable]
Florian Wilkensf8cfd242014-12-19 20:52:10531 pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> {
532 IterMut {
Colin Sherratt7a666df2014-10-19 20:19:07533 tail: self.tail,
534 head: self.head,
535 cap: self.cap,
536 ptr: self.ptr,
537 marker: marker::ContravariantLifetime::<'a>,
Niko Matsakisbc4164d2013-11-16 22:29:39538 }
Jed Estep4f7a7422013-06-25 19:08:47539 }
Alex Crichton21ac9852014-10-30 20:43:24540
Alexis Beingessner865c2db2014-11-23 02:34:11541 /// Consumes the list into an iterator yielding elements by value.
Alexis Beingessner8dbaa712014-12-31 00:07:53542 #[stable]
Florian Wilkensf8cfd242014-12-19 20:52:10543 pub fn into_iter(self) -> IntoIter<T> {
544 IntoIter {
Alexis Beingessner865c2db2014-11-23 02:34:11545 inner: self,
546 }
547 }
548
Clark Gaebel525f65e2014-12-16 04:01:58549 /// Returns a pair of slices which contain, in order, the contents of the
550 /// `RingBuf`.
551 #[inline]
552 #[unstable = "matches collection reform specification, waiting for dust to settle"]
553 pub fn as_slices<'a>(&'a self) -> (&'a [T], &'a [T]) {
554 unsafe {
555 let contiguous = self.is_contiguous();
556 let buf = self.buffer_as_slice();
557 if contiguous {
558 let (empty, buf) = buf.split_at(0);
559 (buf[self.tail..self.head], empty)
560 } else {
561 let (mid, right) = buf.split_at(self.tail);
562 let (left, _) = mid.split_at(self.head);
563 (right, left)
564 }
565 }
566 }
567
568 /// Returns a pair of slices which contain, in order, the contents of the
569 /// `RingBuf`.
570 #[inline]
571 #[unstable = "matches collection reform specification, waiting for dust to settle"]
572 pub fn as_mut_slices<'a>(&'a mut self) -> (&'a mut [T], &'a mut [T]) {
573 unsafe {
574 let contiguous = self.is_contiguous();
575 let head = self.head;
576 let tail = self.tail;
577 let buf = self.buffer_as_mut_slice();
578
579 if contiguous {
580 let (empty, buf) = buf.split_at_mut(0);
Nick Cameron113f8aa2014-12-23 03:23:11581 (buf.slice_mut(tail, head), empty)
Clark Gaebel525f65e2014-12-16 04:01:58582 } else {
583 let (mid, right) = buf.split_at_mut(tail);
584 let (left, _) = mid.split_at_mut(head);
585
586 (right, left)
587 }
588 }
589 }
590
Alex Crichton21ac9852014-10-30 20:43:24591 /// Returns the number of elements in the `RingBuf`.
592 ///
jbranchaudc09defa2014-12-09 05:28:07593 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24594 ///
595 /// ```
596 /// use std::collections::RingBuf;
597 ///
598 /// let mut v = RingBuf::new();
599 /// assert_eq!(v.len(), 0);
Alex Crichtonee9921a2015-01-06 03:08:37600 /// v.push_back(1i);
Alex Crichton21ac9852014-10-30 20:43:24601 /// assert_eq!(v.len(), 1);
602 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53603 #[stable]
Colin Sherratt7a666df2014-10-19 20:19:07604 pub fn len(&self) -> uint { count(self.tail, self.head, self.cap) }
Alex Crichton21ac9852014-10-30 20:43:24605
606 /// Returns true if the buffer contains no elements
607 ///
jbranchaudc09defa2014-12-09 05:28:07608 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24609 ///
610 /// ```
611 /// use std::collections::RingBuf;
612 ///
613 /// let mut v = RingBuf::new();
614 /// assert!(v.is_empty());
Alex Crichtonee9921a2015-01-06 03:08:37615 /// v.push_front(1i);
Alex Crichton21ac9852014-10-30 20:43:24616 /// assert!(!v.is_empty());
617 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53618 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24619 pub fn is_empty(&self) -> bool { self.len() == 0 }
620
Clark Gaebeld57f2592014-12-16 22:45:03621 /// Creates a draining iterator that clears the `RingBuf` and iterates over
622 /// the removed items from start to end.
623 ///
624 /// # Examples
625 ///
626 /// ```
627 /// use std::collections::RingBuf;
628 ///
629 /// let mut v = RingBuf::new();
Alex Crichtonee9921a2015-01-06 03:08:37630 /// v.push_back(1i);
Clark Gaebeld57f2592014-12-16 22:45:03631 /// assert_eq!(v.drain().next(), Some(1));
632 /// assert!(v.is_empty());
633 /// ```
634 #[inline]
635 #[unstable = "matches collection reform specification, waiting for dust to settle"]
Alexis Beingessner8dbaa712014-12-31 00:07:53636 pub fn drain(&mut self) -> Drain<T> {
Clark Gaebeld57f2592014-12-16 22:45:03637 Drain {
638 inner: self,
639 }
640 }
641
Alex Crichton21ac9852014-10-30 20:43:24642 /// Clears the buffer, removing all values.
643 ///
jbranchaudc09defa2014-12-09 05:28:07644 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24645 ///
646 /// ```
647 /// use std::collections::RingBuf;
648 ///
649 /// let mut v = RingBuf::new();
Alex Crichtonee9921a2015-01-06 03:08:37650 /// v.push_back(1i);
Alex Crichton21ac9852014-10-30 20:43:24651 /// v.clear();
652 /// assert!(v.is_empty());
653 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53654 #[stable]
Clark Gaebeld57f2592014-12-16 22:45:03655 #[inline]
Alex Crichton21ac9852014-10-30 20:43:24656 pub fn clear(&mut self) {
Clark Gaebeld57f2592014-12-16 22:45:03657 self.drain();
Alex Crichton21ac9852014-10-30 20:43:24658 }
659
660 /// Provides a reference to the front element, or `None` if the sequence is
661 /// empty.
662 ///
jbranchaudc09defa2014-12-09 05:28:07663 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24664 ///
665 /// ```
666 /// use std::collections::RingBuf;
667 ///
668 /// let mut d = RingBuf::new();
669 /// assert_eq!(d.front(), None);
670 ///
Alex Crichtonee9921a2015-01-06 03:08:37671 /// d.push_back(1i);
672 /// d.push_back(2i);
673 /// assert_eq!(d.front(), Some(&1i));
Alex Crichton21ac9852014-10-30 20:43:24674 /// ```
Chase Southwoodabf492d2014-12-19 23:53:40675 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24676 pub fn front(&self) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07677 if !self.is_empty() { Some(&self[0]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24678 }
679
680 /// Provides a mutable reference to the front element, or `None` if the
681 /// sequence is empty.
682 ///
jbranchaudc09defa2014-12-09 05:28:07683 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24684 ///
685 /// ```
686 /// use std::collections::RingBuf;
687 ///
688 /// let mut d = RingBuf::new();
689 /// assert_eq!(d.front_mut(), None);
690 ///
Alex Crichtonee9921a2015-01-06 03:08:37691 /// d.push_back(1i);
692 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24693 /// match d.front_mut() {
Alex Crichtonee9921a2015-01-06 03:08:37694 /// Some(x) => *x = 9i,
Alex Crichton21ac9852014-10-30 20:43:24695 /// None => (),
696 /// }
Alex Crichtonee9921a2015-01-06 03:08:37697 /// assert_eq!(d.front(), Some(&9i));
Alex Crichton21ac9852014-10-30 20:43:24698 /// ```
Chase Southwoodabf492d2014-12-19 23:53:40699 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24700 pub fn front_mut(&mut self) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07701 if !self.is_empty() { Some(&mut self[0]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24702 }
703
704 /// Provides a reference to the back element, or `None` if the sequence is
705 /// empty.
706 ///
jbranchaudc09defa2014-12-09 05:28:07707 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24708 ///
709 /// ```
710 /// use std::collections::RingBuf;
711 ///
712 /// let mut d = RingBuf::new();
713 /// assert_eq!(d.back(), None);
714 ///
Alex Crichtonee9921a2015-01-06 03:08:37715 /// d.push_back(1i);
716 /// d.push_back(2i);
717 /// assert_eq!(d.back(), Some(&2i));
Alex Crichton21ac9852014-10-30 20:43:24718 /// ```
Chase Southwoodabf492d2014-12-19 23:53:40719 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24720 pub fn back(&self) -> Option<&T> {
Colin Sherratt7a666df2014-10-19 20:19:07721 if !self.is_empty() { Some(&self[self.len() - 1]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24722 }
723
724 /// Provides a mutable reference to the back element, or `None` if the
725 /// sequence is empty.
726 ///
jbranchaudc09defa2014-12-09 05:28:07727 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24728 ///
729 /// ```
730 /// use std::collections::RingBuf;
731 ///
732 /// let mut d = RingBuf::new();
733 /// assert_eq!(d.back(), None);
734 ///
Alex Crichtonee9921a2015-01-06 03:08:37735 /// d.push_back(1i);
736 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24737 /// match d.back_mut() {
Alex Crichtonee9921a2015-01-06 03:08:37738 /// Some(x) => *x = 9i,
Alex Crichton21ac9852014-10-30 20:43:24739 /// None => (),
740 /// }
Alex Crichtonee9921a2015-01-06 03:08:37741 /// assert_eq!(d.back(), Some(&9i));
Alex Crichton21ac9852014-10-30 20:43:24742 /// ```
Chase Southwoodabf492d2014-12-19 23:53:40743 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24744 pub fn back_mut(&mut self) -> Option<&mut T> {
Colin Sherratt7a666df2014-10-19 20:19:07745 let len = self.len();
746 if !self.is_empty() { Some(&mut self[len - 1]) } else { None }
Alex Crichton21ac9852014-10-30 20:43:24747 }
748
749 /// Removes the first element and returns it, or `None` if the sequence is
750 /// empty.
751 ///
jbranchaudc09defa2014-12-09 05:28:07752 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24753 ///
754 /// ```
755 /// use std::collections::RingBuf;
756 ///
757 /// let mut d = RingBuf::new();
Alex Crichtonee9921a2015-01-06 03:08:37758 /// d.push_back(1i);
759 /// d.push_back(2i);
Alex Crichton21ac9852014-10-30 20:43:24760 ///
Alex Crichtonee9921a2015-01-06 03:08:37761 /// assert_eq!(d.pop_front(), Some(1i));
762 /// assert_eq!(d.pop_front(), Some(2i));
Alex Crichton21ac9852014-10-30 20:43:24763 /// assert_eq!(d.pop_front(), None);
764 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53765 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24766 pub fn pop_front(&mut self) -> Option<T> {
Colin Sherratt7a666df2014-10-19 20:19:07767 if self.is_empty() {
768 None
769 } else {
770 let tail = self.tail;
Colin Sherratt40191182014-11-12 01:22:07771 self.tail = self.wrap_index(self.tail + 1);
Colin Sherratt7a666df2014-10-19 20:19:07772 unsafe { Some(self.buffer_read(tail)) }
Alex Crichton21ac9852014-10-30 20:43:24773 }
Alex Crichton21ac9852014-10-30 20:43:24774 }
775
776 /// Inserts an element first in the sequence.
777 ///
jbranchaudc09defa2014-12-09 05:28:07778 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24779 ///
780 /// ```
781 /// use std::collections::RingBuf;
782 ///
783 /// let mut d = RingBuf::new();
Alex Crichtonee9921a2015-01-06 03:08:37784 /// d.push_front(1i);
785 /// d.push_front(2i);
786 /// assert_eq!(d.front(), Some(&2i));
Alex Crichton21ac9852014-10-30 20:43:24787 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53788 #[stable]
Alex Crichton21ac9852014-10-30 20:43:24789 pub fn push_front(&mut self, t: T) {
Colin Sherratt4cae9ad2014-11-11 02:16:29790 if self.is_full() {
791 self.reserve(1);
792 debug_assert!(!self.is_full());
793 }
Colin Sherratt7a666df2014-10-19 20:19:07794
Colin Sherratt40191182014-11-12 01:22:07795 self.tail = self.wrap_index(self.tail - 1);
Colin Sherratt7a666df2014-10-19 20:19:07796 let tail = self.tail;
797 unsafe { self.buffer_write(tail, t); }
Alex Crichton21ac9852014-10-30 20:43:24798 }
799
Alex Crichton21ac9852014-10-30 20:43:24800 /// Appends an element to the back of a buffer
801 ///
jbranchaudc09defa2014-12-09 05:28:07802 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24803 ///
804 /// ```rust
805 /// use std::collections::RingBuf;
806 ///
807 /// let mut buf = RingBuf::new();
Alex Crichtonee9921a2015-01-06 03:08:37808 /// buf.push_back(1i);
Alexis Beingessnercf3b2e42014-11-06 17:24:47809 /// buf.push_back(3);
Alex Crichton21ac9852014-10-30 20:43:24810 /// assert_eq!(3, *buf.back().unwrap());
811 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53812 #[stable]
Alexis Beingessnercf3b2e42014-11-06 17:24:47813 pub fn push_back(&mut self, t: T) {
Colin Sherratt4cae9ad2014-11-11 02:16:29814 if self.is_full() {
815 self.reserve(1);
816 debug_assert!(!self.is_full());
817 }
Colin Sherratt7a666df2014-10-19 20:19:07818
819 let head = self.head;
Colin Sherratt40191182014-11-12 01:22:07820 self.head = self.wrap_index(self.head + 1);
Colin Sherratt7a666df2014-10-19 20:19:07821 unsafe { self.buffer_write(head, t) }
Alex Crichton21ac9852014-10-30 20:43:24822 }
823
Alex Crichton21ac9852014-10-30 20:43:24824 /// Removes the last element from a buffer and returns it, or `None` if
825 /// it is empty.
826 ///
jbranchaudc09defa2014-12-09 05:28:07827 /// # Examples
Alex Crichton21ac9852014-10-30 20:43:24828 ///
829 /// ```rust
830 /// use std::collections::RingBuf;
831 ///
832 /// let mut buf = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:47833 /// assert_eq!(buf.pop_back(), None);
Alex Crichtonee9921a2015-01-06 03:08:37834 /// buf.push_back(1i);
Alexis Beingessnercf3b2e42014-11-06 17:24:47835 /// buf.push_back(3);
836 /// assert_eq!(buf.pop_back(), Some(3));
Alex Crichton21ac9852014-10-30 20:43:24837 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:53838 #[stable]
Alexis Beingessnercf3b2e42014-11-06 17:24:47839 pub fn pop_back(&mut self) -> Option<T> {
Colin Sherratt7a666df2014-10-19 20:19:07840 if self.is_empty() {
Alex Crichton21ac9852014-10-30 20:43:24841 None
Colin Sherratt7a666df2014-10-19 20:19:07842 } else {
Colin Sherratt40191182014-11-12 01:22:07843 self.head = self.wrap_index(self.head - 1);
Colin Sherratt7a666df2014-10-19 20:19:07844 let head = self.head;
845 unsafe { Some(self.buffer_read(head)) }
Alex Crichton21ac9852014-10-30 20:43:24846 }
847 }
Matt Murphy40f28c72014-12-03 17:12:30848
Clark Gaebel525f65e2014-12-16 04:01:58849 #[inline]
850 fn is_contiguous(&self) -> bool {
851 self.tail <= self.head
852 }
853
Piotr Czarnecki156a1c32015-01-05 14:48:58854 /// Removes an element from anywhere in the ringbuf and returns it, replacing it with the last
855 /// element.
856 ///
857 /// This does not preserve ordering, but is O(1).
858 ///
859 /// Returns `None` if `index` is out of bounds.
860 ///
861 /// # Examples
862 ///
863 /// ```
864 /// use std::collections::RingBuf;
865 ///
866 /// let mut buf = RingBuf::new();
867 /// assert_eq!(buf.swap_back_remove(0), None);
868 /// buf.push_back(5i);
869 /// buf.push_back(99);
870 /// buf.push_back(15);
871 /// buf.push_back(20);
872 /// buf.push_back(10);
873 /// assert_eq!(buf.swap_back_remove(1), Some(99));
874 /// ```
875 #[unstable = "the naming of this function may be altered"]
876 pub fn swap_back_remove(&mut self, index: uint) -> Option<T> {
877 let length = self.len();
878 if length > 0 && index < length - 1 {
879 self.swap(index, length - 1);
880 } else if index >= length {
881 return None;
882 }
883 self.pop_back()
884 }
885
886 /// Removes an element from anywhere in the ringbuf and returns it, replacing it with the first
887 /// element.
888 ///
889 /// This does not preserve ordering, but is O(1).
890 ///
891 /// Returns `None` if `index` is out of bounds.
892 ///
893 /// # Examples
894 ///
895 /// ```
896 /// use std::collections::RingBuf;
897 ///
898 /// let mut buf = RingBuf::new();
899 /// assert_eq!(buf.swap_front_remove(0), None);
900 /// buf.push_back(15i);
901 /// buf.push_back(5);
902 /// buf.push_back(10);
903 /// buf.push_back(99);
904 /// buf.push_back(20i);
905 /// assert_eq!(buf.swap_front_remove(3), Some(99));
906 /// ```
907 #[unstable = "the naming of this function may be altered"]
908 pub fn swap_front_remove(&mut self, index: uint) -> Option<T> {
909 let length = self.len();
910 if length > 0 && index < length && index != 0 {
911 self.swap(index, 0);
912 } else if index >= length {
913 return None;
914 }
915 self.pop_front()
916 }
917
Matt Murphy40f28c72014-12-03 17:12:30918 /// Inserts an element at position `i` within the ringbuf. Whichever
919 /// end is closer to the insertion point will be moved to make room,
920 /// and all the affected elements will be moved to new positions.
921 ///
922 /// # Panics
923 ///
924 /// Panics if `i` is greater than ringbuf's length
925 ///
Piotr Czarnecki156a1c32015-01-05 14:48:58926 /// # Examples
Matt Murphy40f28c72014-12-03 17:12:30927 /// ```rust
928 /// use std::collections::RingBuf;
929 ///
930 /// let mut buf = RingBuf::new();
Alex Crichtonee9921a2015-01-06 03:08:37931 /// buf.push_back(10i);
Matt Murphy40f28c72014-12-03 17:12:30932 /// buf.push_back(12);
933 /// buf.insert(1,11);
934 /// assert_eq!(Some(&11), buf.get(1));
935 /// ```
936 pub fn insert(&mut self, i: uint, t: T) {
937 assert!(i <= self.len(), "index out of bounds");
938 if self.is_full() {
939 self.reserve(1);
940 debug_assert!(!self.is_full());
941 }
942
943 // Move the least number of elements in the ring buffer and insert
944 // the given object
945 //
946 // At most len/2 - 1 elements will be moved. O(min(n, n-i))
947 //
948 // There are three main cases:
949 // Elements are contiguous
950 // - special case when tail is 0
951 // Elements are discontiguous and the insert is in the tail section
952 // Elements are discontiguous and the insert is in the head section
953 //
954 // For each of those there are two more cases:
955 // Insert is closer to tail
956 // Insert is closer to head
957 //
958 // Key: H - self.head
959 // T - self.tail
960 // o - Valid element
961 // I - Insertion element
962 // A - The element that should be after the insertion point
963 // M - Indicates element was moved
964
965 let idx = self.wrap_index(self.tail + i);
966
967 let distance_to_tail = i;
968 let distance_to_head = self.len() - i;
969
Clark Gaebel525f65e2014-12-16 04:01:58970 let contiguous = self.is_contiguous();
Matt Murphy40f28c72014-12-03 17:12:30971
972 match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
973 (true, true, _) if i == 0 => {
974 // push_front
975 //
976 // T
977 // I H
978 // [A o o o o o o . . . . . . . . .]
979 //
980 // H T
981 // [A o o o o o o o . . . . . I]
982 //
983
984 self.tail = self.wrap_index(self.tail - 1);
985 },
Piotr Czarnecki59d41532014-12-16 23:37:55986 (true, true, _) => unsafe {
Matt Murphy40f28c72014-12-03 17:12:30987 // contiguous, insert closer to tail:
988 //
989 // T I H
990 // [. . . o o A o o o o . . . . . .]
991 //
992 // T H
993 // [. . o o I A o o o o . . . . . .]
994 // M M
995 //
996 // contiguous, insert closer to tail and tail is 0:
997 //
998 //
999 // T I H
1000 // [o o A o o o o . . . . . . . . .]
1001 //
1002 // H T
1003 // [o I A o o o o o . . . . . . . o]
1004 // M M
1005
Piotr Czarnecki59d41532014-12-16 23:37:551006 let new_tail = self.wrap_index(self.tail - 1);
Matt Murphy40f28c72014-12-03 17:12:301007
Piotr Czarnecki59d41532014-12-16 23:37:551008 self.copy(new_tail, self.tail, 1);
1009 // Already moved the tail, so we only copy `i - 1` elements.
1010 self.copy(self.tail, self.tail + 1, i - 1);
1011
1012 self.tail = new_tail;
Matt Murphy40f28c72014-12-03 17:12:301013 },
Piotr Czarnecki59d41532014-12-16 23:37:551014 (true, false, _) => unsafe {
Matt Murphy40f28c72014-12-03 17:12:301015 // contiguous, insert closer to head:
1016 //
1017 // T I H
1018 // [. . . o o o o A o o . . . . . .]
1019 //
1020 // T H
1021 // [. . . o o o o I A o o . . . . .]
1022 // M M M
1023
Piotr Czarnecki59d41532014-12-16 23:37:551024 self.copy(idx + 1, idx, self.head - idx);
Matt Murphy40f28c72014-12-03 17:12:301025 self.head = self.wrap_index(self.head + 1);
Matt Murphy40f28c72014-12-03 17:12:301026 },
Piotr Czarnecki59d41532014-12-16 23:37:551027 (false, true, true) => unsafe {
1028 // discontiguous, insert closer to tail, tail section:
Matt Murphy40f28c72014-12-03 17:12:301029 //
1030 // H T I
1031 // [o o o o o o . . . . . o o A o o]
1032 //
1033 // H T
1034 // [o o o o o o . . . . o o I A o o]
1035 // M M
1036
Piotr Czarnecki59d41532014-12-16 23:37:551037 self.copy(self.tail - 1, self.tail, i);
1038 self.tail -= 1;
Matt Murphy40f28c72014-12-03 17:12:301039 },
Piotr Czarnecki59d41532014-12-16 23:37:551040 (false, false, true) => unsafe {
1041 // discontiguous, insert closer to head, tail section:
Matt Murphy40f28c72014-12-03 17:12:301042 //
1043 // H T I
1044 // [o o . . . . . . . o o o o o A o]
1045 //
1046 // H T
1047 // [o o o . . . . . . o o o o o I A]
1048 // M M M M
1049
Matt Murphy40f28c72014-12-03 17:12:301050 // copy elements up to new head
Piotr Czarnecki59d41532014-12-16 23:37:551051 self.copy(1, 0, self.head);
Matt Murphy40f28c72014-12-03 17:12:301052
1053 // copy last element into empty spot at bottom of buffer
1054 self.copy(0, self.cap - 1, 1);
1055
1056 // move elements from idx to end forward not including ^ element
1057 self.copy(idx + 1, idx, self.cap - 1 - idx);
Piotr Czarnecki59d41532014-12-16 23:37:551058
1059 self.head += 1;
Matt Murphy40f28c72014-12-03 17:12:301060 },
Piotr Czarnecki59d41532014-12-16 23:37:551061 (false, true, false) if idx == 0 => unsafe {
1062 // discontiguous, insert is closer to tail, head section,
Matt Murphy40f28c72014-12-03 17:12:301063 // and is at index zero in the internal buffer:
1064 //
1065 // I H T
1066 // [A o o o o o o o o o . . . o o o]
1067 //
1068 // H T
1069 // [A o o o o o o o o o . . o o o I]
1070 // M M M
1071
Matt Murphy40f28c72014-12-03 17:12:301072 // copy elements up to new tail
Piotr Czarnecki59d41532014-12-16 23:37:551073 self.copy(self.tail - 1, self.tail, self.cap - self.tail);
Matt Murphy40f28c72014-12-03 17:12:301074
1075 // copy last element into empty spot at bottom of buffer
1076 self.copy(self.cap - 1, 0, 1);
Piotr Czarnecki59d41532014-12-16 23:37:551077
1078 self.tail -= 1;
Matt Murphy40f28c72014-12-03 17:12:301079 },
Piotr Czarnecki59d41532014-12-16 23:37:551080 (false, true, false) => unsafe {
1081 // discontiguous, insert closer to tail, head section:
Matt Murphy40f28c72014-12-03 17:12:301082 //
1083 // I H T
1084 // [o o o A o o o o o o . . . o o o]
1085 //
1086 // H T
1087 // [o o I A o o o o o o . . o o o o]
1088 // M M M M M M
1089
Matt Murphy40f28c72014-12-03 17:12:301090 // copy elements up to new tail
Piotr Czarnecki59d41532014-12-16 23:37:551091 self.copy(self.tail - 1, self.tail, self.cap - self.tail);
Matt Murphy40f28c72014-12-03 17:12:301092
1093 // copy last element into empty spot at bottom of buffer
1094 self.copy(self.cap - 1, 0, 1);
1095
1096 // move elements from idx-1 to end forward not including ^ element
1097 self.copy(0, 1, idx - 1);
Piotr Czarnecki59d41532014-12-16 23:37:551098
1099 self.tail -= 1;
1100 },
1101 (false, false, false) => unsafe {
1102 // discontiguous, insert closer to head, head section:
Matt Murphy40f28c72014-12-03 17:12:301103 //
1104 // I H T
1105 // [o o o o A o o . . . . . . o o o]
1106 //
1107 // H T
1108 // [o o o o I A o o . . . . . o o o]
1109 // M M M
1110
Piotr Czarnecki59d41532014-12-16 23:37:551111 self.copy(idx + 1, idx, self.head - idx);
1112 self.head += 1;
Matt Murphy40f28c72014-12-03 17:12:301113 }
1114 }
1115
1116 // tail might've been changed so we need to recalculate
1117 let new_idx = self.wrap_index(self.tail + i);
1118 unsafe {
1119 self.buffer_write(new_idx, t);
1120 }
1121 }
Piotr Czarnecki59d41532014-12-16 23:37:551122
1123 /// Removes and returns the element at position `i` from the ringbuf.
1124 /// Whichever end is closer to the removal point will be moved to make
1125 /// room, and all the affected elements will be moved to new positions.
1126 /// Returns `None` if `i` is out of bounds.
1127 ///
Piotr Czarnecki156a1c32015-01-05 14:48:581128 /// # Examples
Piotr Czarnecki59d41532014-12-16 23:37:551129 /// ```rust
1130 /// use std::collections::RingBuf;
1131 ///
1132 /// let mut buf = RingBuf::new();
Alex Crichtonee9921a2015-01-06 03:08:371133 /// buf.push_back(5i);
1134 /// buf.push_back(10i);
1135 /// buf.push_back(12i);
Piotr Czarnecki59d41532014-12-16 23:37:551136 /// buf.push_back(15);
1137 /// buf.remove(2);
1138 /// assert_eq!(Some(&15), buf.get(2));
1139 /// ```
Alexis Beingessner8dbaa712014-12-31 00:07:531140 #[stable]
Piotr Czarnecki59d41532014-12-16 23:37:551141 pub fn remove(&mut self, i: uint) -> Option<T> {
1142 if self.is_empty() || self.len() <= i {
1143 return None;
1144 }
1145
1146 // There are three main cases:
1147 // Elements are contiguous
1148 // Elements are discontiguous and the removal is in the tail section
1149 // Elements are discontiguous and the removal is in the head section
1150 // - special case when elements are technically contiguous,
1151 // but self.head = 0
1152 //
1153 // For each of those there are two more cases:
1154 // Insert is closer to tail
1155 // Insert is closer to head
1156 //
1157 // Key: H - self.head
1158 // T - self.tail
1159 // o - Valid element
1160 // x - Element marked for removal
1161 // R - Indicates element that is being removed
1162 // M - Indicates element was moved
1163
1164 let idx = self.wrap_index(self.tail + i);
1165
1166 let elem = unsafe {
1167 Some(self.buffer_read(idx))
1168 };
1169
1170 let distance_to_tail = i;
1171 let distance_to_head = self.len() - i;
1172
Piotr Czarnecki156a1c32015-01-05 14:48:581173 let contiguous = self.is_contiguous();
Piotr Czarnecki59d41532014-12-16 23:37:551174
1175 match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
1176 (true, true, _) => unsafe {
1177 // contiguous, remove closer to tail:
1178 //
1179 // T R H
1180 // [. . . o o x o o o o . . . . . .]
1181 //
1182 // T H
1183 // [. . . . o o o o o o . . . . . .]
1184 // M M
1185
1186 self.copy(self.tail + 1, self.tail, i);
1187 self.tail += 1;
1188 },
1189 (true, false, _) => unsafe {
1190 // contiguous, remove closer to head:
1191 //
1192 // T R H
1193 // [. . . o o o o x o o . . . . . .]
1194 //
1195 // T H
1196 // [. . . o o o o o o . . . . . . .]
1197 // M M
1198
1199 self.copy(idx, idx + 1, self.head - idx - 1);
1200 self.head -= 1;
1201 },
1202 (false, true, true) => unsafe {
1203 // discontiguous, remove closer to tail, tail section:
1204 //
1205 // H T R
1206 // [o o o o o o . . . . . o o x o o]
1207 //
1208 // H T
1209 // [o o o o o o . . . . . . o o o o]
1210 // M M
1211
1212 self.copy(self.tail + 1, self.tail, i);
1213 self.tail = self.wrap_index(self.tail + 1);
1214 },
1215 (false, false, false) => unsafe {
1216 // discontiguous, remove closer to head, head section:
1217 //
1218 // R H T
1219 // [o o o o x o o . . . . . . o o o]
1220 //
1221 // H T
1222 // [o o o o o o . . . . . . . o o o]
1223 // M M
1224
1225 self.copy(idx, idx + 1, self.head - idx - 1);
1226 self.head -= 1;
1227 },
1228 (false, false, true) => unsafe {
1229 // discontiguous, remove closer to head, tail section:
1230 //
1231 // H T R
1232 // [o o o . . . . . . o o o o o x o]
1233 //
1234 // H T
1235 // [o o . . . . . . . o o o o o o o]
1236 // M M M M
1237 //
1238 // or quasi-discontiguous, remove next to head, tail section:
1239 //
1240 // H T R
1241 // [. . . . . . . . . o o o o o x o]
1242 //
1243 // T H
1244 // [. . . . . . . . . o o o o o o .]
1245 // M
1246
1247 // draw in elements in the tail section
1248 self.copy(idx, idx + 1, self.cap - idx - 1);
1249
1250 // Prevents underflow.
1251 if self.head != 0 {
1252 // copy first element into empty spot
1253 self.copy(self.cap - 1, 0, 1);
1254
1255 // move elements in the head section backwards
1256 self.copy(0, 1, self.head - 1);
1257 }
1258
1259 self.head = self.wrap_index(self.head - 1);
1260 },
1261 (false, true, false) => unsafe {
1262 // discontiguous, remove closer to tail, head section:
1263 //
1264 // R H T
1265 // [o o x o o o o o o o . . . o o o]
1266 //
1267 // H T
1268 // [o o o o o o o o o o . . . . o o]
1269 // M M M M M
1270
1271 // draw in elements up to idx
1272 self.copy(1, 0, idx);
1273
1274 // copy last element into empty spot
1275 self.copy(0, self.cap - 1, 1);
1276
1277 // move elements from tail to end forward, excluding the last one
1278 self.copy(self.tail + 1, self.tail, self.cap - self.tail - 1);
1279
1280 self.tail = self.wrap_index(self.tail + 1);
1281 }
1282 }
1283
1284 return elem;
1285 }
Jed Estep4f7a7422013-06-25 19:08:471286}
1287
Piotr Czarnecki156a1c32015-01-05 14:48:581288impl<T: Clone> RingBuf<T> {
1289 /// Modifies the ringbuf in-place so that `len()` is equal to new_len,
1290 /// either by removing excess elements or by appending copies of a value to the back.
1291 ///
1292 /// # Examples
1293 ///
1294 /// ```
1295 /// use std::collections::RingBuf;
1296 ///
1297 /// let mut buf = RingBuf::new();
1298 /// buf.push_back(5i);
1299 /// buf.push_back(10i);
1300 /// buf.push_back(15);
1301 /// buf.resize(2, 0);
1302 /// buf.resize(6, 20);
1303 /// for (a, b) in [5, 10, 20, 20, 20, 20].iter().zip(buf.iter()) {
1304 /// assert_eq!(a, b);
1305 /// }
1306 /// ```
1307 #[unstable = "matches collection reform specification; waiting on panic semantics"]
1308 pub fn resize(&mut self, new_len: uint, value: T) {
1309 let len = self.len();
1310
1311 if new_len > len {
1312 self.extend(repeat(value).take(new_len - len))
1313 } else {
1314 self.truncate(new_len);
1315 }
1316 }
1317}
1318
Colin Sherratt7a666df2014-10-19 20:19:071319/// Returns the index in the underlying buffer for a given logical element index.
1320#[inline]
1321fn wrap_index(index: uint, size: uint) -> uint {
1322 // size is always a power of 2
Colin Sherratt40191182014-11-12 01:22:071323 index & (size - 1)
Colin Sherratt7a666df2014-10-19 20:19:071324}
1325
1326/// Calculate the number of elements left to be read in the buffer
1327#[inline]
1328fn count(tail: uint, head: uint, size: uint) -> uint {
1329 // size is always a power of 2
1330 (head - tail) & (size - 1)
1331}
1332
Niko Matsakis1b487a82014-08-28 01:46:521333/// `RingBuf` iterator.
Alexis Beingessner8dbaa712014-12-31 00:07:531334#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101335pub struct Iter<'a, T:'a> {
Colin Sherratt7a666df2014-10-19 20:19:071336 ring: &'a [T],
1337 tail: uint,
1338 head: uint
Niko Matsakis1b487a82014-08-28 01:46:521339}
1340
Jorge Aparicio351409a2015-01-04 03:54:181341// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
Huon Wilsonb7832ed2014-12-30 10:01:361342impl<'a, T> Clone for Iter<'a, T> {
1343 fn clone(&self) -> Iter<'a, T> {
1344 Iter {
1345 ring: self.ring,
1346 tail: self.tail,
1347 head: self.head
1348 }
1349 }
1350}
1351
Alexis Beingessner8dbaa712014-12-31 00:07:531352#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351353impl<'a, T> Iterator for Iter<'a, T> {
1354 type Item = &'a T;
1355
Niko Matsakisbc4164d2013-11-16 22:29:391356 #[inline]
Erik Price5731ca32013-12-10 07:16:181357 fn next(&mut self) -> Option<&'a T> {
Colin Sherratt7a666df2014-10-19 20:19:071358 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:391359 return None;
1360 }
Colin Sherratt7a666df2014-10-19 20:19:071361 let tail = self.tail;
1362 self.tail = wrap_index(self.tail + 1, self.ring.len());
Aaron Turon6abfac02014-12-30 18:51:181363 unsafe { Some(self.ring.get_unchecked(tail)) }
Niko Matsakisbc4164d2013-11-16 22:29:391364 }
1365
1366 #[inline]
1367 fn size_hint(&self) -> (uint, Option<uint>) {
Colin Sherratt7a666df2014-10-19 20:19:071368 let len = count(self.tail, self.head, self.ring.len());
Niko Matsakisbc4164d2013-11-16 22:29:391369 (len, Some(len))
1370 }
1371}
1372
Alexis Beingessner8dbaa712014-12-31 00:07:531373#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351374impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:391375 #[inline]
Erik Price5731ca32013-12-10 07:16:181376 fn next_back(&mut self) -> Option<&'a T> {
Colin Sherratt7a666df2014-10-19 20:19:071377 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:391378 return None;
1379 }
Colin Sherratt7a666df2014-10-19 20:19:071380 self.head = wrap_index(self.head - 1, self.ring.len());
Aaron Turon6abfac02014-12-30 18:51:181381 unsafe { Some(self.ring.get_unchecked(self.head)) }
Niko Matsakisbc4164d2013-11-16 22:29:391382 }
1383}
Jed Estep35314c92013-06-26 15:38:291384
Alexis Beingessner8dbaa712014-12-31 00:07:531385#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351386impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
blake2-ppc7c369ee72013-09-01 16:20:241387
Alexis Beingessner8dbaa712014-12-31 00:07:531388#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351389impl<'a, T> RandomAccessIterator for Iter<'a, T> {
blake2-ppcf6862132013-07-29 18:16:261390 #[inline]
Colin Sherratt7a666df2014-10-19 20:19:071391 fn indexable(&self) -> uint {
1392 let (len, _) = self.size_hint();
1393 len
1394 }
blake2-ppcf6862132013-07-29 18:16:261395
1396 #[inline]
Alex Crichtonf4083a22014-04-22 05:15:421397 fn idx(&mut self, j: uint) -> Option<&'a T> {
blake2-ppcf6862132013-07-29 18:16:261398 if j >= self.indexable() {
1399 None
1400 } else {
Colin Sherratt7a666df2014-10-19 20:19:071401 let idx = wrap_index(self.tail + j, self.ring.len());
Aaron Turon6abfac02014-12-30 18:51:181402 unsafe { Some(self.ring.get_unchecked(idx)) }
blake2-ppcf6862132013-07-29 18:16:261403 }
1404 }
1405}
1406
Florian Wilkensf8cfd242014-12-19 20:52:101407// FIXME This was implemented differently from Iter because of a problem
Colin Sherratt7a666df2014-10-19 20:19:071408// with returning the mutable reference. I couldn't find a way to
1409// make the lifetime checker happy so, but there should be a way.
Niko Matsakis1b487a82014-08-28 01:46:521410/// `RingBuf` mutable iterator.
Alexis Beingessner8dbaa712014-12-31 00:07:531411#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101412pub struct IterMut<'a, T:'a> {
Colin Sherratt7a666df2014-10-19 20:19:071413 ptr: *mut T,
1414 tail: uint,
1415 head: uint,
1416 cap: uint,
1417 marker: marker::ContravariantLifetime<'a>,
Niko Matsakis1b487a82014-08-28 01:46:521418}
1419
Alexis Beingessner8dbaa712014-12-31 00:07:531420#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351421impl<'a, T> Iterator for IterMut<'a, T> {
1422 type Item = &'a mut T;
1423
Niko Matsakisbc4164d2013-11-16 22:29:391424 #[inline]
Erik Price5731ca32013-12-10 07:16:181425 fn next(&mut self) -> Option<&'a mut T> {
Colin Sherratt7a666df2014-10-19 20:19:071426 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:391427 return None;
1428 }
Colin Sherratt7a666df2014-10-19 20:19:071429 let tail = self.tail;
1430 self.tail = wrap_index(self.tail + 1, self.cap);
Alexis Beingessner865c2db2014-11-23 02:34:111431
1432 unsafe {
1433 Some(&mut *self.ptr.offset(tail as int))
Alex Crichton9d5d97b2014-10-15 06:05:011434 }
Niko Matsakisbc4164d2013-11-16 22:29:391435 }
1436
1437 #[inline]
1438 fn size_hint(&self) -> (uint, Option<uint>) {
Colin Sherratt7a666df2014-10-19 20:19:071439 let len = count(self.tail, self.head, self.cap);
1440 (len, Some(len))
Niko Matsakisbc4164d2013-11-16 22:29:391441 }
1442}
1443
Alexis Beingessner8dbaa712014-12-31 00:07:531444#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351445impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
Niko Matsakisbc4164d2013-11-16 22:29:391446 #[inline]
Erik Price5731ca32013-12-10 07:16:181447 fn next_back(&mut self) -> Option<&'a mut T> {
Colin Sherratt7a666df2014-10-19 20:19:071448 if self.tail == self.head {
Niko Matsakisbc4164d2013-11-16 22:29:391449 return None;
1450 }
Colin Sherratt7a666df2014-10-19 20:19:071451 self.head = wrap_index(self.head - 1, self.cap);
Alexis Beingessner865c2db2014-11-23 02:34:111452
1453 unsafe {
1454 Some(&mut *self.ptr.offset(self.head as int))
1455 }
Niko Matsakisbc4164d2013-11-16 22:29:391456 }
1457}
Daniel Micayb47e1e92013-02-16 22:55:551458
Alexis Beingessner8dbaa712014-12-31 00:07:531459#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351460impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
blake2-ppc7c369ee72013-09-01 16:20:241461
Alexis Beingessner8dbaa712014-12-31 00:07:531462/// A by-value RingBuf iterator
1463#[stable]
Florian Wilkensf8cfd242014-12-19 20:52:101464pub struct IntoIter<T> {
Alexis Beingessner865c2db2014-11-23 02:34:111465 inner: RingBuf<T>,
1466}
1467
Alexis Beingessner8dbaa712014-12-31 00:07:531468#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351469impl<T> Iterator for IntoIter<T> {
1470 type Item = T;
1471
Alexis Beingessner865c2db2014-11-23 02:34:111472 #[inline]
1473 fn next(&mut self) -> Option<T> {
1474 self.inner.pop_front()
1475 }
1476
1477 #[inline]
1478 fn size_hint(&self) -> (uint, Option<uint>) {
1479 let len = self.inner.len();
1480 (len, Some(len))
1481 }
1482}
1483
Alexis Beingessner8dbaa712014-12-31 00:07:531484#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351485impl<T> DoubleEndedIterator for IntoIter<T> {
Alexis Beingessner865c2db2014-11-23 02:34:111486 #[inline]
1487 fn next_back(&mut self) -> Option<T> {
1488 self.inner.pop_back()
1489 }
1490}
1491
Alexis Beingessner8dbaa712014-12-31 00:07:531492#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351493impl<T> ExactSizeIterator for IntoIter<T> {}
Alexis Beingessner865c2db2014-11-23 02:34:111494
Clark Gaebeld57f2592014-12-16 22:45:031495/// A draining RingBuf iterator
Alexis Beingessner8dbaa712014-12-31 00:07:531496#[unstable = "matches collection reform specification, waiting for dust to settle"]
Clark Gaebeld57f2592014-12-16 22:45:031497pub struct Drain<'a, T: 'a> {
1498 inner: &'a mut RingBuf<T>,
1499}
1500
1501#[unsafe_destructor]
Alexis Beingessner8dbaa712014-12-31 00:07:531502#[stable]
Clark Gaebeld57f2592014-12-16 22:45:031503impl<'a, T: 'a> Drop for Drain<'a, T> {
1504 fn drop(&mut self) {
1505 for _ in *self {}
1506 self.inner.head = 0;
1507 self.inner.tail = 0;
1508 }
1509}
1510
Alexis Beingessner8dbaa712014-12-31 00:07:531511#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351512impl<'a, T: 'a> Iterator for Drain<'a, T> {
1513 type Item = T;
1514
Clark Gaebeld57f2592014-12-16 22:45:031515 #[inline]
1516 fn next(&mut self) -> Option<T> {
1517 self.inner.pop_front()
1518 }
1519
1520 #[inline]
1521 fn size_hint(&self) -> (uint, Option<uint>) {
1522 let len = self.inner.len();
1523 (len, Some(len))
1524 }
1525}
1526
Alexis Beingessner8dbaa712014-12-31 00:07:531527#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351528impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
Clark Gaebeld57f2592014-12-16 22:45:031529 #[inline]
1530 fn next_back(&mut self) -> Option<T> {
1531 self.inner.pop_back()
1532 }
1533}
1534
Alexis Beingessner8dbaa712014-12-31 00:07:531535#[stable]
Jorge Aparicio6b116be2015-01-02 04:15:351536impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
Clark Gaebeld57f2592014-12-16 22:45:031537
Aaron Turonb94bcbf2014-12-30 22:44:261538#[stable]
Alex Crichton748bc3c2014-05-30 00:45:071539impl<A: PartialEq> PartialEq for RingBuf<A> {
blake2-ppc70523712013-07-10 13:27:141540 fn eq(&self, other: &RingBuf<A>) -> bool {
Colin Sherratt7a666df2014-10-19 20:19:071541 self.len() == other.len() &&
blake2-ppc10c76982013-07-06 13:27:321542 self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
1543 }
blake2-ppc10c76982013-07-06 13:27:321544}
1545
Aaron Turonb94bcbf2014-12-30 22:44:261546#[stable]
nham25acfde2014-08-01 20:05:031547impl<A: Eq> Eq for RingBuf<A> {}
1548
Aaron Turonb94bcbf2014-12-30 22:44:261549#[stable]
nham63615772014-07-27 03:18:561550impl<A: PartialOrd> PartialOrd for RingBuf<A> {
1551 fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
1552 iter::order::partial_cmp(self.iter(), other.iter())
1553 }
1554}
1555
Aaron Turonb94bcbf2014-12-30 22:44:261556#[stable]
nham3737c532014-08-01 20:22:481557impl<A: Ord> Ord for RingBuf<A> {
1558 #[inline]
1559 fn cmp(&self, other: &RingBuf<A>) -> Ordering {
1560 iter::order::cmp(self.iter(), other.iter())
1561 }
1562}
1563
Alexis Beingessner8dbaa712014-12-31 00:07:531564#[stable]
nham1cfa6562014-07-27 02:33:471565impl<S: Writer, A: Hash<S>> Hash<S> for RingBuf<A> {
1566 fn hash(&self, state: &mut S) {
nham9fa44242014-07-27 16:37:321567 self.len().hash(state);
nham1cfa6562014-07-27 02:33:471568 for elt in self.iter() {
1569 elt.hash(state);
1570 }
1571 }
1572}
1573
Jorge Aparicio32dd5922015-01-03 15:40:101574#[stable]
1575impl<A> Index<uint> for RingBuf<A> {
1576 type Output = A;
1577
1578 #[inline]
1579 fn index<'a>(&'a self, i: &uint) -> &'a A {
1580 self.get(*i).expect("Out of bounds access")
1581 }
1582}
1583
Jorge Aparicio32dd5922015-01-03 15:40:101584#[stable]
1585impl<A> IndexMut<uint> for RingBuf<A> {
1586 type Output = A;
1587
1588 #[inline]
1589 fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut A {
1590 self.get_mut(*i).expect("Out of bounds access")
1591 }
1592}
1593
Alexis Beingessner8dbaa712014-12-31 00:07:531594#[stable]
Huon Wilson53487a02013-08-13 13:08:141595impl<A> FromIterator<A> for RingBuf<A> {
Jorge Aparicio6b116be2015-01-02 04:15:351596 fn from_iter<T: Iterator<Item=A>>(iterator: T) -> RingBuf<A> {
blake2-ppcf8ae5262013-07-30 00:06:491597 let (lower, _) = iterator.size_hint();
1598 let mut deq = RingBuf::with_capacity(lower);
1599 deq.extend(iterator);
blake2-ppc08dc72f2013-07-06 03:42:451600 deq
1601 }
1602}
1603
Alexis Beingessner8dbaa712014-12-31 00:07:531604#[stable]
gamazeps16c8cd92014-11-08 00:39:391605impl<A> Extend<A> for RingBuf<A> {
Jorge Aparicio6b116be2015-01-02 04:15:351606 fn extend<T: Iterator<Item=A>>(&mut self, mut iterator: T) {
Marvin Löbel6200e762014-03-20 13:12:561607 for elt in iterator {
Alexis Beingessnercf3b2e42014-11-06 17:24:471608 self.push_back(elt);
blake2-ppcf8ae5262013-07-30 00:06:491609 }
1610 }
1611}
1612
Alexis Beingessner8dbaa712014-12-31 00:07:531613#[stable]
Alex Crichton6a585372014-05-30 01:50:121614impl<T: fmt::Show> fmt::Show for RingBuf<T> {
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041615 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Sean McArthur44440e52014-12-20 08:09:351616 try!(write!(f, "RingBuf ["));
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041617
1618 for (i, e) in self.iter().enumerate() {
1619 if i != 0 { try!(write!(f, ", ")); }
Sean McArthur44440e52014-12-20 08:09:351620 try!(write!(f, "{:?}", *e));
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:041621 }
1622
1623 write!(f, "]")
1624 }
1625}
1626
Brian Anderson6e27b272012-01-18 03:05:071627#[cfg(test)]
1628mod tests {
Steven Fackler3dcd2152014-11-06 08:05:531629 use self::Taggy::*;
1630 use self::Taggypar::*;
Eduard Burtescub45d30d2014-12-19 12:02:221631 use prelude::*;
Eduard Burtescub45d30d2014-12-19 12:02:221632 use core::iter;
Alex Crichton02882fb2014-02-28 09:23:061633 use std::fmt::Show;
nham1cfa6562014-07-27 02:33:471634 use std::hash;
Alex Crichton760b93a2014-05-30 02:03:061635 use test::Bencher;
1636 use test;
1637
Alex Crichtonf47e4b22014-01-07 06:33:501638 use super::RingBuf;
Patrick Waltonfa5ee932012-12-28 02:24:181639
Brian Anderson6e27b272012-01-18 03:05:071640 #[test]
Victor Berger52ea83d2014-09-22 17:30:061641 #[allow(deprecated)]
Brian Anderson6e27b272012-01-18 03:05:071642 fn test_simple() {
blake2-ppc70523712013-07-10 13:27:141643 let mut d = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:451644 assert_eq!(d.len(), 0u);
Niko Matsakis9e3d0b02014-04-21 21:58:521645 d.push_front(17i);
1646 d.push_front(42i);
Alexis Beingessnercf3b2e42014-11-06 17:24:471647 d.push_back(137);
Corey Richardsoncc57ca02013-05-19 02:02:451648 assert_eq!(d.len(), 3u);
Alexis Beingessnercf3b2e42014-11-06 17:24:471649 d.push_back(137);
Corey Richardsoncc57ca02013-05-19 02:02:451650 assert_eq!(d.len(), 4u);
Luqman Aden3ef9aa02014-10-15 07:22:551651 debug!("{}", d.front());
blake2-ppc70523712013-07-10 13:27:141652 assert_eq!(*d.front().unwrap(), 42);
Luqman Aden3ef9aa02014-10-15 07:22:551653 debug!("{}", d.back());
blake2-ppc70523712013-07-10 13:27:141654 assert_eq!(*d.back().unwrap(), 137);
1655 let mut i = d.pop_front();
Luqman Aden3ef9aa02014-10-15 07:22:551656 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:141657 assert_eq!(i, Some(42));
Alexis Beingessnercf3b2e42014-11-06 17:24:471658 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:551659 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:141660 assert_eq!(i, Some(137));
Alexis Beingessnercf3b2e42014-11-06 17:24:471661 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:551662 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:141663 assert_eq!(i, Some(137));
Alexis Beingessnercf3b2e42014-11-06 17:24:471664 i = d.pop_back();
Luqman Aden3ef9aa02014-10-15 07:22:551665 debug!("{}", i);
blake2-ppc70523712013-07-10 13:27:141666 assert_eq!(i, Some(17));
Corey Richardsoncc57ca02013-05-19 02:02:451667 assert_eq!(d.len(), 0u);
Alexis Beingessnercf3b2e42014-11-06 17:24:471668 d.push_back(3);
Corey Richardsoncc57ca02013-05-19 02:02:451669 assert_eq!(d.len(), 1u);
blake2-ppc70523712013-07-10 13:27:141670 d.push_front(2);
Corey Richardsoncc57ca02013-05-19 02:02:451671 assert_eq!(d.len(), 2u);
Alexis Beingessnercf3b2e42014-11-06 17:24:471672 d.push_back(4);
Corey Richardsoncc57ca02013-05-19 02:02:451673 assert_eq!(d.len(), 3u);
blake2-ppc70523712013-07-10 13:27:141674 d.push_front(1);
Corey Richardsoncc57ca02013-05-19 02:02:451675 assert_eq!(d.len(), 4u);
Alex Crichton9d5d97b2014-10-15 06:05:011676 debug!("{}", d[0]);
1677 debug!("{}", d[1]);
1678 debug!("{}", d[2]);
1679 debug!("{}", d[3]);
1680 assert_eq!(d[0], 1);
1681 assert_eq!(d[1], 2);
1682 assert_eq!(d[2], 3);
1683 assert_eq!(d[3], 4);
Brian Anderson6e27b272012-01-18 03:05:071684 }
1685
Felix S. Klock IIa636f512013-05-01 23:32:371686 #[cfg(test)]
Alex Crichton748bc3c2014-05-30 00:45:071687 fn test_parameterized<T:Clone + PartialEq + Show>(a: T, b: T, c: T, d: T) {
Patrick Waltondc4bf172013-07-13 04:05:591688 let mut deq = RingBuf::new();
Corey Richardsoncc57ca02013-05-19 02:02:451689 assert_eq!(deq.len(), 0);
Patrick Waltondc4bf172013-07-13 04:05:591690 deq.push_front(a.clone());
1691 deq.push_front(b.clone());
Alexis Beingessnercf3b2e42014-11-06 17:24:471692 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451693 assert_eq!(deq.len(), 3);
Alexis Beingessnercf3b2e42014-11-06 17:24:471694 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451695 assert_eq!(deq.len(), 4);
Marvin Löbel0ac7a212013-08-03 23:59:241696 assert_eq!((*deq.front().unwrap()).clone(), b.clone());
1697 assert_eq!((*deq.back().unwrap()).clone(), d.clone());
1698 assert_eq!(deq.pop_front().unwrap(), b.clone());
Alexis Beingessnercf3b2e42014-11-06 17:24:471699 assert_eq!(deq.pop_back().unwrap(), d.clone());
1700 assert_eq!(deq.pop_back().unwrap(), c.clone());
1701 assert_eq!(deq.pop_back().unwrap(), a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451702 assert_eq!(deq.len(), 0);
Alexis Beingessnercf3b2e42014-11-06 17:24:471703 deq.push_back(c.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451704 assert_eq!(deq.len(), 1);
Patrick Waltondc4bf172013-07-13 04:05:591705 deq.push_front(b.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451706 assert_eq!(deq.len(), 2);
Alexis Beingessnercf3b2e42014-11-06 17:24:471707 deq.push_back(d.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451708 assert_eq!(deq.len(), 3);
Patrick Waltondc4bf172013-07-13 04:05:591709 deq.push_front(a.clone());
Corey Richardsoncc57ca02013-05-19 02:02:451710 assert_eq!(deq.len(), 4);
NODA, Kaif27ad3d2014-10-05 10:11:171711 assert_eq!(deq[0].clone(), a.clone());
1712 assert_eq!(deq[1].clone(), b.clone());
1713 assert_eq!(deq[2].clone(), c.clone());
1714 assert_eq!(deq[3].clone(), d.clone());
Brian Anderson6e27b272012-01-18 03:05:071715 }
1716
blake2-ppc81933ed2013-07-06 03:42:451717 #[test]
blake2-ppc70523712013-07-10 13:27:141718 fn test_push_front_grow() {
1719 let mut deq = RingBuf::new();
Daniel Micay100894552013-08-03 16:45:231720 for i in range(0u, 66) {
blake2-ppc70523712013-07-10 13:27:141721 deq.push_front(i);
blake2-ppc81933ed2013-07-06 03:42:451722 }
1723 assert_eq!(deq.len(), 66);
1724
Daniel Micay100894552013-08-03 16:45:231725 for i in range(0u, 66) {
NODA, Kaif27ad3d2014-10-05 10:11:171726 assert_eq!(deq[i], 65 - i);
blake2-ppc81933ed2013-07-06 03:42:451727 }
1728
blake2-ppc70523712013-07-10 13:27:141729 let mut deq = RingBuf::new();
Daniel Micay100894552013-08-03 16:45:231730 for i in range(0u, 66) {
Alexis Beingessnercf3b2e42014-11-06 17:24:471731 deq.push_back(i);
blake2-ppc81933ed2013-07-06 03:42:451732 }
1733
Daniel Micay100894552013-08-03 16:45:231734 for i in range(0u, 66) {
NODA, Kaif27ad3d2014-10-05 10:11:171735 assert_eq!(deq[i], i);
blake2-ppc81933ed2013-07-06 03:42:451736 }
1737 }
1738
P1startfd10d202014-08-02 06:39:391739 #[test]
1740 fn test_index() {
1741 let mut deq = RingBuf::new();
1742 for i in range(1u, 4) {
1743 deq.push_front(i);
1744 }
1745 assert_eq!(deq[1], 2);
1746 }
1747
1748 #[test]
1749 #[should_fail]
1750 fn test_index_out_of_bounds() {
1751 let mut deq = RingBuf::new();
1752 for i in range(1u, 4) {
1753 deq.push_front(i);
1754 }
1755 deq[3];
1756 }
1757
blake2-ppc81933ed2013-07-06 03:42:451758 #[bench]
Liigo Zhuang408f4842014-04-01 01:16:351759 fn bench_new(b: &mut test::Bencher) {
Patrick Walton38efa172013-11-22 03:20:481760 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521761 let ring: RingBuf<u64> = RingBuf::new();
1762 test::black_box(ring);
Patrick Walton38efa172013-11-22 03:20:481763 })
blake2-ppc81933ed2013-07-06 03:42:451764 }
1765
1766 #[bench]
Colin Sherratt7a666df2014-10-19 20:19:071767 fn bench_push_back_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521768 let mut deq = RingBuf::with_capacity(101);
Patrick Walton38efa172013-11-22 03:20:481769 b.iter(|| {
Colin Sherratt7a666df2014-10-19 20:19:071770 for i in range(0i, 100) {
1771 deq.push_back(i);
1772 }
Colin Sherratt5e549d82014-11-11 02:57:521773 deq.head = 0;
1774 deq.tail = 0;
Patrick Walton38efa172013-11-22 03:20:481775 })
blake2-ppc81933ed2013-07-06 03:42:451776 }
1777
1778 #[bench]
Colin Sherratt7a666df2014-10-19 20:19:071779 fn bench_push_front_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521780 let mut deq = RingBuf::with_capacity(101);
Patrick Walton38efa172013-11-22 03:20:481781 b.iter(|| {
Colin Sherratt7a666df2014-10-19 20:19:071782 for i in range(0i, 100) {
1783 deq.push_front(i);
1784 }
Colin Sherratt5e549d82014-11-11 02:57:521785 deq.head = 0;
1786 deq.tail = 0;
Patrick Walton38efa172013-11-22 03:20:481787 })
blake2-ppc81933ed2013-07-06 03:42:451788 }
1789
1790 #[bench]
Colin Sherratt5e549d82014-11-11 02:57:521791 fn bench_pop_back_100(b: &mut test::Bencher) {
1792 let mut deq: RingBuf<int> = RingBuf::with_capacity(101);
Colin Sherratt7a666df2014-10-19 20:19:071793
Patrick Walton38efa172013-11-22 03:20:481794 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521795 deq.head = 100;
1796 deq.tail = 0;
1797 while !deq.is_empty() {
1798 test::black_box(deq.pop_back());
Colin Sherratt7a666df2014-10-19 20:19:071799 }
Colin Sherratt7a666df2014-10-19 20:19:071800 })
1801 }
1802
1803 #[bench]
1804 fn bench_pop_front_100(b: &mut test::Bencher) {
Colin Sherratt5e549d82014-11-11 02:57:521805 let mut deq: RingBuf<int> = RingBuf::with_capacity(101);
Colin Sherratt7a666df2014-10-19 20:19:071806
1807 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521808 deq.head = 100;
1809 deq.tail = 0;
1810 while !deq.is_empty() {
1811 test::black_box(deq.pop_front());
Colin Sherratt7a666df2014-10-19 20:19:071812 }
Colin Sherratt7a666df2014-10-19 20:19:071813 })
1814 }
1815
1816 #[bench]
1817 fn bench_grow_1025(b: &mut test::Bencher) {
1818 b.iter(|| {
1819 let mut deq = RingBuf::new();
1820 for i in range(0i, 1025) {
1821 deq.push_front(i);
Brendan Zabarauskas729060d2014-01-30 00:20:341822 }
Colin Sherratt5e549d82014-11-11 02:57:521823 test::black_box(deq);
Patrick Walton38efa172013-11-22 03:20:481824 })
blake2-ppc81933ed2013-07-06 03:42:451825 }
1826
Colin Sherratt7a666df2014-10-19 20:19:071827 #[bench]
1828 fn bench_iter_1000(b: &mut test::Bencher) {
1829 let ring: RingBuf<int> = range(0i, 1000).collect();
1830
1831 b.iter(|| {
1832 let mut sum = 0;
1833 for &i in ring.iter() {
1834 sum += i;
1835 }
Colin Sherratt5e549d82014-11-11 02:57:521836 test::black_box(sum);
Colin Sherratt7a666df2014-10-19 20:19:071837 })
1838 }
1839
1840 #[bench]
1841 fn bench_mut_iter_1000(b: &mut test::Bencher) {
1842 let mut ring: RingBuf<int> = range(0i, 1000).collect();
1843
1844 b.iter(|| {
Colin Sherratt5e549d82014-11-11 02:57:521845 let mut sum = 0;
Colin Sherratt7a666df2014-10-19 20:19:071846 for i in ring.iter_mut() {
Colin Sherratt5e549d82014-11-11 02:57:521847 sum += *i;
Colin Sherratt7a666df2014-10-19 20:19:071848 }
Colin Sherratt5e549d82014-11-11 02:57:521849 test::black_box(sum);
Colin Sherratt7a666df2014-10-19 20:19:071850 })
1851 }
1852
Jorge Aparicio351409a2015-01-04 03:54:181853 #[derive(Clone, PartialEq, Show)]
Patrick Walton99b33f72013-07-02 19:47:321854 enum Taggy {
1855 One(int),
1856 Two(int, int),
1857 Three(int, int, int),
Brian Anderson6e27b272012-01-18 03:05:071858 }
1859
Jorge Aparicio351409a2015-01-04 03:54:181860 #[derive(Clone, PartialEq, Show)]
Patrick Walton99b33f72013-07-02 19:47:321861 enum Taggypar<T> {
1862 Onepar(int),
1863 Twopar(int, int),
1864 Threepar(int, int, int),
1865 }
1866
Jorge Aparicio351409a2015-01-04 03:54:181867 #[derive(Clone, PartialEq, Show)]
Erick Tryzelaare84576b2013-01-22 16:44:241868 struct RecCy {
1869 x: int,
1870 y: int,
Patrick Waltoneb4d39e2013-01-26 00:57:391871 t: Taggy
Patrick Walton9117dcb2012-09-20 01:00:261872 }
Kevin Cantuc43426e2012-09-13 05:09:551873
1874 #[test]
1875 fn test_param_int() {
1876 test_parameterized::<int>(5, 72, 64, 175);
1877 }
1878
1879 #[test]
Kevin Cantuc43426e2012-09-13 05:09:551880 fn test_param_taggy() {
Corey Richardsonf8ae9b02013-06-26 22:14:351881 test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:551882 }
1883
1884 #[test]
1885 fn test_param_taggypar() {
1886 test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
Ben Striegela605fd02012-08-11 14:08:421887 Twopar::<int>(1, 2),
1888 Threepar::<int>(1, 2, 3),
1889 Twopar::<int>(17, 42));
Kevin Cantuc43426e2012-09-13 05:09:551890 }
Brian Anderson6e27b272012-01-18 03:05:071891
Kevin Cantuc43426e2012-09-13 05:09:551892 #[test]
1893 fn test_param_reccy() {
Erick Tryzelaare84576b2013-01-22 16:44:241894 let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
1895 let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
1896 let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
1897 let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
Kevin Cantuc43426e2012-09-13 05:09:551898 test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
Brian Anderson6e27b272012-01-18 03:05:071899 }
Erick Tryzelaar909d8f02013-03-30 01:02:441900
1901 #[test]
blake2-ppc0ff5c172013-07-06 03:42:451902 fn test_with_capacity() {
blake2-ppc70523712013-07-10 13:27:141903 let mut d = RingBuf::with_capacity(0);
Alexis Beingessnercf3b2e42014-11-06 17:24:471904 d.push_back(1i);
blake2-ppc0ff5c172013-07-06 03:42:451905 assert_eq!(d.len(), 1);
blake2-ppc70523712013-07-10 13:27:141906 let mut d = RingBuf::with_capacity(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471907 d.push_back(1i);
blake2-ppc0ff5c172013-07-06 03:42:451908 assert_eq!(d.len(), 1);
1909 }
1910
1911 #[test]
Kevin Butler64896d62014-08-07 01:11:131912 fn test_with_capacity_non_power_two() {
1913 let mut d3 = RingBuf::with_capacity(3);
Alexis Beingessnercf3b2e42014-11-06 17:24:471914 d3.push_back(1i);
Kevin Butler64896d62014-08-07 01:11:131915
1916 // X = None, | = lo
1917 // [|1, X, X]
1918 assert_eq!(d3.pop_front(), Some(1));
1919 // [X, |X, X]
1920 assert_eq!(d3.front(), None);
1921
1922 // [X, |3, X]
Alexis Beingessnercf3b2e42014-11-06 17:24:471923 d3.push_back(3);
Kevin Butler64896d62014-08-07 01:11:131924 // [X, |3, 6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471925 d3.push_back(6);
Kevin Butler64896d62014-08-07 01:11:131926 // [X, X, |6]
1927 assert_eq!(d3.pop_front(), Some(3));
1928
1929 // Pushing the lo past half way point to trigger
1930 // the 'B' scenario for growth
1931 // [9, X, |6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471932 d3.push_back(9);
Kevin Butler64896d62014-08-07 01:11:131933 // [9, 12, |6]
Alexis Beingessnercf3b2e42014-11-06 17:24:471934 d3.push_back(12);
Kevin Butler64896d62014-08-07 01:11:131935
Alexis Beingessnercf3b2e42014-11-06 17:24:471936 d3.push_back(15);
Kevin Butler64896d62014-08-07 01:11:131937 // There used to be a bug here about how the
1938 // RingBuf made growth assumptions about the
1939 // underlying Vec which didn't hold and lead
1940 // to corruption.
1941 // (Vec grows to next power of two)
1942 //good- [9, 12, 15, X, X, X, X, |6]
1943 //bug- [15, 12, X, X, X, |6, X, X]
1944 assert_eq!(d3.pop_front(), Some(6));
1945
1946 // Which leads us to the following state which
1947 // would be a failure case.
1948 //bug- [15, 12, X, X, X, X, |X, X]
1949 assert_eq!(d3.front(), Some(&9));
1950 }
1951
1952 #[test]
David Manescu65f35782014-01-31 13:03:201953 fn test_reserve_exact() {
blake2-ppc70523712013-07-10 13:27:141954 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471955 d.push_back(0u64);
David Manescu65f35782014-01-31 13:03:201956 d.reserve_exact(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471957 assert!(d.capacity() >= 51);
blake2-ppc70523712013-07-10 13:27:141958 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471959 d.push_back(0u32);
David Manescu65f35782014-01-31 13:03:201960 d.reserve_exact(50);
Alexis Beingessnercf3b2e42014-11-06 17:24:471961 assert!(d.capacity() >= 51);
Tim Chevalier77de84b2013-05-27 18:47:381962 }
1963
1964 #[test]
David Manescu65f35782014-01-31 13:03:201965 fn test_reserve() {
blake2-ppc70523712013-07-10 13:27:141966 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471967 d.push_back(0u64);
David Manescu65f35782014-01-31 13:03:201968 d.reserve(50);
Colin Sherratt7a666df2014-10-19 20:19:071969 assert!(d.capacity() >= 51);
blake2-ppc70523712013-07-10 13:27:141970 let mut d = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:471971 d.push_back(0u32);
David Manescu65f35782014-01-31 13:03:201972 d.reserve(50);
Colin Sherratt7a666df2014-10-19 20:19:071973 assert!(d.capacity() >= 51);
Tim Chevalier77de84b2013-05-27 18:47:381974 }
1975
Jed Estep096fb792013-06-26 14:04:441976 #[test]
blake2-ppc57757a82013-09-26 07:19:261977 fn test_swap() {
Niko Matsakis9e3d0b02014-04-21 21:58:521978 let mut d: RingBuf<int> = range(0i, 5).collect();
blake2-ppc57757a82013-09-26 07:19:261979 d.pop_front();
1980 d.swap(0, 3);
Huon Wilson4b9a7a22014-04-05 05:45:421981 assert_eq!(d.iter().map(|&x|x).collect::<Vec<int>>(), vec!(4, 2, 3, 1));
blake2-ppc57757a82013-09-26 07:19:261982 }
1983
1984 #[test]
Jed Estep096fb792013-06-26 14:04:441985 fn test_iter() {
blake2-ppc70523712013-07-10 13:27:141986 let mut d = RingBuf::new();
blake2-ppcf88d5322013-07-06 03:42:451987 assert_eq!(d.iter().next(), None);
blake2-ppc9ccf4432013-07-14 20:30:221988 assert_eq!(d.iter().size_hint(), (0, Some(0)));
blake2-ppcf88d5322013-07-06 03:42:451989
Niko Matsakis9e3d0b02014-04-21 21:58:521990 for i in range(0i, 5) {
Alexis Beingessnercf3b2e42014-11-06 17:24:471991 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:441992 }
Nick Cameron37a94b82014-08-04 12:19:021993 {
1994 let b: &[_] = &[&0,&1,&2,&3,&4];
Jorge Apariciof2af07e2014-11-27 16:45:501995 assert_eq!(d.iter().collect::<Vec<&int>>(), b);
Nick Cameron37a94b82014-08-04 12:19:021996 }
Corey Richardsonf8ae9b02013-06-26 22:14:351997
Niko Matsakis9e3d0b02014-04-21 21:58:521998 for i in range(6i, 9) {
blake2-ppc70523712013-07-10 13:27:141999 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:442000 }
Nick Cameron37a94b82014-08-04 12:19:022001 {
2002 let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
Jorge Apariciof2af07e2014-11-27 16:45:502003 assert_eq!(d.iter().collect::<Vec<&int>>(), b);
Nick Cameron37a94b82014-08-04 12:19:022004 }
blake2-ppc9ccf4432013-07-14 20:30:222005
2006 let mut it = d.iter();
2007 let mut len = d.len();
2008 loop {
2009 match it.next() {
2010 None => break,
2011 _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
2012 }
2013 }
Jed Estep096fb792013-06-26 14:04:442014 }
2015
2016 #[test]
2017 fn test_rev_iter() {
blake2-ppc70523712013-07-10 13:27:142018 let mut d = RingBuf::new();
Jonathan S03609e52014-04-21 04:59:122019 assert_eq!(d.iter().rev().next(), None);
blake2-ppcf88d5322013-07-06 03:42:452020
Niko Matsakis9e3d0b02014-04-21 21:58:522021 for i in range(0i, 5) {
Alexis Beingessnercf3b2e42014-11-06 17:24:472022 d.push_back(i);
Jed Estep096fb792013-06-26 14:04:442023 }
Nick Cameron37a94b82014-08-04 12:19:022024 {
2025 let b: &[_] = &[&4,&3,&2,&1,&0];
Jorge Apariciof2af07e2014-11-27 16:45:502026 assert_eq!(d.iter().rev().collect::<Vec<&int>>(), b);
Nick Cameron37a94b82014-08-04 12:19:022027 }
Corey Richardsonf8ae9b02013-06-26 22:14:352028
Niko Matsakis9e3d0b02014-04-21 21:58:522029 for i in range(6i, 9) {
blake2-ppc70523712013-07-10 13:27:142030 d.push_front(i);
Jed Estep096fb792013-06-26 14:04:442031 }
Nick Cameron37a94b82014-08-04 12:19:022032 let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
Jorge Apariciof2af07e2014-11-27 16:45:502033 assert_eq!(d.iter().rev().collect::<Vec<&int>>(), b);
Jed Estep096fb792013-06-26 14:04:442034 }
blake2-ppc08dc72f2013-07-06 03:42:452035
2036 #[test]
Niko Matsakisbc4164d2013-11-16 22:29:392037 fn test_mut_rev_iter_wrap() {
2038 let mut d = RingBuf::with_capacity(3);
Aaron Turonfc525ee2014-09-15 03:27:362039 assert!(d.iter_mut().rev().next().is_none());
Niko Matsakisbc4164d2013-11-16 22:29:392040
Alexis Beingessnercf3b2e42014-11-06 17:24:472041 d.push_back(1i);
2042 d.push_back(2);
2043 d.push_back(3);
Niko Matsakisbc4164d2013-11-16 22:29:392044 assert_eq!(d.pop_front(), Some(1));
Alexis Beingessnercf3b2e42014-11-06 17:24:472045 d.push_back(4);
Niko Matsakisbc4164d2013-11-16 22:29:392046
Aaron Turonfc525ee2014-09-15 03:27:362047 assert_eq!(d.iter_mut().rev().map(|x| *x).collect::<Vec<int>>(),
Huon Wilson4b9a7a22014-04-05 05:45:422048 vec!(4, 3, 2));
Niko Matsakisbc4164d2013-11-16 22:29:392049 }
2050
2051 #[test]
blake2-ppcf88d5322013-07-06 03:42:452052 fn test_mut_iter() {
blake2-ppc70523712013-07-10 13:27:142053 let mut d = RingBuf::new();
Aaron Turonfc525ee2014-09-15 03:27:362054 assert!(d.iter_mut().next().is_none());
blake2-ppcf88d5322013-07-06 03:42:452055
Daniel Micay100894552013-08-03 16:45:232056 for i in range(0u, 3) {
blake2-ppc70523712013-07-10 13:27:142057 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:452058 }
2059
Aaron Turonfc525ee2014-09-15 03:27:362060 for (i, elt) in d.iter_mut().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:452061 assert_eq!(*elt, 2 - i);
2062 *elt = i;
2063 }
2064
2065 {
Aaron Turonfc525ee2014-09-15 03:27:362066 let mut it = d.iter_mut();
blake2-ppcf88d5322013-07-06 03:42:452067 assert_eq!(*it.next().unwrap(), 0);
2068 assert_eq!(*it.next().unwrap(), 1);
2069 assert_eq!(*it.next().unwrap(), 2);
2070 assert!(it.next().is_none());
2071 }
2072 }
2073
2074 #[test]
2075 fn test_mut_rev_iter() {
blake2-ppc70523712013-07-10 13:27:142076 let mut d = RingBuf::new();
Aaron Turonfc525ee2014-09-15 03:27:362077 assert!(d.iter_mut().rev().next().is_none());
blake2-ppcf88d5322013-07-06 03:42:452078
Daniel Micay100894552013-08-03 16:45:232079 for i in range(0u, 3) {
blake2-ppc70523712013-07-10 13:27:142080 d.push_front(i);
blake2-ppcf88d5322013-07-06 03:42:452081 }
2082
Aaron Turonfc525ee2014-09-15 03:27:362083 for (i, elt) in d.iter_mut().rev().enumerate() {
blake2-ppcf88d5322013-07-06 03:42:452084 assert_eq!(*elt, i);
2085 *elt = i;
2086 }
2087
2088 {
Aaron Turonfc525ee2014-09-15 03:27:362089 let mut it = d.iter_mut().rev();
blake2-ppcf88d5322013-07-06 03:42:452090 assert_eq!(*it.next().unwrap(), 0);
2091 assert_eq!(*it.next().unwrap(), 1);
2092 assert_eq!(*it.next().unwrap(), 2);
2093 assert!(it.next().is_none());
2094 }
2095 }
2096
2097 #[test]
Alexis Beingessner865c2db2014-11-23 02:34:112098 fn test_into_iter() {
2099
2100 // Empty iter
2101 {
2102 let d: RingBuf<int> = RingBuf::new();
2103 let mut iter = d.into_iter();
2104
2105 assert_eq!(iter.size_hint(), (0, Some(0)));
2106 assert_eq!(iter.next(), None);
2107 assert_eq!(iter.size_hint(), (0, Some(0)));
2108 }
2109
2110 // simple iter
2111 {
2112 let mut d = RingBuf::new();
2113 for i in range(0i, 5) {
2114 d.push_back(i);
2115 }
2116
2117 let b = vec![0,1,2,3,4];
2118 assert_eq!(d.into_iter().collect::<Vec<int>>(), b);
2119 }
2120
2121 // wrapped iter
2122 {
2123 let mut d = RingBuf::new();
2124 for i in range(0i, 5) {
2125 d.push_back(i);
2126 }
2127 for i in range(6, 9) {
2128 d.push_front(i);
2129 }
2130
2131 let b = vec![8,7,6,0,1,2,3,4];
2132 assert_eq!(d.into_iter().collect::<Vec<int>>(), b);
2133 }
2134
2135 // partially used
2136 {
2137 let mut d = RingBuf::new();
2138 for i in range(0i, 5) {
2139 d.push_back(i);
2140 }
2141 for i in range(6, 9) {
2142 d.push_front(i);
2143 }
2144
2145 let mut it = d.into_iter();
2146 assert_eq!(it.size_hint(), (8, Some(8)));
2147 assert_eq!(it.next(), Some(8));
2148 assert_eq!(it.size_hint(), (7, Some(7)));
2149 assert_eq!(it.next_back(), Some(4));
2150 assert_eq!(it.size_hint(), (6, Some(6)));
2151 assert_eq!(it.next(), Some(7));
2152 assert_eq!(it.size_hint(), (5, Some(5)));
2153 }
2154 }
2155
2156 #[test]
Clark Gaebeld57f2592014-12-16 22:45:032157 fn test_drain() {
2158
2159 // Empty iter
2160 {
2161 let mut d: RingBuf<int> = RingBuf::new();
2162
2163 {
2164 let mut iter = d.drain();
2165
2166 assert_eq!(iter.size_hint(), (0, Some(0)));
2167 assert_eq!(iter.next(), None);
2168 assert_eq!(iter.size_hint(), (0, Some(0)));
2169 }
2170
2171 assert!(d.is_empty());
2172 }
2173
2174 // simple iter
2175 {
2176 let mut d = RingBuf::new();
2177 for i in range(0i, 5) {
2178 d.push_back(i);
2179 }
2180
2181 assert_eq!(d.drain().collect::<Vec<int>>(), [0, 1, 2, 3, 4]);
2182 assert!(d.is_empty());
2183 }
2184
2185 // wrapped iter
2186 {
2187 let mut d = RingBuf::new();
2188 for i in range(0i, 5) {
2189 d.push_back(i);
2190 }
2191 for i in range(6, 9) {
2192 d.push_front(i);
2193 }
2194
2195 assert_eq!(d.drain().collect::<Vec<int>>(), [8,7,6,0,1,2,3,4]);
2196 assert!(d.is_empty());
2197 }
2198
2199 // partially used
2200 {
2201 let mut d = RingBuf::new();
2202 for i in range(0i, 5) {
2203 d.push_back(i);
2204 }
2205 for i in range(6, 9) {
2206 d.push_front(i);
2207 }
2208
2209 {
2210 let mut it = d.drain();
2211 assert_eq!(it.size_hint(), (8, Some(8)));
2212 assert_eq!(it.next(), Some(8));
2213 assert_eq!(it.size_hint(), (7, Some(7)));
2214 assert_eq!(it.next_back(), Some(4));
2215 assert_eq!(it.size_hint(), (6, Some(6)));
2216 assert_eq!(it.next(), Some(7));
2217 assert_eq!(it.size_hint(), (5, Some(5)));
2218 }
2219 assert!(d.is_empty());
2220 }
2221 }
2222
2223 #[test]
Brian Andersonee052192014-03-31 04:45:552224 fn test_from_iter() {
Eduard Burtescub45d30d2014-12-19 12:02:222225 use core::iter;
Niko Matsakis9e3d0b02014-04-21 21:58:522226 let v = vec!(1i,2,3,4,5,6,7);
Erick Tryzelaar68f40d22013-08-10 03:09:472227 let deq: RingBuf<int> = v.iter().map(|&x| x).collect();
Huon Wilson4b9a7a22014-04-05 05:45:422228 let u: Vec<int> = deq.iter().map(|&x| x).collect();
blake2-ppc08dc72f2013-07-06 03:42:452229 assert_eq!(u, v);
2230
Aaron Turonb299c2b2014-11-06 17:32:372231 let seq = iter::count(0u, 2).take(256);
blake2-ppc70523712013-07-10 13:27:142232 let deq: RingBuf<uint> = seq.collect();
Daniel Micay100894552013-08-03 16:45:232233 for (i, &x) in deq.iter().enumerate() {
blake2-ppc08dc72f2013-07-06 03:42:452234 assert_eq!(2*i, x);
2235 }
2236 assert_eq!(deq.len(), 256);
2237 }
blake2-ppc10c76982013-07-06 13:27:322238
2239 #[test]
2240 fn test_clone() {
blake2-ppc70523712013-07-10 13:27:142241 let mut d = RingBuf::new();
Niko Matsakis9e3d0b02014-04-21 21:58:522242 d.push_front(17i);
blake2-ppc70523712013-07-10 13:27:142243 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:472244 d.push_back(137);
2245 d.push_back(137);
blake2-ppc10c76982013-07-06 13:27:322246 assert_eq!(d.len(), 4u);
2247 let mut e = d.clone();
2248 assert_eq!(e.len(), 4u);
2249 while !d.is_empty() {
Alexis Beingessnercf3b2e42014-11-06 17:24:472250 assert_eq!(d.pop_back(), e.pop_back());
blake2-ppc10c76982013-07-06 13:27:322251 }
2252 assert_eq!(d.len(), 0u);
2253 assert_eq!(e.len(), 0u);
2254 }
2255
2256 #[test]
2257 fn test_eq() {
blake2-ppc70523712013-07-10 13:27:142258 let mut d = RingBuf::new();
Alex Crichton02882fb2014-02-28 09:23:062259 assert!(d == RingBuf::with_capacity(0));
Niko Matsakis9e3d0b02014-04-21 21:58:522260 d.push_front(137i);
blake2-ppc70523712013-07-10 13:27:142261 d.push_front(17);
2262 d.push_front(42);
Alexis Beingessnercf3b2e42014-11-06 17:24:472263 d.push_back(137);
blake2-ppc70523712013-07-10 13:27:142264 let mut e = RingBuf::with_capacity(0);
Alexis Beingessnercf3b2e42014-11-06 17:24:472265 e.push_back(42);
2266 e.push_back(17);
2267 e.push_back(137);
2268 e.push_back(137);
Alex Crichton02882fb2014-02-28 09:23:062269 assert!(&e == &d);
Alexis Beingessnercf3b2e42014-11-06 17:24:472270 e.pop_back();
2271 e.push_back(0);
blake2-ppc10c76982013-07-06 13:27:322272 assert!(e != d);
2273 e.clear();
Alex Crichton02882fb2014-02-28 09:23:062274 assert!(e == RingBuf::new());
blake2-ppc10c76982013-07-06 13:27:322275 }
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042276
2277 #[test]
nham1cfa6562014-07-27 02:33:472278 fn test_hash() {
2279 let mut x = RingBuf::new();
2280 let mut y = RingBuf::new();
2281
Alexis Beingessnercf3b2e42014-11-06 17:24:472282 x.push_back(1i);
2283 x.push_back(2);
2284 x.push_back(3);
nham1cfa6562014-07-27 02:33:472285
Alexis Beingessnercf3b2e42014-11-06 17:24:472286 y.push_back(0i);
2287 y.push_back(1i);
nham1cfa6562014-07-27 02:33:472288 y.pop_front();
Alexis Beingessnercf3b2e42014-11-06 17:24:472289 y.push_back(2);
2290 y.push_back(3);
nham1cfa6562014-07-27 02:33:472291
2292 assert!(hash::hash(&x) == hash::hash(&y));
2293 }
2294
2295 #[test]
nham63615772014-07-27 03:18:562296 fn test_ord() {
2297 let x = RingBuf::new();
2298 let mut y = RingBuf::new();
Alexis Beingessnercf3b2e42014-11-06 17:24:472299 y.push_back(1i);
2300 y.push_back(2);
2301 y.push_back(3);
nham63615772014-07-27 03:18:562302 assert!(x < y);
2303 assert!(y > x);
2304 assert!(x <= x);
2305 assert!(x >= x);
2306 }
2307
2308 #[test]
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042309 fn test_show() {
Niko Matsakis9e3d0b02014-04-21 21:58:522310 let ringbuf: RingBuf<int> = range(0i, 10).collect();
Jorge Apariciof2af07e2014-11-27 16:45:502311 assert!(format!("{}", ringbuf) == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042312
2313 let ringbuf: RingBuf<&str> = vec!["just", "one", "test", "more"].iter()
2314 .map(|&s| s)
2315 .collect();
Jorge Apariciof2af07e2014-11-27 16:45:502316 assert!(format!("{}", ringbuf) == "[just, one, test, more]");
Adolfo Ochagavía8e4e3ab2014-06-04 14:15:042317 }
Colin Sherratt7a666df2014-10-19 20:19:072318
2319 #[test]
2320 fn test_drop() {
2321 static mut drops: uint = 0;
2322 struct Elem;
2323 impl Drop for Elem {
2324 fn drop(&mut self) {
2325 unsafe { drops += 1; }
2326 }
2327 }
2328
2329 let mut ring = RingBuf::new();
2330 ring.push_back(Elem);
2331 ring.push_front(Elem);
2332 ring.push_back(Elem);
2333 ring.push_front(Elem);
2334 drop(ring);
2335
2336 assert_eq!(unsafe {drops}, 4);
2337 }
2338
2339 #[test]
2340 fn test_drop_with_pop() {
2341 static mut drops: uint = 0;
2342 struct Elem;
2343 impl Drop for Elem {
2344 fn drop(&mut self) {
2345 unsafe { drops += 1; }
2346 }
2347 }
2348
2349 let mut ring = RingBuf::new();
2350 ring.push_back(Elem);
2351 ring.push_front(Elem);
2352 ring.push_back(Elem);
2353 ring.push_front(Elem);
2354
2355 drop(ring.pop_back());
2356 drop(ring.pop_front());
2357 assert_eq!(unsafe {drops}, 2);
2358
2359 drop(ring);
2360 assert_eq!(unsafe {drops}, 4);
2361 }
2362
2363 #[test]
2364 fn test_drop_clear() {
2365 static mut drops: uint = 0;
2366 struct Elem;
2367 impl Drop for Elem {
2368 fn drop(&mut self) {
2369 unsafe { drops += 1; }
2370 }
2371 }
2372
2373 let mut ring = RingBuf::new();
2374 ring.push_back(Elem);
2375 ring.push_front(Elem);
2376 ring.push_back(Elem);
2377 ring.push_front(Elem);
2378 ring.clear();
2379 assert_eq!(unsafe {drops}, 4);
2380
2381 drop(ring);
2382 assert_eq!(unsafe {drops}, 4);
2383 }
2384
2385 #[test]
2386 fn test_reserve_grow() {
2387 // test growth path A
2388 // [T o o H] -> [T o o H . . . . ]
2389 let mut ring = RingBuf::with_capacity(4);
2390 for i in range(0i, 3) {
2391 ring.push_back(i);
2392 }
2393 ring.reserve(7);
2394 for i in range(0i, 3) {
2395 assert_eq!(ring.pop_front(), Some(i));
2396 }
2397
2398 // test growth path B
2399 // [H T o o] -> [. T o o H . . . ]
2400 let mut ring = RingBuf::with_capacity(4);
2401 for i in range(0i, 1) {
2402 ring.push_back(i);
2403 assert_eq!(ring.pop_front(), Some(i));
2404 }
2405 for i in range(0i, 3) {
2406 ring.push_back(i);
2407 }
2408 ring.reserve(7);
2409 for i in range(0i, 3) {
2410 assert_eq!(ring.pop_front(), Some(i));
2411 }
2412
2413 // test growth path C
2414 // [o o H T] -> [o o H . . . . T ]
2415 let mut ring = RingBuf::with_capacity(4);
2416 for i in range(0i, 3) {
2417 ring.push_back(i);
2418 assert_eq!(ring.pop_front(), Some(i));
2419 }
2420 for i in range(0i, 3) {
2421 ring.push_back(i);
2422 }
2423 ring.reserve(7);
2424 for i in range(0i, 3) {
2425 assert_eq!(ring.pop_front(), Some(i));
2426 }
2427 }
2428
2429 #[test]
2430 fn test_get() {
2431 let mut ring = RingBuf::new();
2432 ring.push_back(0i);
2433 assert_eq!(ring.get(0), Some(&0));
2434 assert_eq!(ring.get(1), None);
2435
2436 ring.push_back(1);
2437 assert_eq!(ring.get(0), Some(&0));
2438 assert_eq!(ring.get(1), Some(&1));
2439 assert_eq!(ring.get(2), None);
2440
2441 ring.push_back(2);
2442 assert_eq!(ring.get(0), Some(&0));
2443 assert_eq!(ring.get(1), Some(&1));
2444 assert_eq!(ring.get(2), Some(&2));
2445 assert_eq!(ring.get(3), None);
2446
2447 assert_eq!(ring.pop_front(), Some(0));
2448 assert_eq!(ring.get(0), Some(&1));
2449 assert_eq!(ring.get(1), Some(&2));
2450 assert_eq!(ring.get(2), None);
2451
2452 assert_eq!(ring.pop_front(), Some(1));
2453 assert_eq!(ring.get(0), Some(&2));
2454 assert_eq!(ring.get(1), None);
2455
2456 assert_eq!(ring.pop_front(), Some(2));
2457 assert_eq!(ring.get(0), None);
2458 assert_eq!(ring.get(1), None);
2459 }
2460
2461 #[test]
2462 fn test_get_mut() {
2463 let mut ring = RingBuf::new();
2464 for i in range(0i, 3) {
2465 ring.push_back(i);
2466 }
2467
2468 match ring.get_mut(1) {
2469 Some(x) => *x = -1,
2470 None => ()
2471 };
2472
2473 assert_eq!(ring.get_mut(0), Some(&mut 0));
2474 assert_eq!(ring.get_mut(1), Some(&mut -1));
2475 assert_eq!(ring.get_mut(2), Some(&mut 2));
2476 assert_eq!(ring.get_mut(3), None);
2477
2478 assert_eq!(ring.pop_front(), Some(0));
2479 assert_eq!(ring.get_mut(0), Some(&mut -1));
2480 assert_eq!(ring.get_mut(1), Some(&mut 2));
2481 assert_eq!(ring.get_mut(2), None);
2482 }
Matt Murphy40f28c72014-12-03 17:12:302483
2484 #[test]
Piotr Czarnecki156a1c32015-01-05 14:48:582485 fn test_swap_front_back_remove() {
2486 fn test(back: bool) {
2487 // This test checks that every single combination of tail position and length is tested.
2488 // Capacity 15 should be large enough to cover every case.
2489 let mut tester = RingBuf::with_capacity(15);
2490 let usable_cap = tester.capacity();
2491 let final_len = usable_cap / 2;
2492
2493 for len in range(0, final_len) {
2494 let expected = if back {
2495 range(0, len).collect()
2496 } else {
2497 range(0, len).rev().collect()
2498 };
2499 for tail_pos in range(0, usable_cap) {
2500 tester.tail = tail_pos;
2501 tester.head = tail_pos;
2502 if back {
2503 for i in range(0, len * 2) {
2504 tester.push_front(i);
2505 }
2506 for i in range(0, len) {
2507 assert_eq!(tester.swap_back_remove(i), Some(len * 2 - 1 - i));
2508 }
2509 } else {
2510 for i in range(0, len * 2) {
2511 tester.push_back(i);
2512 }
2513 for i in range(0, len) {
2514 let idx = tester.len() - 1 - i;
2515 assert_eq!(tester.swap_front_remove(idx), Some(len * 2 - 1 - i));
2516 }
2517 }
2518 assert!(tester.tail < tester.cap);
2519 assert!(tester.head < tester.cap);
2520 assert_eq!(tester, expected);
2521 }
2522 }
2523 }
2524 test(true);
2525 test(false);
2526 }
2527
2528 #[test]
Matt Murphy40f28c72014-12-03 17:12:302529 fn test_insert() {
2530 // This test checks that every single combination of tail position, length, and
Piotr Czarnecki59d41532014-12-16 23:37:552531 // insertion position is tested. Capacity 15 should be large enough to cover every case.
Matt Murphy40f28c72014-12-03 17:12:302532
Piotr Czarnecki59d41532014-12-16 23:37:552533 let mut tester = RingBuf::with_capacity(15);
2534 // can't guarantee we got 15, so have to get what we got.
2535 // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
Matt Murphy40f28c72014-12-03 17:12:302536 // this test isn't covering what it wants to
2537 let cap = tester.capacity();
2538
2539
2540 // len is the length *after* insertion
2541 for len in range(1, cap) {
2542 // 0, 1, 2, .., len - 1
2543 let expected = iter::count(0, 1).take(len).collect();
2544 for tail_pos in range(0, cap) {
2545 for to_insert in range(0, len) {
2546 tester.tail = tail_pos;
2547 tester.head = tail_pos;
2548 for i in range(0, len) {
2549 if i != to_insert {
2550 tester.push_back(i);
2551 }
2552 }
2553 tester.insert(to_insert, to_insert);
Piotr Czarnecki59d41532014-12-16 23:37:552554 assert!(tester.tail < tester.cap);
2555 assert!(tester.head < tester.cap);
2556 assert_eq!(tester, expected);
2557 }
2558 }
2559 }
2560 }
2561
2562 #[test]
2563 fn test_remove() {
2564 // This test checks that every single combination of tail position, length, and
2565 // removal position is tested. Capacity 15 should be large enough to cover every case.
2566
2567 let mut tester = RingBuf::with_capacity(15);
2568 // can't guarantee we got 15, so have to get what we got.
2569 // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
2570 // this test isn't covering what it wants to
2571 let cap = tester.capacity();
2572
2573 // len is the length *after* removal
2574 for len in range(0, cap - 1) {
2575 // 0, 1, 2, .., len - 1
2576 let expected = iter::count(0, 1).take(len).collect();
2577 for tail_pos in range(0, cap) {
2578 for to_remove in range(0, len + 1) {
2579 tester.tail = tail_pos;
2580 tester.head = tail_pos;
2581 for i in range(0, len) {
2582 if i == to_remove {
2583 tester.push_back(1234);
2584 }
2585 tester.push_back(i);
2586 }
2587 if to_remove == len {
2588 tester.push_back(1234);
2589 }
2590 tester.remove(to_remove);
2591 assert!(tester.tail < tester.cap);
2592 assert!(tester.head < tester.cap);
Matt Murphy40f28c72014-12-03 17:12:302593 assert_eq!(tester, expected);
2594 }
2595 }
2596 }
2597 }
2598
2599 #[test]
Piotr Czarnecki156a1c32015-01-05 14:48:582600 fn test_shrink_to_fit() {
2601 // This test checks that every single combination of head and tail position,
2602 // is tested. Capacity 15 should be large enough to cover every case.
2603
2604 let mut tester = RingBuf::with_capacity(15);
2605 // can't guarantee we got 15, so have to get what we got.
2606 // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
2607 // this test isn't covering what it wants to
2608 let cap = tester.capacity();
2609 tester.reserve(63);
2610 let max_cap = tester.capacity();
2611
2612 for len in range(0, cap + 1) {
2613 // 0, 1, 2, .., len - 1
2614 let expected = iter::count(0, 1).take(len).collect();
2615 for tail_pos in range(0, max_cap + 1) {
2616 tester.tail = tail_pos;
2617 tester.head = tail_pos;
2618 tester.reserve(63);
2619 for i in range(0, len) {
2620 tester.push_back(i);
2621 }
2622 tester.shrink_to_fit();
2623 assert!(tester.capacity() <= cap);
2624 assert!(tester.tail < tester.cap);
2625 assert!(tester.head < tester.cap);
2626 assert_eq!(tester, expected);
2627 }
2628 }
2629 }
2630
2631 #[test]
Matt Murphy40f28c72014-12-03 17:12:302632 fn test_front() {
2633 let mut ring = RingBuf::new();
2634 ring.push_back(10i);
2635 ring.push_back(20i);
2636 assert_eq!(ring.front(), Some(&10));
2637 ring.pop_front();
2638 assert_eq!(ring.front(), Some(&20));
2639 ring.pop_front();
2640 assert_eq!(ring.front(), None);
2641 }
Clark Gaebel525f65e2014-12-16 04:01:582642
2643 #[test]
2644 fn test_as_slices() {
2645 let mut ring: RingBuf<int> = RingBuf::with_capacity(127);
2646 let cap = ring.capacity() as int;
2647 let first = cap/2;
2648 let last = cap - first;
2649 for i in range(0, first) {
2650 ring.push_back(i);
2651
2652 let (left, right) = ring.as_slices();
2653 let expected: Vec<_> = range(0, i+1).collect();
2654 assert_eq!(left, expected);
2655 assert_eq!(right, []);
2656 }
2657
2658 for j in range(-last, 0) {
2659 ring.push_front(j);
2660 let (left, right) = ring.as_slices();
2661 let expected_left: Vec<_> = range(-last, j+1).rev().collect();
2662 let expected_right: Vec<_> = range(0, first).collect();
2663 assert_eq!(left, expected_left);
2664 assert_eq!(right, expected_right);
2665 }
2666
2667 assert_eq!(ring.len() as int, cap);
2668 assert_eq!(ring.capacity() as int, cap);
2669 }
2670
2671 #[test]
2672 fn test_as_mut_slices() {
2673 let mut ring: RingBuf<int> = RingBuf::with_capacity(127);
2674 let cap = ring.capacity() as int;
2675 let first = cap/2;
2676 let last = cap - first;
2677 for i in range(0, first) {
2678 ring.push_back(i);
2679
2680 let (left, right) = ring.as_mut_slices();
2681 let expected: Vec<_> = range(0, i+1).collect();
2682 assert_eq!(left, expected);
2683 assert_eq!(right, []);
2684 }
2685
2686 for j in range(-last, 0) {
2687 ring.push_front(j);
2688 let (left, right) = ring.as_mut_slices();
2689 let expected_left: Vec<_> = range(-last, j+1).rev().collect();
2690 let expected_right: Vec<_> = range(0, first).collect();
2691 assert_eq!(left, expected_left);
2692 assert_eq!(right, expected_right);
2693 }
2694
2695 assert_eq!(ring.len() as int, cap);
2696 assert_eq!(ring.capacity() as int, cap);
2697 }
Michael Sullivanc854d6e2012-07-03 17:52:322698}