rust/src/liballoc/vec_deque.rs

2970 lines
96 KiB
Rust
Raw Normal View History

Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap) This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also deprecates related functions like rsplit, rev_components, and rev_str_components. In every case, these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this more concrete, a translation table for all functional changes necessary follows: * container.rev_iter() -> container.iter().rev() * container.mut_rev_iter() -> container.mut_iter().rev() * container.move_rev_iter() -> container.move_iter().rev() * sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev() * path.rev_components() -> path.components().rev() * path.rev_str_components() -> path.str_components().rev() In terms of the type system, this change also deprecates any specialized reversed iterator types (except in treemap), opting instead to use Rev directly if any type annotations are needed. However, since methods directly returning reversed iterators are now discouraged, the need for such annotations should be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in the original reversed name and surround it with Rev<>: * RevComponents<'a> -> Rev<Components<'a>> * RevStrComponents<'a> -> Rev<StrComponents<'a>> * RevItems<'a, T> -> Rev<Items<'a, T>> * etc. The reasoning behind this change is that it makes the standard API much simpler without reducing readability, performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries (all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft goes away. [breaking-change]
2014-04-20 23:59:12 -05:00
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! A double-ended queue implemented with a growable ring buffer.
//!
2015-02-17 19:00:20 -08:00
//! This queue has `O(1)` amortized inserts and removals from both ends of the
//! container. It also has `O(1)` indexing like a vector. The contained elements
//! are not required to be copyable, and the queue will be sendable if the
//! contained type is sendable.
2015-01-23 21:48:20 -08:00
#![stable(feature = "rust1", since = "1.0.0")]
use core::cmp::Ordering;
std: Recreate a `collections` module As with the previous commit with `librand`, this commit shuffles around some `collections` code. The new state of the world is similar to that of librand: * The libcollections crate now only depends on libcore and liballoc. * The standard library has a new module, `std::collections`. All functionality of libcollections is reexported through this module. I would like to stress that this change is purely cosmetic. There are very few alterations to these primitives. There are a number of notable points about the new organization: * std::{str, slice, string, vec} all moved to libcollections. There is no reason that these primitives shouldn't be necessarily usable in a freestanding context that has allocation. These are all reexported in their usual places in the standard library. * The `hashmap`, and transitively the `lru_cache`, modules no longer reside in `libcollections`, but rather in libstd. The reason for this is because the `HashMap::new` contructor requires access to the OSRng for initially seeding the hash map. Beyond this requirement, there is no reason that the hashmap could not move to libcollections. I do, however, have a plan to move the hash map to the collections module. The `HashMap::new` function could be altered to require that the `H` hasher parameter ascribe to the `Default` trait, allowing the entire `hashmap` module to live in libcollections. The key idea would be that the default hasher would be different in libstd. Something along the lines of: // src/libstd/collections/mod.rs pub type HashMap<K, V, H = RandomizedSipHasher> = core_collections::HashMap<K, V, H>; This is not possible today because you cannot invoke static methods through type aliases. If we modified the compiler, however, to allow invocation of static methods through type aliases, then this type definition would essentially be switching the default hasher from `SipHasher` in libcollections to a libstd-defined `RandomizedSipHasher` type. This type's `Default` implementation would randomly seed the `SipHasher` instance, and otherwise perform the same as `SipHasher`. This future state doesn't seem incredibly far off, but until that time comes, the hashmap module will live in libstd to not compromise on functionality. * In preparation for the hashmap moving to libcollections, the `hash` module has moved from libstd to libcollections. A previously snapshotted commit enables a distinct `Writer` trait to live in the `hash` module which `Hash` implementations are now parameterized over. Due to using a custom trait, the `SipHasher` implementation has lost its specialized methods for writing integers. These can be re-added backwards-compatibly in the future via default methods if necessary, but the FNV hashing should satisfy much of the need for speedier hashing. A list of breaking changes: * HashMap::{get, get_mut} no longer fails with the key formatted into the error message with `{:?}`, instead, a generic message is printed. With backtraces, it should still be not-too-hard to track down errors. * The HashMap, HashSet, and LruCache types are now available through std::collections instead of the collections crate. * Manual implementations of hash should be parameterized over `hash::Writer` instead of just `Writer`. [breaking-change]
2014-05-29 18:50:12 -07:00
use core::fmt;
use core::iter::{repeat, FromIterator, FusedIterator};
use core::mem;
use core::ops::{Index, IndexMut, Place, Placer, InPlace, RangeArgument};
use core::ops::Bound::{Excluded, Included, Unbounded};
2015-07-09 21:57:21 -07:00
use core::ptr;
use core::ptr::Shared;
use core::slice;
use core::hash::{Hash, Hasher};
use core::cmp;
2013-05-06 00:42:54 -04:00
2017-06-13 15:52:59 -07:00
use raw_vec::RawVec;
use super::vec::Vec;
const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
const MINIMUM_CAPACITY: usize = 1; // 2 - 1
std: Stabilize APIs for the 1.7 release This commit stabilizes and deprecates the FCP (final comment period) APIs for the upcoming 1.7 beta release. The specific APIs which changed were: Stabilized * `Path::strip_prefix` (renamed from `relative_from`) * `path::StripPrefixError` (new error type returned from `strip_prefix`) * `Ipv4Addr::is_loopback` * `Ipv4Addr::is_private` * `Ipv4Addr::is_link_local` * `Ipv4Addr::is_multicast` * `Ipv4Addr::is_broadcast` * `Ipv4Addr::is_documentation` * `Ipv6Addr::is_unspecified` * `Ipv6Addr::is_loopback` * `Ipv6Addr::is_unique_local` * `Ipv6Addr::is_multicast` * `Vec::as_slice` * `Vec::as_mut_slice` * `String::as_str` * `String::as_mut_str` * `<[T]>::clone_from_slice` - the `usize` return value is removed * `<[T]>::sort_by_key` * `i32::checked_rem` (and other signed types) * `i32::checked_neg` (and other signed types) * `i32::checked_shl` (and other signed types) * `i32::checked_shr` (and other signed types) * `i32::saturating_mul` (and other signed types) * `i32::overflowing_add` (and other signed types) * `i32::overflowing_sub` (and other signed types) * `i32::overflowing_mul` (and other signed types) * `i32::overflowing_div` (and other signed types) * `i32::overflowing_rem` (and other signed types) * `i32::overflowing_neg` (and other signed types) * `i32::overflowing_shl` (and other signed types) * `i32::overflowing_shr` (and other signed types) * `u32::checked_rem` (and other unsigned types) * `u32::checked_neg` (and other unsigned types) * `u32::checked_shl` (and other unsigned types) * `u32::saturating_mul` (and other unsigned types) * `u32::overflowing_add` (and other unsigned types) * `u32::overflowing_sub` (and other unsigned types) * `u32::overflowing_mul` (and other unsigned types) * `u32::overflowing_div` (and other unsigned types) * `u32::overflowing_rem` (and other unsigned types) * `u32::overflowing_neg` (and other unsigned types) * `u32::overflowing_shl` (and other unsigned types) * `u32::overflowing_shr` (and other unsigned types) * `ffi::IntoStringError` * `CString::into_string` * `CString::into_bytes` * `CString::into_bytes_with_nul` * `From<CString> for Vec<u8>` * `From<CString> for Vec<u8>` * `IntoStringError::into_cstring` * `IntoStringError::utf8_error` * `Error for IntoStringError` Deprecated * `Path::relative_from` - renamed to `strip_prefix` * `Path::prefix` - use `components().next()` instead * `os::unix::fs` constants - moved to the `libc` crate * `fmt::{radix, Radix, RadixFmt}` - not used enough to stabilize * `IntoCow` - conflicts with `Into` and may come back later * `i32::{BITS, BYTES}` (and other integers) - not pulling their weight * `DebugTuple::formatter` - will be removed * `sync::Semaphore` - not used enough and confused with system semaphores Closes #23284 cc #27709 (still lots more methods though) Closes #27712 Closes #27722 Closes #27728 Closes #27735 Closes #27729 Closes #27755 Closes #27782 Closes #27798
2016-01-15 10:07:52 -08:00
#[cfg(target_pointer_width = "32")]
const MAXIMUM_ZST_CAPACITY: usize = 1 << (32 - 1); // Largest possible power of two
#[cfg(target_pointer_width = "64")]
const MAXIMUM_ZST_CAPACITY: usize = 1 << (64 - 1); // Largest possible power of two
/// A double-ended queue implemented with a growable ring buffer.
///
/// The "default" usage of this type as a queue is to use [`push_back`] to add to
/// the queue, and [`pop_front`] to remove from the queue. [`extend`] and [`append`]
std: Stabilize library APIs for 1.5 This commit stabilizes and deprecates library APIs whose FCP has closed in the last cycle, specifically: Stabilized APIs: * `fs::canonicalize` * `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists, is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait. * `Formatter::fill` * `Formatter::width` * `Formatter::precision` * `Formatter::sign_plus` * `Formatter::sign_minus` * `Formatter::alternate` * `Formatter::sign_aware_zero_pad` * `string::ParseError` * `Utf8Error::valid_up_to` * `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}` * `<[T]>::split_{first,last}{,_mut}` * `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated but will be once 1.5 is released. * `str::{R,}MatchIndices` * `str::{r,}match_indices` * `char::from_u32_unchecked` * `VecDeque::insert` * `VecDeque::shrink_to_fit` * `VecDeque::as_slices` * `VecDeque::as_mut_slices` * `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`) * `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`) * `Vec::resize` * `str::slice_mut_unchecked` * `FileTypeExt` * `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}` * `BinaryHeap::from` - `from_vec` deprecated in favor of this * `BinaryHeap::into_vec` - plus a `Into` impl * `BinaryHeap::into_sorted_vec` Deprecated APIs * `slice::ref_slice` * `slice::mut_ref_slice` * `iter::{range_inclusive, RangeInclusive}` * `std::dynamic_lib` Closes #27706 Closes #27725 cc #27726 (align not stabilized yet) Closes #27734 Closes #27737 Closes #27742 Closes #27743 Closes #27772 Closes #27774 Closes #27777 Closes #27781 cc #27788 (a few remaining methods though) Closes #27790 Closes #27793 Closes #27796 Closes #27810 cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
/// push onto the back in this manner, and iterating over `VecDeque` goes front
/// to back.
///
/// [`push_back`]: #method.push_back
/// [`pop_front`]: #method.pop_front
/// [`extend`]: #method.extend
/// [`append`]: #method.append
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub struct VecDeque<T> {
// tail and head are pointers into the buffer. Tail always points
// to the first element that could be read, Head always points
// to where data should be written.
// If tail == head the buffer is empty. The length of the ringbuffer
// is defined as the distance between the two.
2015-02-04 21:17:19 -05:00
tail: usize,
head: usize,
2015-07-09 21:57:21 -07:00
buf: RawVec<T>,
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone> Clone for VecDeque<T> {
fn clone(&self) -> VecDeque<T> {
2015-02-04 21:17:19 -05:00
self.iter().cloned().collect()
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<#[may_dangle] T> Drop for VecDeque<T> {
fn drop(&mut self) {
let (front, back) = self.as_mut_slices();
unsafe {
// use drop for [T]
ptr::drop_in_place(front);
ptr::drop_in_place(back);
}
2015-07-09 21:57:21 -07:00
// RawVec handles deallocation
}
2012-01-11 12:49:33 +01:00
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for VecDeque<T> {
/// Creates an empty `VecDeque<T>`.
#[inline]
2015-11-24 11:23:48 +13:00
fn default() -> VecDeque<T> {
VecDeque::new()
}
}
impl<T> VecDeque<T> {
2015-07-09 21:57:21 -07:00
/// Marginally more convenient
#[inline]
fn ptr(&self) -> *mut T {
self.buf.ptr()
}
/// Marginally more convenient
#[inline]
fn cap(&self) -> usize {
if mem::size_of::<T>() == 0 {
// For zero sized types, we are always at maximum capacity
MAXIMUM_ZST_CAPACITY
} else {
self.buf.cap()
}
2015-07-09 21:57:21 -07:00
}
/// Turn ptr into a slice
#[inline]
2014-12-30 19:07:53 -05:00
unsafe fn buffer_as_slice(&self) -> &[T] {
2015-07-09 21:57:21 -07:00
slice::from_raw_parts(self.ptr(), self.cap())
}
/// Turn ptr into a mut slice
#[inline]
2014-12-30 19:07:53 -05:00
unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] {
2015-07-09 21:57:21 -07:00
slice::from_raw_parts_mut(self.ptr(), self.cap())
}
/// Moves an element out of the buffer
#[inline]
2015-02-04 21:17:19 -05:00
unsafe fn buffer_read(&mut self, off: usize) -> T {
2015-07-09 21:57:21 -07:00
ptr::read(self.ptr().offset(off as isize))
}
/// Writes an element into the buffer, moving it.
#[inline]
unsafe fn buffer_write(&mut self, off: usize, value: T) {
ptr::write(self.ptr().offset(off as isize), value);
}
/// Returns `true` if and only if the buffer is at full capacity.
#[inline]
2015-11-24 11:23:48 +13:00
fn is_full(&self) -> bool {
self.cap() - self.len() == 1
}
2015-02-17 19:00:20 -08:00
/// Returns the index in the underlying buffer for a given logical element
/// index.
#[inline]
2015-11-24 11:23:48 +13:00
fn wrap_index(&self, idx: usize) -> usize {
wrap_index(idx, self.cap())
}
2014-12-03 11:12:30 -06:00
/// Returns the index in the underlying buffer for a given logical element
/// index + addend.
#[inline]
fn wrap_add(&self, idx: usize, addend: usize) -> usize {
2015-07-09 21:57:21 -07:00
wrap_index(idx.wrapping_add(addend), self.cap())
}
/// Returns the index in the underlying buffer for a given logical element
/// index - subtrahend.
#[inline]
fn wrap_sub(&self, idx: usize, subtrahend: usize) -> usize {
2015-07-09 21:57:21 -07:00
wrap_index(idx.wrapping_sub(subtrahend), self.cap())
}
2014-12-03 11:12:30 -06:00
/// Copies a contiguous block of memory len long from src to dst
#[inline]
2015-02-04 21:17:19 -05:00
unsafe fn copy(&self, dst: usize, src: usize, len: usize) {
2015-11-24 11:23:48 +13:00
debug_assert!(dst + len <= self.cap(),
"cpy dst={} src={} len={} cap={}",
dst,
src,
len,
2015-07-09 21:57:21 -07:00
self.cap());
2015-11-24 11:23:48 +13:00
debug_assert!(src + len <= self.cap(),
"cpy dst={} src={} len={} cap={}",
dst,
src,
len,
2015-07-09 21:57:21 -07:00
self.cap());
2015-11-24 11:23:48 +13:00
ptr::copy(self.ptr().offset(src as isize),
self.ptr().offset(dst as isize),
len);
}
/// Copies a contiguous block of memory len long from src to dst
#[inline]
2015-02-04 21:17:19 -05:00
unsafe fn copy_nonoverlapping(&self, dst: usize, src: usize, len: usize) {
2015-11-24 11:23:48 +13:00
debug_assert!(dst + len <= self.cap(),
"cno dst={} src={} len={} cap={}",
dst,
src,
len,
2015-07-09 21:57:21 -07:00
self.cap());
2015-11-24 11:23:48 +13:00
debug_assert!(src + len <= self.cap(),
"cno dst={} src={} len={} cap={}",
dst,
src,
len,
2015-07-09 21:57:21 -07:00
self.cap());
2015-11-24 11:23:48 +13:00
ptr::copy_nonoverlapping(self.ptr().offset(src as isize),
self.ptr().offset(dst as isize),
len);
2014-12-03 11:12:30 -06:00
}
2015-07-09 21:57:21 -07:00
/// Copies a potentially wrapping block of memory len long from src to dest.
/// (abs(dst - src) + len) must be no larger than cap() (There must be at
/// most one continuous overlapping region between src and dest).
unsafe fn wrap_copy(&self, dst: usize, src: usize, len: usize) {
#[allow(dead_code)]
2015-11-24 11:23:48 +13:00
fn diff(a: usize, b: usize) -> usize {
2016-12-20 09:54:00 +05:30
if a <= b { b - a } else { a - b }
2015-11-24 11:23:48 +13:00
}
debug_assert!(cmp::min(diff(dst, src), self.cap() - diff(dst, src)) + len <= self.cap(),
"wrc dst={} src={} len={} cap={}",
dst,
src,
len,
self.cap());
2015-11-24 11:23:48 +13:00
if src == dst || len == 0 {
return;
}
let dst_after_src = self.wrap_sub(dst, src) < len;
let src_pre_wrap_len = self.cap() - src;
let dst_pre_wrap_len = self.cap() - dst;
let src_wraps = src_pre_wrap_len < len;
let dst_wraps = dst_pre_wrap_len < len;
match (dst_after_src, src_wraps, dst_wraps) {
(_, false, false) => {
// src doesn't wrap, dst doesn't wrap
//
// S . . .
// 1 [_ _ A A B B C C _]
// 2 [_ _ A A A A B B _]
// D . . .
//
self.copy(dst, src, len);
}
(false, false, true) => {
// dst before src, src doesn't wrap, dst wraps
//
// S . . .
// 1 [A A B B _ _ _ C C]
// 2 [A A B B _ _ _ A A]
// 3 [B B B B _ _ _ A A]
// . . D .
//
self.copy(dst, src, dst_pre_wrap_len);
self.copy(0, src + dst_pre_wrap_len, len - dst_pre_wrap_len);
}
(true, false, true) => {
// src before dst, src doesn't wrap, dst wraps
//
// S . . .
// 1 [C C _ _ _ A A B B]
// 2 [B B _ _ _ A A B B]
// 3 [B B _ _ _ A A A A]
// . . D .
//
self.copy(0, src + dst_pre_wrap_len, len - dst_pre_wrap_len);
self.copy(dst, src, dst_pre_wrap_len);
}
(false, true, false) => {
// dst before src, src wraps, dst doesn't wrap
//
// . . S .
// 1 [C C _ _ _ A A B B]
// 2 [C C _ _ _ B B B B]
// 3 [C C _ _ _ B B C C]
// D . . .
//
self.copy(dst, src, src_pre_wrap_len);
self.copy(dst + src_pre_wrap_len, 0, len - src_pre_wrap_len);
}
(true, true, false) => {
// src before dst, src wraps, dst doesn't wrap
//
// . . S .
// 1 [A A B B _ _ _ C C]
// 2 [A A A A _ _ _ C C]
// 3 [C C A A _ _ _ C C]
// D . . .
//
self.copy(dst + src_pre_wrap_len, 0, len - src_pre_wrap_len);
self.copy(dst, src, src_pre_wrap_len);
}
(false, true, true) => {
// dst before src, src wraps, dst wraps
//
// . . . S .
// 1 [A B C D _ E F G H]
// 2 [A B C D _ E G H H]
// 3 [A B C D _ E G H A]
// 4 [B C C D _ E G H A]
// . . D . .
//
debug_assert!(dst_pre_wrap_len > src_pre_wrap_len);
let delta = dst_pre_wrap_len - src_pre_wrap_len;
self.copy(dst, src, src_pre_wrap_len);
self.copy(dst + src_pre_wrap_len, 0, delta);
self.copy(0, delta, len - dst_pre_wrap_len);
}
(true, true, true) => {
// src before dst, src wraps, dst wraps
//
// . . S . .
// 1 [A B C D _ E F G H]
// 2 [A A B D _ E F G H]
// 3 [H A B D _ E F G H]
// 4 [H A B D _ E F F G]
// . . . D .
//
debug_assert!(src_pre_wrap_len > dst_pre_wrap_len);
let delta = src_pre_wrap_len - dst_pre_wrap_len;
self.copy(delta, 0, len - src_pre_wrap_len);
self.copy(0, self.cap() - delta, delta);
self.copy(dst, src, dst_pre_wrap_len);
}
}
}
2015-07-09 21:57:21 -07:00
/// Frobs the head and tail sections around to handle the fact that we
/// just reallocated. Unsafe because it trusts old_cap.
#[inline]
unsafe fn handle_cap_increase(&mut self, old_cap: usize) {
let new_cap = self.cap();
// Move the shortest contiguous section of the ring buffer
// T H
// [o o o o o o o . ]
// T H
// A [o o o o o o o . . . . . . . . . ]
// H T
// [o o . o o o o o ]
// T H
// B [. . . o o o o o o o . . . . . . ]
// H T
// [o o o o o . o o ]
// H T
// C [o o o o o . . . . . . . . . o o ]
2015-11-24 11:23:48 +13:00
if self.tail <= self.head {
// A
2015-07-09 21:57:21 -07:00
// Nop
2015-11-24 11:23:48 +13:00
} else if self.head < old_cap - self.tail {
// B
2015-07-09 21:57:21 -07:00
self.copy_nonoverlapping(old_cap, 0, self.head);
self.head += old_cap;
debug_assert!(self.head > self.tail);
2015-11-24 11:23:48 +13:00
} else {
// C
2015-07-09 21:57:21 -07:00
let new_tail = new_cap - (old_cap - self.tail);
self.copy_nonoverlapping(new_tail, self.tail, old_cap - self.tail);
self.tail = new_tail;
debug_assert!(self.head < self.tail);
}
debug_assert!(self.head < self.cap());
debug_assert!(self.tail < self.cap());
debug_assert!(self.cap().count_ones() == 1);
}
}
impl<T> VecDeque<T> {
/// Creates an empty `VecDeque`.
2016-07-16 18:00:05 +02:00
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let vector: VecDeque<u32> = VecDeque::new();
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> VecDeque<T> {
VecDeque::with_capacity(INITIAL_CAPACITY)
}
/// Creates an empty `VecDeque` with space for at least `n` elements.
2016-07-16 18:00:05 +02:00
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let vector: VecDeque<u32> = VecDeque::with_capacity(10);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn with_capacity(n: usize) -> VecDeque<T> {
// +1 since the ringbuffer always leaves one space empty
let cap = cmp::max(n + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
assert!(cap > n, "capacity overflow");
VecDeque {
tail: 0,
head: 0,
2015-07-09 21:57:21 -07:00
buf: RawVec::with_capacity(cap),
}
}
/// Retrieves an element in the `VecDeque` by index.
///
/// Element at index 0 is the front of the queue.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
2015-01-25 22:05:03 +01:00
/// buf.push_back(3);
/// buf.push_back(4);
/// buf.push_back(5);
2015-07-17 23:49:13 +02:00
/// assert_eq!(buf.get(1), Some(&4));
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get(&self, index: usize) -> Option<&T> {
if index < self.len() {
let idx = self.wrap_add(self.tail, index);
2015-07-09 21:57:21 -07:00
unsafe { Some(&*self.ptr().offset(idx as isize)) }
} else {
None
}
}
/// Retrieves an element in the `VecDeque` mutably by index.
///
/// Element at index 0 is the front of the queue.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
2015-01-25 22:05:03 +01:00
/// buf.push_back(3);
/// buf.push_back(4);
/// buf.push_back(5);
/// if let Some(elem) = buf.get_mut(1) {
/// *elem = 7;
/// }
///
/// assert_eq!(buf[1], 7);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
if index < self.len() {
let idx = self.wrap_add(self.tail, index);
2015-07-09 21:57:21 -07:00
unsafe { Some(&mut *self.ptr().offset(idx as isize)) }
} else {
None
}
}
2014-08-04 22:48:39 +12:00
/// Swaps elements at indices `i` and `j`.
///
/// `i` and `j` may be equal.
///
2014-08-04 22:48:39 +12:00
/// Fails if there is no element with either index.
///
/// Element at index 0 is the front of the queue.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
2015-01-25 22:05:03 +01:00
/// buf.push_back(3);
/// buf.push_back(4);
/// buf.push_back(5);
/// assert_eq!(buf, [3, 4, 5]);
/// buf.swap(0, 2);
/// assert_eq!(buf, [5, 4, 3]);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn swap(&mut self, i: usize, j: usize) {
assert!(i < self.len());
assert!(j < self.len());
let ri = self.wrap_add(self.tail, i);
let rj = self.wrap_add(self.tail, j);
unsafe {
2015-11-24 11:23:48 +13:00
ptr::swap(self.ptr().offset(ri as isize),
self.ptr().offset(rj as isize))
}
}
/// Returns the number of elements the `VecDeque` can hold without
/// reallocating.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let buf: VecDeque<i32> = VecDeque::with_capacity(10);
/// assert!(buf.capacity() >= 10);
/// ```
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-11-24 11:23:48 +13:00
pub fn capacity(&self) -> usize {
self.cap() - 1
}
/// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
/// given `VecDeque`. Does nothing if the capacity is already sufficient.
///
/// Note that the allocator may give the collection more space than it requests. Therefore
/// capacity can not be relied upon to be precisely minimal. Prefer [`reserve`] if future
/// insertions are expected.
///
/// # Panics
///
2015-02-04 21:17:19 -05:00
/// Panics if the new capacity overflows `usize`.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
/// buf.reserve_exact(10);
/// assert!(buf.capacity() >= 11);
/// ```
///
/// [`reserve`]: #method.reserve
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn reserve_exact(&mut self, additional: usize) {
self.reserve(additional);
}
/// Reserves capacity for at least `additional` more elements to be inserted in the given
/// `VecDeque`. The collection may reserve more space to avoid frequent reallocations.
///
/// # Panics
///
2015-02-04 21:17:19 -05:00
/// Panics if the new capacity overflows `usize`.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
/// buf.reserve(10);
/// assert!(buf.capacity() >= 11);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn reserve(&mut self, additional: usize) {
2015-07-09 21:57:21 -07:00
let old_cap = self.cap();
let used_cap = self.len() + 1;
2015-11-24 11:23:48 +13:00
let new_cap = used_cap.checked_add(additional)
2016-12-20 09:54:00 +05:30
.and_then(|needed_cap| needed_cap.checked_next_power_of_two())
.expect("capacity overflow");
2015-07-09 21:57:21 -07:00
if new_cap > self.capacity() {
self.buf.reserve_exact(used_cap, new_cap - used_cap);
2015-11-24 11:23:48 +13:00
unsafe {
self.handle_cap_increase(old_cap);
}
}
}
/// Shrinks the capacity of the `VecDeque` as much as possible.
///
/// It will drop down as close as possible to the length but the allocator may still inform the
/// `VecDeque` that there is space for a few more elements.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::with_capacity(15);
/// buf.extend(0..4);
/// assert_eq!(buf.capacity(), 15);
/// buf.shrink_to_fit();
/// assert!(buf.capacity() >= 4);
/// ```
std: Stabilize library APIs for 1.5 This commit stabilizes and deprecates library APIs whose FCP has closed in the last cycle, specifically: Stabilized APIs: * `fs::canonicalize` * `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists, is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait. * `Formatter::fill` * `Formatter::width` * `Formatter::precision` * `Formatter::sign_plus` * `Formatter::sign_minus` * `Formatter::alternate` * `Formatter::sign_aware_zero_pad` * `string::ParseError` * `Utf8Error::valid_up_to` * `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}` * `<[T]>::split_{first,last}{,_mut}` * `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated but will be once 1.5 is released. * `str::{R,}MatchIndices` * `str::{r,}match_indices` * `char::from_u32_unchecked` * `VecDeque::insert` * `VecDeque::shrink_to_fit` * `VecDeque::as_slices` * `VecDeque::as_mut_slices` * `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`) * `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`) * `Vec::resize` * `str::slice_mut_unchecked` * `FileTypeExt` * `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}` * `BinaryHeap::from` - `from_vec` deprecated in favor of this * `BinaryHeap::into_vec` - plus a `Into` impl * `BinaryHeap::into_sorted_vec` Deprecated APIs * `slice::ref_slice` * `slice::mut_ref_slice` * `iter::{range_inclusive, RangeInclusive}` * `std::dynamic_lib` Closes #27706 Closes #27725 cc #27726 (align not stabilized yet) Closes #27734 Closes #27737 Closes #27742 Closes #27743 Closes #27772 Closes #27774 Closes #27777 Closes #27781 cc #27788 (a few remaining methods though) Closes #27790 Closes #27793 Closes #27796 Closes #27810 cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
#[stable(feature = "deque_extras_15", since = "1.5.0")]
pub fn shrink_to_fit(&mut self) {
// +1 since the ringbuffer always leaves one space empty
// len + 1 can't overflow for an existing, well-formed ringbuffer.
let target_cap = cmp::max(self.len() + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
2015-07-09 21:57:21 -07:00
if target_cap < self.cap() {
// There are three cases of interest:
// All elements are out of desired bounds
// Elements are contiguous, and head is out of desired bounds
// Elements are discontiguous, and tail is out of desired bounds
//
// At all other times, element positions are unaffected.
//
// Indicates that elements at the head should be moved.
let head_outside = self.head == 0 || self.head >= target_cap;
// Move elements from out of desired bounds (positions after target_cap)
if self.tail >= target_cap && head_outside {
// T H
// [. . . . . . . . o o o o o o o . ]
// T H
// [o o o o o o o . ]
unsafe {
self.copy_nonoverlapping(0, self.tail, self.len());
}
self.head = self.len();
self.tail = 0;
} else if self.tail != 0 && self.tail < target_cap && head_outside {
// T H
// [. . . o o o o o o o . . . . . . ]
// H T
// [o o . o o o o o ]
let len = self.wrap_sub(self.head, target_cap);
unsafe {
self.copy_nonoverlapping(0, target_cap, len);
}
self.head = len;
debug_assert!(self.head < self.tail);
} else if self.tail >= target_cap {
// H T
// [o o o o o . . . . . . . . . o o ]
// H T
// [o o o o o . o o ]
debug_assert!(self.wrap_sub(self.head, 1) < target_cap);
2015-07-09 21:57:21 -07:00
let len = self.cap() - self.tail;
let new_tail = target_cap - len;
unsafe {
self.copy_nonoverlapping(new_tail, self.tail, len);
}
self.tail = new_tail;
debug_assert!(self.head < self.tail);
}
2015-07-09 21:57:21 -07:00
self.buf.shrink_to_fit(target_cap);
debug_assert!(self.head < self.cap());
debug_assert!(self.tail < self.cap());
debug_assert!(self.cap().count_ones() == 1);
}
}
2013-06-25 15:08:47 -04:00
2017-03-31 17:12:47 +02:00
/// Shortens the `VecDeque`, dropping excess elements from the back.
///
/// If `len` is greater than the `VecDeque`'s current length, this has no
/// effect.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
2015-01-25 22:05:03 +01:00
/// buf.push_back(5);
/// buf.push_back(10);
/// buf.push_back(15);
/// assert_eq!(buf, [5, 10, 15]);
/// buf.truncate(1);
/// assert_eq!(buf, [5]);
/// ```
#[stable(feature = "deque_extras", since = "1.16.0")]
2015-02-04 21:17:19 -05:00
pub fn truncate(&mut self, len: usize) {
for _ in len..self.len() {
self.pop_back();
}
}
2014-08-04 22:48:39 +12:00
/// Returns a front-to-back iterator.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
2015-01-25 22:05:03 +01:00
/// buf.push_back(5);
/// buf.push_back(3);
/// buf.push_back(4);
2014-08-06 11:59:40 +02:00
/// let b: &[_] = &[&5, &3, &4];
2015-03-30 19:22:46 +03:00
/// let c: Vec<&i32> = buf.iter().collect();
/// assert_eq!(&c[..], b);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn iter(&self) -> Iter<T> {
Iter {
tail: self.tail,
head: self.head,
2015-11-24 11:23:48 +13:00
ring: unsafe { self.buffer_as_slice() },
}
2013-06-25 15:08:47 -04:00
}
/// Returns a front-to-back iterator that returns mutable references.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
2015-01-25 22:05:03 +01:00
/// buf.push_back(5);
/// buf.push_back(3);
/// buf.push_back(4);
2014-09-14 20:27:36 -07:00
/// for num in buf.iter_mut() {
/// *num = *num - 2;
/// }
2014-08-06 11:59:40 +02:00
/// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
/// assert_eq!(&buf.iter_mut().collect::<Vec<&mut i32>>()[..], b);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut {
tail: self.tail,
head: self.head,
ring: unsafe { self.buffer_as_mut_slice() },
}
2013-06-25 15:08:47 -04:00
}
/// Returns a pair of slices which contain, in order, the contents of the
/// `VecDeque`.
2016-07-16 18:00:05 +02:00
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
2016-09-22 22:05:41 -04:00
/// let mut vector = VecDeque::new();
2016-07-16 18:00:05 +02:00
///
/// vector.push_back(0);
/// vector.push_back(1);
/// vector.push_back(2);
///
2016-09-22 22:05:41 -04:00
/// assert_eq!(vector.as_slices(), (&[0, 1, 2][..], &[][..]));
2016-07-16 18:00:05 +02:00
///
/// vector.push_front(10);
/// vector.push_front(9);
///
2016-09-22 22:05:41 -04:00
/// assert_eq!(vector.as_slices(), (&[9, 10][..], &[0, 1, 2][..]));
2016-07-16 18:00:05 +02:00
/// ```
#[inline]
std: Stabilize library APIs for 1.5 This commit stabilizes and deprecates library APIs whose FCP has closed in the last cycle, specifically: Stabilized APIs: * `fs::canonicalize` * `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists, is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait. * `Formatter::fill` * `Formatter::width` * `Formatter::precision` * `Formatter::sign_plus` * `Formatter::sign_minus` * `Formatter::alternate` * `Formatter::sign_aware_zero_pad` * `string::ParseError` * `Utf8Error::valid_up_to` * `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}` * `<[T]>::split_{first,last}{,_mut}` * `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated but will be once 1.5 is released. * `str::{R,}MatchIndices` * `str::{r,}match_indices` * `char::from_u32_unchecked` * `VecDeque::insert` * `VecDeque::shrink_to_fit` * `VecDeque::as_slices` * `VecDeque::as_mut_slices` * `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`) * `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`) * `Vec::resize` * `str::slice_mut_unchecked` * `FileTypeExt` * `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}` * `BinaryHeap::from` - `from_vec` deprecated in favor of this * `BinaryHeap::into_vec` - plus a `Into` impl * `BinaryHeap::into_sorted_vec` Deprecated APIs * `slice::ref_slice` * `slice::mut_ref_slice` * `iter::{range_inclusive, RangeInclusive}` * `std::dynamic_lib` Closes #27706 Closes #27725 cc #27726 (align not stabilized yet) Closes #27734 Closes #27737 Closes #27742 Closes #27743 Closes #27772 Closes #27774 Closes #27777 Closes #27781 cc #27788 (a few remaining methods though) Closes #27790 Closes #27793 Closes #27796 Closes #27810 cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
#[stable(feature = "deque_extras_15", since = "1.5.0")]
pub fn as_slices(&self) -> (&[T], &[T]) {
unsafe {
let buf = self.buffer_as_slice();
RingSlices::ring_slices(buf, self.head, self.tail)
}
}
/// Returns a pair of slices which contain, in order, the contents of the
/// `VecDeque`.
2016-07-16 18:00:05 +02:00
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
2016-09-22 22:05:41 -04:00
/// let mut vector = VecDeque::new();
2016-07-16 18:00:05 +02:00
///
/// vector.push_back(0);
/// vector.push_back(1);
///
/// vector.push_front(10);
/// vector.push_front(9);
///
/// vector.as_mut_slices().0[0] = 42;
/// vector.as_mut_slices().1[0] = 24;
2016-09-22 22:05:41 -04:00
/// assert_eq!(vector.as_slices(), (&[42, 10][..], &[24, 1][..]));
2016-07-16 18:00:05 +02:00
/// ```
#[inline]
std: Stabilize library APIs for 1.5 This commit stabilizes and deprecates library APIs whose FCP has closed in the last cycle, specifically: Stabilized APIs: * `fs::canonicalize` * `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists, is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait. * `Formatter::fill` * `Formatter::width` * `Formatter::precision` * `Formatter::sign_plus` * `Formatter::sign_minus` * `Formatter::alternate` * `Formatter::sign_aware_zero_pad` * `string::ParseError` * `Utf8Error::valid_up_to` * `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}` * `<[T]>::split_{first,last}{,_mut}` * `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated but will be once 1.5 is released. * `str::{R,}MatchIndices` * `str::{r,}match_indices` * `char::from_u32_unchecked` * `VecDeque::insert` * `VecDeque::shrink_to_fit` * `VecDeque::as_slices` * `VecDeque::as_mut_slices` * `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`) * `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`) * `Vec::resize` * `str::slice_mut_unchecked` * `FileTypeExt` * `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}` * `BinaryHeap::from` - `from_vec` deprecated in favor of this * `BinaryHeap::into_vec` - plus a `Into` impl * `BinaryHeap::into_sorted_vec` Deprecated APIs * `slice::ref_slice` * `slice::mut_ref_slice` * `iter::{range_inclusive, RangeInclusive}` * `std::dynamic_lib` Closes #27706 Closes #27725 cc #27726 (align not stabilized yet) Closes #27734 Closes #27737 Closes #27742 Closes #27743 Closes #27772 Closes #27774 Closes #27777 Closes #27781 cc #27788 (a few remaining methods though) Closes #27790 Closes #27793 Closes #27796 Closes #27810 cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
#[stable(feature = "deque_extras_15", since = "1.5.0")]
pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
unsafe {
let head = self.head;
let tail = self.tail;
let buf = self.buffer_as_mut_slice();
RingSlices::ring_slices(buf, head, tail)
}
}
/// Returns the number of elements in the `VecDeque`.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut v = VecDeque::new();
/// assert_eq!(v.len(), 0);
2015-01-25 22:05:03 +01:00
/// v.push_back(1);
/// assert_eq!(v.len(), 1);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-11-24 11:23:48 +13:00
pub fn len(&self) -> usize {
count(self.tail, self.head, self.cap())
}
/// Returns `true` if the `VecDeque` is empty.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut v = VecDeque::new();
/// assert!(v.is_empty());
2015-01-25 22:05:03 +01:00
/// v.push_front(1);
/// assert!(!v.is_empty());
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-11-24 11:23:48 +13:00
pub fn is_empty(&self) -> bool {
self.tail == self.head
2015-11-24 11:23:48 +13:00
}
/// Create a draining iterator that removes the specified range in the
/// `VecDeque` and yields the removed items.
///
/// Note 1: The element range is removed even if the iterator is not
/// consumed until the end.
///
/// Note 2: It is unspecified how many elements are removed from the deque,
/// if the `Drain` value is not dropped, but the borrow it holds expires
/// (eg. due to mem::forget).
///
/// # Panics
///
/// Panics if the starting point is greater than the end point or if
/// the end point is greater than the length of the vector.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
2016-07-16 18:00:05 +02:00
///
/// let mut v: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
/// let drained = v.drain(2..).collect::<VecDeque<_>>();
/// assert_eq!(drained, [3]);
/// assert_eq!(v, [1, 2]);
///
/// // A full range clears all contents
/// v.drain(..);
/// assert!(v.is_empty());
/// ```
#[inline]
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[stable(feature = "drain", since = "1.6.0")]
2015-11-24 11:23:48 +13:00
pub fn drain<R>(&mut self, range: R) -> Drain<T>
where R: RangeArgument<usize>
{
// Memory safety
//
// When the Drain is first created, the source deque is shortened to
// make sure no uninitialized or moved-from elements are accessible at
// all if the Drain's destructor never gets to run.
//
// Drain will ptr::read out the values to remove.
// When finished, the remaining data will be copied back to cover the hole,
// and the head/tail values will be restored correctly.
//
let len = self.len();
let start = match range.start() {
Included(&n) => n,
Excluded(&n) => n + 1,
Unbounded => 0,
};
let end = match range.end() {
Included(&n) => n + 1,
Excluded(&n) => n,
Unbounded => len,
};
assert!(start <= end, "drain lower bound was too large");
assert!(end <= len, "drain upper bound was too large");
// The deque's elements are parted into three segments:
// * self.tail -> drain_tail
// * drain_tail -> drain_head
// * drain_head -> self.head
//
// T = self.tail; H = self.head; t = drain_tail; h = drain_head
//
// We store drain_tail as self.head, and drain_head and self.head as
// after_tail and after_head respectively on the Drain. This also
// truncates the effective array such that if the Drain is leaked, we
// have forgotten about the potentially moved values after the start of
// the drain.
//
// T t h H
// [. . . o o x x o o . . .]
//
let drain_tail = self.wrap_add(self.tail, start);
let drain_head = self.wrap_add(self.tail, end);
let head = self.head;
// "forget" about the values after the start of the drain until after
// the drain is complete and the Drain destructor is run.
self.head = drain_tail;
Drain {
deque: unsafe { Shared::new(self as *mut _) },
after_tail: drain_head,
after_head: head,
iter: Iter {
tail: drain_tail,
head: drain_head,
ring: unsafe { self.buffer_as_mut_slice() },
},
}
}
/// Clears the buffer, removing all values.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut v = VecDeque::new();
2015-01-25 22:05:03 +01:00
/// v.push_back(1);
/// v.clear();
/// assert!(v.is_empty());
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn clear(&mut self) {
self.drain(..);
}
/// Returns `true` if the `VecDeque` contains an element equal to the
/// given value.
2016-07-16 18:00:05 +02:00
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut vector: VecDeque<u32> = VecDeque::new();
///
/// vector.push_back(0);
/// vector.push_back(1);
///
/// assert_eq!(vector.contains(&1), true);
/// assert_eq!(vector.contains(&10), false);
/// ```
#[stable(feature = "vec_deque_contains", since = "1.12.0")]
pub fn contains(&self, x: &T) -> bool
where T: PartialEq<T>
{
let (a, b) = self.as_slices();
a.contains(x) || b.contains(x)
}
2017-03-31 17:12:47 +02:00
/// Provides a reference to the front element, or `None` if the `VecDeque` is
/// empty.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut d = VecDeque::new();
/// assert_eq!(d.front(), None);
///
2015-01-25 22:05:03 +01:00
/// d.push_back(1);
/// d.push_back(2);
/// assert_eq!(d.front(), Some(&1));
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn front(&self) -> Option<&T> {
2015-11-24 11:23:48 +13:00
if !self.is_empty() {
Some(&self[0])
} else {
None
}
}
/// Provides a mutable reference to the front element, or `None` if the
2017-03-31 17:12:47 +02:00
/// `VecDeque` is empty.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut d = VecDeque::new();
/// assert_eq!(d.front_mut(), None);
///
2015-01-25 22:05:03 +01:00
/// d.push_back(1);
/// d.push_back(2);
/// match d.front_mut() {
2015-01-25 22:05:03 +01:00
/// Some(x) => *x = 9,
/// None => (),
/// }
2015-01-25 22:05:03 +01:00
/// assert_eq!(d.front(), Some(&9));
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn front_mut(&mut self) -> Option<&mut T> {
2015-11-24 11:23:48 +13:00
if !self.is_empty() {
Some(&mut self[0])
} else {
None
}
}
2017-03-31 17:12:47 +02:00
/// Provides a reference to the back element, or `None` if the `VecDeque` is
/// empty.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut d = VecDeque::new();
/// assert_eq!(d.back(), None);
///
2015-01-25 22:05:03 +01:00
/// d.push_back(1);
/// d.push_back(2);
/// assert_eq!(d.back(), Some(&2));
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn back(&self) -> Option<&T> {
2015-11-24 11:23:48 +13:00
if !self.is_empty() {
Some(&self[self.len() - 1])
} else {
None
}
}
/// Provides a mutable reference to the back element, or `None` if the
2017-03-31 17:12:47 +02:00
/// `VecDeque` is empty.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut d = VecDeque::new();
/// assert_eq!(d.back(), None);
///
2015-01-25 22:05:03 +01:00
/// d.push_back(1);
/// d.push_back(2);
/// match d.back_mut() {
2015-01-25 22:05:03 +01:00
/// Some(x) => *x = 9,
/// None => (),
/// }
2015-01-25 22:05:03 +01:00
/// assert_eq!(d.back(), Some(&9));
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn back_mut(&mut self) -> Option<&mut T> {
let len = self.len();
2015-11-24 11:23:48 +13:00
if !self.is_empty() {
Some(&mut self[len - 1])
} else {
None
}
}
2017-03-31 17:12:47 +02:00
/// Removes the first element and returns it, or `None` if the `VecDeque` is
/// empty.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut d = VecDeque::new();
2015-01-25 22:05:03 +01:00
/// d.push_back(1);
/// d.push_back(2);
///
2015-01-25 22:05:03 +01:00
/// assert_eq!(d.pop_front(), Some(1));
/// assert_eq!(d.pop_front(), Some(2));
/// assert_eq!(d.pop_front(), None);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn pop_front(&mut self) -> Option<T> {
if self.is_empty() {
None
} else {
let tail = self.tail;
self.tail = self.wrap_add(self.tail, 1);
unsafe { Some(self.buffer_read(tail)) }
}
}
2017-04-01 02:47:37 +02:00
/// Prepends an element to the `VecDeque`.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut d = VecDeque::new();
2015-01-25 22:05:03 +01:00
/// d.push_front(1);
/// d.push_front(2);
/// assert_eq!(d.front(), Some(&2));
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn push_front(&mut self, value: T) {
self.grow_if_necessary();
self.tail = self.wrap_sub(self.tail, 1);
let tail = self.tail;
2015-11-24 11:23:48 +13:00
unsafe {
self.buffer_write(tail, value);
}
}
2017-03-31 17:12:47 +02:00
/// Appends an element to the back of the `VecDeque`.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
2015-01-25 22:05:03 +01:00
/// buf.push_back(1);
/// buf.push_back(3);
/// assert_eq!(3, *buf.back().unwrap());
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn push_back(&mut self, value: T) {
self.grow_if_necessary();
let head = self.head;
self.head = self.wrap_add(self.head, 1);
unsafe { self.buffer_write(head, value) }
}
2017-03-31 17:12:47 +02:00
/// Removes the last element from the `VecDeque` and returns it, or `None` if
/// it is empty.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
/// assert_eq!(buf.pop_back(), None);
2015-01-25 22:05:03 +01:00
/// buf.push_back(1);
/// buf.push_back(3);
/// assert_eq!(buf.pop_back(), Some(3));
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn pop_back(&mut self) -> Option<T> {
if self.is_empty() {
None
} else {
self.head = self.wrap_sub(self.head, 1);
let head = self.head;
unsafe { Some(self.buffer_read(head)) }
}
}
2014-12-03 11:12:30 -06:00
#[inline]
fn is_contiguous(&self) -> bool {
self.tail <= self.head
}
/// Removes an element from anywhere in the `VecDeque` and returns it, replacing it with the
/// last element.
///
/// This does not preserve ordering, but is O(1).
///
/// Returns `None` if `index` is out of bounds.
///
/// Element at index 0 is the front of the queue.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
std: Stabilize library APIs for 1.5 This commit stabilizes and deprecates library APIs whose FCP has closed in the last cycle, specifically: Stabilized APIs: * `fs::canonicalize` * `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists, is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait. * `Formatter::fill` * `Formatter::width` * `Formatter::precision` * `Formatter::sign_plus` * `Formatter::sign_minus` * `Formatter::alternate` * `Formatter::sign_aware_zero_pad` * `string::ParseError` * `Utf8Error::valid_up_to` * `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}` * `<[T]>::split_{first,last}{,_mut}` * `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated but will be once 1.5 is released. * `str::{R,}MatchIndices` * `str::{r,}match_indices` * `char::from_u32_unchecked` * `VecDeque::insert` * `VecDeque::shrink_to_fit` * `VecDeque::as_slices` * `VecDeque::as_mut_slices` * `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`) * `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`) * `Vec::resize` * `str::slice_mut_unchecked` * `FileTypeExt` * `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}` * `BinaryHeap::from` - `from_vec` deprecated in favor of this * `BinaryHeap::into_vec` - plus a `Into` impl * `BinaryHeap::into_sorted_vec` Deprecated APIs * `slice::ref_slice` * `slice::mut_ref_slice` * `iter::{range_inclusive, RangeInclusive}` * `std::dynamic_lib` Closes #27706 Closes #27725 cc #27726 (align not stabilized yet) Closes #27734 Closes #27737 Closes #27742 Closes #27743 Closes #27772 Closes #27774 Closes #27777 Closes #27781 cc #27788 (a few remaining methods though) Closes #27790 Closes #27793 Closes #27796 Closes #27810 cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
/// assert_eq!(buf.swap_remove_back(0), None);
2015-07-17 23:49:13 +02:00
/// buf.push_back(1);
/// buf.push_back(2);
/// buf.push_back(3);
/// assert_eq!(buf, [1, 2, 3]);
2015-07-17 23:49:13 +02:00
///
std: Stabilize library APIs for 1.5 This commit stabilizes and deprecates library APIs whose FCP has closed in the last cycle, specifically: Stabilized APIs: * `fs::canonicalize` * `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists, is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait. * `Formatter::fill` * `Formatter::width` * `Formatter::precision` * `Formatter::sign_plus` * `Formatter::sign_minus` * `Formatter::alternate` * `Formatter::sign_aware_zero_pad` * `string::ParseError` * `Utf8Error::valid_up_to` * `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}` * `<[T]>::split_{first,last}{,_mut}` * `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated but will be once 1.5 is released. * `str::{R,}MatchIndices` * `str::{r,}match_indices` * `char::from_u32_unchecked` * `VecDeque::insert` * `VecDeque::shrink_to_fit` * `VecDeque::as_slices` * `VecDeque::as_mut_slices` * `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`) * `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`) * `Vec::resize` * `str::slice_mut_unchecked` * `FileTypeExt` * `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}` * `BinaryHeap::from` - `from_vec` deprecated in favor of this * `BinaryHeap::into_vec` - plus a `Into` impl * `BinaryHeap::into_sorted_vec` Deprecated APIs * `slice::ref_slice` * `slice::mut_ref_slice` * `iter::{range_inclusive, RangeInclusive}` * `std::dynamic_lib` Closes #27706 Closes #27725 cc #27726 (align not stabilized yet) Closes #27734 Closes #27737 Closes #27742 Closes #27743 Closes #27772 Closes #27774 Closes #27777 Closes #27781 cc #27788 (a few remaining methods though) Closes #27790 Closes #27793 Closes #27796 Closes #27810 cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
/// assert_eq!(buf.swap_remove_back(0), Some(1));
/// assert_eq!(buf, [3, 2]);
/// ```
std: Stabilize library APIs for 1.5 This commit stabilizes and deprecates library APIs whose FCP has closed in the last cycle, specifically: Stabilized APIs: * `fs::canonicalize` * `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists, is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait. * `Formatter::fill` * `Formatter::width` * `Formatter::precision` * `Formatter::sign_plus` * `Formatter::sign_minus` * `Formatter::alternate` * `Formatter::sign_aware_zero_pad` * `string::ParseError` * `Utf8Error::valid_up_to` * `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}` * `<[T]>::split_{first,last}{,_mut}` * `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated but will be once 1.5 is released. * `str::{R,}MatchIndices` * `str::{r,}match_indices` * `char::from_u32_unchecked` * `VecDeque::insert` * `VecDeque::shrink_to_fit` * `VecDeque::as_slices` * `VecDeque::as_mut_slices` * `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`) * `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`) * `Vec::resize` * `str::slice_mut_unchecked` * `FileTypeExt` * `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}` * `BinaryHeap::from` - `from_vec` deprecated in favor of this * `BinaryHeap::into_vec` - plus a `Into` impl * `BinaryHeap::into_sorted_vec` Deprecated APIs * `slice::ref_slice` * `slice::mut_ref_slice` * `iter::{range_inclusive, RangeInclusive}` * `std::dynamic_lib` Closes #27706 Closes #27725 cc #27726 (align not stabilized yet) Closes #27734 Closes #27737 Closes #27742 Closes #27743 Closes #27772 Closes #27774 Closes #27777 Closes #27781 cc #27788 (a few remaining methods though) Closes #27790 Closes #27793 Closes #27796 Closes #27810 cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
#[stable(feature = "deque_extras_15", since = "1.5.0")]
pub fn swap_remove_back(&mut self, index: usize) -> Option<T> {
let length = self.len();
if length > 0 && index < length - 1 {
self.swap(index, length - 1);
} else if index >= length {
return None;
}
self.pop_back()
}
/// Removes an element from anywhere in the `VecDeque` and returns it,
/// replacing it with the first element.
///
/// This does not preserve ordering, but is O(1).
///
/// Returns `None` if `index` is out of bounds.
///
/// Element at index 0 is the front of the queue.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
std: Stabilize library APIs for 1.5 This commit stabilizes and deprecates library APIs whose FCP has closed in the last cycle, specifically: Stabilized APIs: * `fs::canonicalize` * `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists, is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait. * `Formatter::fill` * `Formatter::width` * `Formatter::precision` * `Formatter::sign_plus` * `Formatter::sign_minus` * `Formatter::alternate` * `Formatter::sign_aware_zero_pad` * `string::ParseError` * `Utf8Error::valid_up_to` * `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}` * `<[T]>::split_{first,last}{,_mut}` * `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated but will be once 1.5 is released. * `str::{R,}MatchIndices` * `str::{r,}match_indices` * `char::from_u32_unchecked` * `VecDeque::insert` * `VecDeque::shrink_to_fit` * `VecDeque::as_slices` * `VecDeque::as_mut_slices` * `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`) * `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`) * `Vec::resize` * `str::slice_mut_unchecked` * `FileTypeExt` * `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}` * `BinaryHeap::from` - `from_vec` deprecated in favor of this * `BinaryHeap::into_vec` - plus a `Into` impl * `BinaryHeap::into_sorted_vec` Deprecated APIs * `slice::ref_slice` * `slice::mut_ref_slice` * `iter::{range_inclusive, RangeInclusive}` * `std::dynamic_lib` Closes #27706 Closes #27725 cc #27726 (align not stabilized yet) Closes #27734 Closes #27737 Closes #27742 Closes #27743 Closes #27772 Closes #27774 Closes #27777 Closes #27781 cc #27788 (a few remaining methods though) Closes #27790 Closes #27793 Closes #27796 Closes #27810 cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
/// assert_eq!(buf.swap_remove_front(0), None);
2015-07-17 23:49:13 +02:00
/// buf.push_back(1);
/// buf.push_back(2);
/// buf.push_back(3);
/// assert_eq!(buf, [1, 2, 3]);
2015-07-17 23:49:13 +02:00
///
std: Stabilize library APIs for 1.5 This commit stabilizes and deprecates library APIs whose FCP has closed in the last cycle, specifically: Stabilized APIs: * `fs::canonicalize` * `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists, is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait. * `Formatter::fill` * `Formatter::width` * `Formatter::precision` * `Formatter::sign_plus` * `Formatter::sign_minus` * `Formatter::alternate` * `Formatter::sign_aware_zero_pad` * `string::ParseError` * `Utf8Error::valid_up_to` * `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}` * `<[T]>::split_{first,last}{,_mut}` * `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated but will be once 1.5 is released. * `str::{R,}MatchIndices` * `str::{r,}match_indices` * `char::from_u32_unchecked` * `VecDeque::insert` * `VecDeque::shrink_to_fit` * `VecDeque::as_slices` * `VecDeque::as_mut_slices` * `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`) * `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`) * `Vec::resize` * `str::slice_mut_unchecked` * `FileTypeExt` * `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}` * `BinaryHeap::from` - `from_vec` deprecated in favor of this * `BinaryHeap::into_vec` - plus a `Into` impl * `BinaryHeap::into_sorted_vec` Deprecated APIs * `slice::ref_slice` * `slice::mut_ref_slice` * `iter::{range_inclusive, RangeInclusive}` * `std::dynamic_lib` Closes #27706 Closes #27725 cc #27726 (align not stabilized yet) Closes #27734 Closes #27737 Closes #27742 Closes #27743 Closes #27772 Closes #27774 Closes #27777 Closes #27781 cc #27788 (a few remaining methods though) Closes #27790 Closes #27793 Closes #27796 Closes #27810 cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
/// assert_eq!(buf.swap_remove_front(2), Some(3));
/// assert_eq!(buf, [2, 1]);
/// ```
std: Stabilize library APIs for 1.5 This commit stabilizes and deprecates library APIs whose FCP has closed in the last cycle, specifically: Stabilized APIs: * `fs::canonicalize` * `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists, is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait. * `Formatter::fill` * `Formatter::width` * `Formatter::precision` * `Formatter::sign_plus` * `Formatter::sign_minus` * `Formatter::alternate` * `Formatter::sign_aware_zero_pad` * `string::ParseError` * `Utf8Error::valid_up_to` * `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}` * `<[T]>::split_{first,last}{,_mut}` * `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated but will be once 1.5 is released. * `str::{R,}MatchIndices` * `str::{r,}match_indices` * `char::from_u32_unchecked` * `VecDeque::insert` * `VecDeque::shrink_to_fit` * `VecDeque::as_slices` * `VecDeque::as_mut_slices` * `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`) * `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`) * `Vec::resize` * `str::slice_mut_unchecked` * `FileTypeExt` * `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}` * `BinaryHeap::from` - `from_vec` deprecated in favor of this * `BinaryHeap::into_vec` - plus a `Into` impl * `BinaryHeap::into_sorted_vec` Deprecated APIs * `slice::ref_slice` * `slice::mut_ref_slice` * `iter::{range_inclusive, RangeInclusive}` * `std::dynamic_lib` Closes #27706 Closes #27725 cc #27726 (align not stabilized yet) Closes #27734 Closes #27737 Closes #27742 Closes #27743 Closes #27772 Closes #27774 Closes #27777 Closes #27781 cc #27788 (a few remaining methods though) Closes #27790 Closes #27793 Closes #27796 Closes #27810 cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
#[stable(feature = "deque_extras_15", since = "1.5.0")]
pub fn swap_remove_front(&mut self, index: usize) -> Option<T> {
let length = self.len();
if length > 0 && index < length && index != 0 {
self.swap(index, 0);
} else if index >= length {
return None;
}
self.pop_front()
}
/// Inserts an element at `index` within the `VecDeque`, shifting all elements with indices
/// greater than or equal to `index` towards the back.
2014-12-03 11:12:30 -06:00
///
/// Element at index 0 is the front of the queue.
///
2014-12-03 11:12:30 -06:00
/// # Panics
///
/// Panics if `index` is greater than `VecDeque`'s length
2014-12-03 11:12:30 -06:00
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
2014-12-03 11:12:30 -06:00
///
/// let mut vec_deque = VecDeque::new();
/// vec_deque.push_back('a');
/// vec_deque.push_back('b');
/// vec_deque.push_back('c');
/// assert_eq!(vec_deque, &['a', 'b', 'c']);
///
/// vec_deque.insert(1, 'd');
/// assert_eq!(vec_deque, &['a', 'd', 'b', 'c']);
2014-12-03 11:12:30 -06:00
/// ```
std: Stabilize library APIs for 1.5 This commit stabilizes and deprecates library APIs whose FCP has closed in the last cycle, specifically: Stabilized APIs: * `fs::canonicalize` * `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists, is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait. * `Formatter::fill` * `Formatter::width` * `Formatter::precision` * `Formatter::sign_plus` * `Formatter::sign_minus` * `Formatter::alternate` * `Formatter::sign_aware_zero_pad` * `string::ParseError` * `Utf8Error::valid_up_to` * `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}` * `<[T]>::split_{first,last}{,_mut}` * `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated but will be once 1.5 is released. * `str::{R,}MatchIndices` * `str::{r,}match_indices` * `char::from_u32_unchecked` * `VecDeque::insert` * `VecDeque::shrink_to_fit` * `VecDeque::as_slices` * `VecDeque::as_mut_slices` * `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`) * `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`) * `Vec::resize` * `str::slice_mut_unchecked` * `FileTypeExt` * `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}` * `BinaryHeap::from` - `from_vec` deprecated in favor of this * `BinaryHeap::into_vec` - plus a `Into` impl * `BinaryHeap::into_sorted_vec` Deprecated APIs * `slice::ref_slice` * `slice::mut_ref_slice` * `iter::{range_inclusive, RangeInclusive}` * `std::dynamic_lib` Closes #27706 Closes #27725 cc #27726 (align not stabilized yet) Closes #27734 Closes #27737 Closes #27742 Closes #27743 Closes #27772 Closes #27774 Closes #27777 Closes #27781 cc #27788 (a few remaining methods though) Closes #27790 Closes #27793 Closes #27796 Closes #27810 cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
#[stable(feature = "deque_extras_15", since = "1.5.0")]
pub fn insert(&mut self, index: usize, value: T) {
assert!(index <= self.len(), "index out of bounds");
self.grow_if_necessary();
2014-12-03 11:12:30 -06:00
// Move the least number of elements in the ring buffer and insert
// the given object
//
// At most len/2 - 1 elements will be moved. O(min(n, n-i))
//
// There are three main cases:
// Elements are contiguous
// - special case when tail is 0
// Elements are discontiguous and the insert is in the tail section
// Elements are discontiguous and the insert is in the head section
//
// For each of those there are two more cases:
// Insert is closer to tail
// Insert is closer to head
//
// Key: H - self.head
// T - self.tail
// o - Valid element
// I - Insertion element
// A - The element that should be after the insertion point
// M - Indicates element was moved
let idx = self.wrap_add(self.tail, index);
2014-12-03 11:12:30 -06:00
let distance_to_tail = index;
let distance_to_head = self.len() - index;
2014-12-03 11:12:30 -06:00
let contiguous = self.is_contiguous();
2014-12-03 11:12:30 -06:00
2016-12-20 09:54:00 +05:30
match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
(true, true, _) if index == 0 => {
2014-12-03 11:12:30 -06:00
// push_front
//
// T
// I H
// [A o o o o o o . . . . . . . . .]
//
// H T
// [A o o o o o o o . . . . . I]
//
self.tail = self.wrap_sub(self.tail, 1);
2015-11-24 11:23:48 +13:00
}
(true, true, _) => {
unsafe {
// contiguous, insert closer to tail:
//
// T I H
// [. . . o o A o o o o . . . . . .]
//
// T H
// [. . o o I A o o o o . . . . . .]
// M M
//
// contiguous, insert closer to tail and tail is 0:
//
//
// T I H
// [o o A o o o o . . . . . . . . .]
//
// H T
// [o I A o o o o o . . . . . . . o]
// M M
let new_tail = self.wrap_sub(self.tail, 1);
self.copy(new_tail, self.tail, 1);
// Already moved the tail, so we only copy `index - 1` elements.
self.copy(self.tail, self.tail + 1, index - 1);
self.tail = new_tail;
}
}
(true, false, _) => {
unsafe {
// contiguous, insert closer to head:
//
// T I H
// [. . . o o o o A o o . . . . . .]
//
// T H
// [. . . o o o o I A o o . . . . .]
// M M M
self.copy(idx + 1, idx, self.head - idx);
self.head = self.wrap_add(self.head, 1);
}
}
(false, true, true) => {
unsafe {
// discontiguous, insert closer to tail, tail section:
//
// H T I
// [o o o o o o . . . . . o o A o o]
//
// H T
// [o o o o o o . . . . o o I A o o]
// M M
self.copy(self.tail - 1, self.tail, index);
self.tail -= 1;
}
}
(false, false, true) => {
unsafe {
// discontiguous, insert closer to head, tail section:
//
// H T I
// [o o . . . . . . . o o o o o A o]
//
// H T
// [o o o . . . . . . o o o o o I A]
// M M M M
2014-12-17 00:37:55 +01:00
2015-11-24 11:23:48 +13:00
// copy elements up to new head
self.copy(1, 0, self.head);
2014-12-03 11:12:30 -06:00
2015-11-24 11:23:48 +13:00
// copy last element into empty spot at bottom of buffer
self.copy(0, self.cap() - 1, 1);
2014-12-03 11:12:30 -06:00
2015-11-24 11:23:48 +13:00
// move elements from idx to end forward not including ^ element
self.copy(idx + 1, idx, self.cap() - 1 - idx);
2014-12-17 00:37:55 +01:00
2015-11-24 11:23:48 +13:00
self.head += 1;
}
}
(false, true, false) if idx == 0 => {
unsafe {
// discontiguous, insert is closer to tail, head section,
// and is at index zero in the internal buffer:
//
// I H T
// [A o o o o o o o o o . . . o o o]
//
// H T
// [A o o o o o o o o o . . o o o I]
// M M M
// copy elements up to new tail
self.copy(self.tail - 1, self.tail, self.cap() - self.tail);
// copy last element into empty spot at bottom of buffer
self.copy(self.cap() - 1, 0, 1);
2014-12-03 11:12:30 -06:00
2015-11-24 11:23:48 +13:00
self.tail -= 1;
}
}
(false, true, false) => {
unsafe {
// discontiguous, insert closer to tail, head section:
//
// I H T
// [o o o A o o o o o o . . . o o o]
//
// H T
// [o o I A o o o o o o . . o o o o]
// M M M M M M
// copy elements up to new tail
self.copy(self.tail - 1, self.tail, self.cap() - self.tail);
// copy last element into empty spot at bottom of buffer
self.copy(self.cap() - 1, 0, 1);
2014-12-17 00:37:55 +01:00
2015-11-24 11:23:48 +13:00
// move elements from idx-1 to end forward not including ^ element
self.copy(0, 1, idx - 1);
2014-12-03 11:12:30 -06:00
2015-11-24 11:23:48 +13:00
self.tail -= 1;
}
}
(false, false, false) => {
unsafe {
// discontiguous, insert closer to head, head section:
//
// I H T
// [o o o o A o o . . . . . . o o o]
//
// H T
// [o o o o I A o o . . . . . o o o]
// M M M
self.copy(idx + 1, idx, self.head - idx);
self.head += 1;
}
2014-12-03 11:12:30 -06:00
}
}
// tail might've been changed so we need to recalculate
let new_idx = self.wrap_add(self.tail, index);
2014-12-03 11:12:30 -06:00
unsafe {
self.buffer_write(new_idx, value);
2014-12-03 11:12:30 -06:00
}
}
2014-12-17 00:37:55 +01:00
/// Removes and returns the element at `index` from the `VecDeque`.
2014-12-17 00:37:55 +01:00
/// Whichever end is closer to the removal point will be moved to make
/// room, and all the affected elements will be moved to new positions.
/// Returns `None` if `index` is out of bounds.
2014-12-17 00:37:55 +01:00
///
/// Element at index 0 is the front of the queue.
///
/// # Examples
2016-07-16 18:00:05 +02:00
///
/// ```
/// use std::collections::VecDeque;
2014-12-17 00:37:55 +01:00
///
/// let mut buf = VecDeque::new();
2015-07-17 23:49:13 +02:00
/// buf.push_back(1);
/// buf.push_back(2);
/// buf.push_back(3);
/// assert_eq!(buf, [1, 2, 3]);
2015-07-17 23:49:13 +02:00
///
/// assert_eq!(buf.remove(1), Some(2));
/// assert_eq!(buf, [1, 3]);
2014-12-17 00:37:55 +01:00
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove(&mut self, index: usize) -> Option<T> {
if self.is_empty() || self.len() <= index {
2014-12-17 00:37:55 +01:00
return None;
}
// There are three main cases:
// Elements are contiguous
// Elements are discontiguous and the removal is in the tail section
// Elements are discontiguous and the removal is in the head section
// - special case when elements are technically contiguous,
// but self.head = 0
//
// For each of those there are two more cases:
// Insert is closer to tail
// Insert is closer to head
//
// Key: H - self.head
// T - self.tail
// o - Valid element
// x - Element marked for removal
// R - Indicates element that is being removed
// M - Indicates element was moved
let idx = self.wrap_add(self.tail, index);
2014-12-17 00:37:55 +01:00
2015-11-24 11:23:48 +13:00
let elem = unsafe { Some(self.buffer_read(idx)) };
2014-12-17 00:37:55 +01:00
let distance_to_tail = index;
let distance_to_head = self.len() - index;
2014-12-17 00:37:55 +01:00
let contiguous = self.is_contiguous();
2014-12-17 00:37:55 +01:00
2016-12-20 09:54:00 +05:30
match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
2015-11-24 11:23:48 +13:00
(true, true, _) => {
unsafe {
// contiguous, remove closer to tail:
//
// T R H
// [. . . o o x o o o o . . . . . .]
//
// T H
// [. . . . o o o o o o . . . . . .]
// M M
self.copy(self.tail + 1, self.tail, index);
self.tail += 1;
}
}
(true, false, _) => {
unsafe {
// contiguous, remove closer to head:
//
// T R H
// [. . . o o o o x o o . . . . . .]
//
// T H
// [. . . o o o o o o . . . . . . .]
// M M
self.copy(idx, idx + 1, self.head - idx - 1);
self.head -= 1;
}
}
(false, true, true) => {
unsafe {
// discontiguous, remove closer to tail, tail section:
//
// H T R
// [o o o o o o . . . . . o o x o o]
//
// H T
// [o o o o o o . . . . . . o o o o]
// M M
self.copy(self.tail + 1, self.tail, index);
self.tail = self.wrap_add(self.tail, 1);
}
}
(false, false, false) => {
unsafe {
// discontiguous, remove closer to head, head section:
//
// R H T
// [o o o o x o o . . . . . . o o o]
//
// H T
// [o o o o o o . . . . . . . o o o]
// M M
self.copy(idx, idx + 1, self.head - idx - 1);
self.head -= 1;
2014-12-17 00:37:55 +01:00
}
2015-11-24 11:23:48 +13:00
}
(false, false, true) => {
unsafe {
// discontiguous, remove closer to head, tail section:
//
// H T R
// [o o o . . . . . . o o o o o x o]
//
// H T
// [o o . . . . . . . o o o o o o o]
// M M M M
//
// or quasi-discontiguous, remove next to head, tail section:
//
// H T R
// [. . . . . . . . . o o o o o x o]
//
// T H
// [. . . . . . . . . o o o o o o .]
// M
// draw in elements in the tail section
self.copy(idx, idx + 1, self.cap() - idx - 1);
// Prevents underflow.
if self.head != 0 {
// copy first element into empty spot
self.copy(self.cap() - 1, 0, 1);
// move elements in the head section backwards
self.copy(0, 1, self.head - 1);
}
2014-12-17 00:37:55 +01:00
2015-11-24 11:23:48 +13:00
self.head = self.wrap_sub(self.head, 1);
}
}
(false, true, false) => {
unsafe {
// discontiguous, remove closer to tail, head section:
//
// R H T
// [o o x o o o o o o o . . . o o o]
//
// H T
// [o o o o o o o o o o . . . . o o]
// M M M M M
2014-12-17 00:37:55 +01:00
2015-11-24 11:23:48 +13:00
// draw in elements up to idx
self.copy(1, 0, idx);
2014-12-17 00:37:55 +01:00
2015-11-24 11:23:48 +13:00
// copy last element into empty spot
self.copy(0, self.cap() - 1, 1);
2014-12-17 00:37:55 +01:00
2015-11-24 11:23:48 +13:00
// move elements from tail to end forward, excluding the last one
self.copy(self.tail + 1, self.tail, self.cap() - self.tail - 1);
2014-12-17 00:37:55 +01:00
2015-11-24 11:23:48 +13:00
self.tail = self.wrap_add(self.tail, 1);
}
2014-12-17 00:37:55 +01:00
}
}
return elem;
}
2015-02-07 11:46:16 -05:00
/// Splits the collection into two at the given index.
///
/// Returns a newly allocated `Self`. `self` contains elements `[0, at)`,
/// and the returned `Self` contains elements `[at, len)`.
///
/// Note that the capacity of `self` does not change.
///
/// Element at index 0 is the front of the queue.
///
2015-02-07 11:46:16 -05:00
/// # Panics
///
/// Panics if `at > len`
///
/// # Examples
2015-02-07 12:13:32 -05:00
///
/// ```
/// use std::collections::VecDeque;
2015-02-07 12:13:32 -05:00
///
/// let mut buf: VecDeque<_> = vec![1,2,3].into_iter().collect();
2015-02-07 11:46:16 -05:00
/// let buf2 = buf.split_off(1);
/// assert_eq!(buf, [1]);
/// assert_eq!(buf2, [2, 3]);
2015-02-07 11:46:16 -05:00
/// ```
#[inline]
std: Stabilize/deprecate features for 1.4 The FCP is coming to a close and 1.4 is coming out soon, so this brings in the libs team decision for all library features this cycle. Stabilized APIs: * `<Box<str>>::into_string` * `Arc::downgrade` * `Arc::get_mut` * `Arc::make_mut` * `Arc::try_unwrap` * `Box::from_raw` * `Box::into_raw` * `CStr::to_str` * `CStr::to_string_lossy` * `CString::from_raw` * `CString::into_raw` * `IntoRawFd::into_raw_fd` * `IntoRawFd` * `IntoRawHandle::into_raw_handle` * `IntoRawHandle` * `IntoRawSocket::into_raw_socket` * `IntoRawSocket` * `Rc::downgrade` * `Rc::get_mut` * `Rc::make_mut` * `Rc::try_unwrap` * `Result::expect` * `String::into_boxed_slice` * `TcpSocket::read_timeout` * `TcpSocket::set_read_timeout` * `TcpSocket::set_write_timeout` * `TcpSocket::write_timeout` * `UdpSocket::read_timeout` * `UdpSocket::set_read_timeout` * `UdpSocket::set_write_timeout` * `UdpSocket::write_timeout` * `Vec::append` * `Vec::split_off` * `VecDeque::append` * `VecDeque::retain` * `VecDeque::split_off` * `rc::Weak::upgrade` * `rc::Weak` * `slice::Iter::as_slice` * `slice::IterMut::into_slice` * `str::CharIndices::as_str` * `str::Chars::as_str` * `str::split_at_mut` * `str::split_at` * `sync::Weak::upgrade` * `sync::Weak` * `thread::park_timeout` * `thread::sleep` Deprecated APIs * `BTreeMap::with_b` * `BTreeSet::with_b` * `Option::as_mut_slice` * `Option::as_slice` * `Result::as_mut_slice` * `Result::as_slice` * `f32::from_str_radix` * `f64::from_str_radix` Closes #27277 Closes #27718 Closes #27736 Closes #27764 Closes #27765 Closes #27766 Closes #27767 Closes #27768 Closes #27769 Closes #27771 Closes #27773 Closes #27775 Closes #27776 Closes #27785 Closes #27792 Closes #27795 Closes #27797
2015-09-10 13:26:44 -07:00
#[stable(feature = "split_off", since = "1.4.0")]
2015-02-07 11:46:16 -05:00
pub fn split_off(&mut self, at: usize) -> Self {
let len = self.len();
assert!(at <= len, "`at` out of bounds");
let other_len = len - at;
let mut other = VecDeque::with_capacity(other_len);
2015-02-07 11:46:16 -05:00
unsafe {
let (first_half, second_half) = self.as_slices();
let first_len = first_half.len();
let second_len = second_half.len();
if at < first_len {
// `at` lies in the first half.
let amount_in_first = first_len - at;
ptr::copy_nonoverlapping(first_half.as_ptr().offset(at as isize),
2015-07-09 21:57:21 -07:00
other.ptr(),
amount_in_first);
2015-02-07 11:46:16 -05:00
// just take all of the second half.
ptr::copy_nonoverlapping(second_half.as_ptr(),
2015-07-09 21:57:21 -07:00
other.ptr().offset(amount_in_first as isize),
second_len);
2015-02-07 11:46:16 -05:00
} else {
// `at` lies in the second half, need to factor in the elements we skipped
// in the first half.
let offset = at - first_len;
let amount_in_second = second_len - offset;
ptr::copy_nonoverlapping(second_half.as_ptr().offset(offset as isize),
2015-07-09 21:57:21 -07:00
other.ptr(),
amount_in_second);
2015-02-07 11:46:16 -05:00
}
}
// Cleanup where the ends of the buffers are
self.head = self.wrap_sub(self.head, other_len);
2015-02-07 11:46:16 -05:00
other.head = other.wrap_index(other_len);
other
}
2015-02-07 12:13:32 -05:00
/// Moves all the elements of `other` into `Self`, leaving `other` empty.
///
/// # Panics
///
/// Panics if the new number of elements in self overflows a `usize`.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
2015-02-07 12:13:32 -05:00
///
/// let mut buf: VecDeque<_> = vec![1, 2].into_iter().collect();
/// let mut buf2: VecDeque<_> = vec![3, 4].into_iter().collect();
2015-02-07 12:13:32 -05:00
/// buf.append(&mut buf2);
/// assert_eq!(buf, [1, 2, 3, 4]);
/// assert_eq!(buf2, []);
2015-02-07 12:13:32 -05:00
/// ```
#[inline]
std: Stabilize/deprecate features for 1.4 The FCP is coming to a close and 1.4 is coming out soon, so this brings in the libs team decision for all library features this cycle. Stabilized APIs: * `<Box<str>>::into_string` * `Arc::downgrade` * `Arc::get_mut` * `Arc::make_mut` * `Arc::try_unwrap` * `Box::from_raw` * `Box::into_raw` * `CStr::to_str` * `CStr::to_string_lossy` * `CString::from_raw` * `CString::into_raw` * `IntoRawFd::into_raw_fd` * `IntoRawFd` * `IntoRawHandle::into_raw_handle` * `IntoRawHandle` * `IntoRawSocket::into_raw_socket` * `IntoRawSocket` * `Rc::downgrade` * `Rc::get_mut` * `Rc::make_mut` * `Rc::try_unwrap` * `Result::expect` * `String::into_boxed_slice` * `TcpSocket::read_timeout` * `TcpSocket::set_read_timeout` * `TcpSocket::set_write_timeout` * `TcpSocket::write_timeout` * `UdpSocket::read_timeout` * `UdpSocket::set_read_timeout` * `UdpSocket::set_write_timeout` * `UdpSocket::write_timeout` * `Vec::append` * `Vec::split_off` * `VecDeque::append` * `VecDeque::retain` * `VecDeque::split_off` * `rc::Weak::upgrade` * `rc::Weak` * `slice::Iter::as_slice` * `slice::IterMut::into_slice` * `str::CharIndices::as_str` * `str::Chars::as_str` * `str::split_at_mut` * `str::split_at` * `sync::Weak::upgrade` * `sync::Weak` * `thread::park_timeout` * `thread::sleep` Deprecated APIs * `BTreeMap::with_b` * `BTreeSet::with_b` * `Option::as_mut_slice` * `Option::as_slice` * `Result::as_mut_slice` * `Result::as_slice` * `f32::from_str_radix` * `f64::from_str_radix` Closes #27277 Closes #27718 Closes #27736 Closes #27764 Closes #27765 Closes #27766 Closes #27767 Closes #27768 Closes #27769 Closes #27771 Closes #27773 Closes #27775 Closes #27776 Closes #27785 Closes #27792 Closes #27795 Closes #27797
2015-09-10 13:26:44 -07:00
#[stable(feature = "append", since = "1.4.0")]
2015-02-07 12:13:32 -05:00
pub fn append(&mut self, other: &mut Self) {
// naive impl
self.extend(other.drain(..));
2015-02-07 12:13:32 -05:00
}
2015-04-27 13:47:19 -04:00
/// Retains only the elements specified by the predicate.
///
/// In other words, remove all elements `e` such that `f(&e)` returns false.
/// This method operates in place and preserves the order of the retained
/// elements.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
/// buf.extend(1..5);
/// buf.retain(|&x| x%2 == 0);
/// assert_eq!(buf, [2, 4]);
2015-04-27 13:47:19 -04:00
/// ```
std: Stabilize/deprecate features for 1.4 The FCP is coming to a close and 1.4 is coming out soon, so this brings in the libs team decision for all library features this cycle. Stabilized APIs: * `<Box<str>>::into_string` * `Arc::downgrade` * `Arc::get_mut` * `Arc::make_mut` * `Arc::try_unwrap` * `Box::from_raw` * `Box::into_raw` * `CStr::to_str` * `CStr::to_string_lossy` * `CString::from_raw` * `CString::into_raw` * `IntoRawFd::into_raw_fd` * `IntoRawFd` * `IntoRawHandle::into_raw_handle` * `IntoRawHandle` * `IntoRawSocket::into_raw_socket` * `IntoRawSocket` * `Rc::downgrade` * `Rc::get_mut` * `Rc::make_mut` * `Rc::try_unwrap` * `Result::expect` * `String::into_boxed_slice` * `TcpSocket::read_timeout` * `TcpSocket::set_read_timeout` * `TcpSocket::set_write_timeout` * `TcpSocket::write_timeout` * `UdpSocket::read_timeout` * `UdpSocket::set_read_timeout` * `UdpSocket::set_write_timeout` * `UdpSocket::write_timeout` * `Vec::append` * `Vec::split_off` * `VecDeque::append` * `VecDeque::retain` * `VecDeque::split_off` * `rc::Weak::upgrade` * `rc::Weak` * `slice::Iter::as_slice` * `slice::IterMut::into_slice` * `str::CharIndices::as_str` * `str::Chars::as_str` * `str::split_at_mut` * `str::split_at` * `sync::Weak::upgrade` * `sync::Weak` * `thread::park_timeout` * `thread::sleep` Deprecated APIs * `BTreeMap::with_b` * `BTreeSet::with_b` * `Option::as_mut_slice` * `Option::as_slice` * `Result::as_mut_slice` * `Result::as_slice` * `f32::from_str_radix` * `f64::from_str_radix` Closes #27277 Closes #27718 Closes #27736 Closes #27764 Closes #27765 Closes #27766 Closes #27767 Closes #27768 Closes #27769 Closes #27771 Closes #27773 Closes #27775 Closes #27776 Closes #27785 Closes #27792 Closes #27795 Closes #27797
2015-09-10 13:26:44 -07:00
#[stable(feature = "vec_deque_retain", since = "1.4.0")]
2015-11-24 11:23:48 +13:00
pub fn retain<F>(&mut self, mut f: F)
where F: FnMut(&T) -> bool
{
2015-04-27 13:47:19 -04:00
let len = self.len();
let mut del = 0;
for i in 0..len {
if !f(&self[i]) {
del += 1;
} else if del > 0 {
2015-11-24 11:23:48 +13:00
self.swap(i - del, i);
2015-04-27 13:47:19 -04:00
}
}
if del > 0 {
self.truncate(len - del);
}
}
// This may panic or abort
#[inline]
fn grow_if_necessary(&mut self) {
if self.is_full() {
let old_cap = self.cap();
self.buf.double();
unsafe {
self.handle_cap_increase(old_cap);
}
debug_assert!(!self.is_full());
}
}
/// Returns a place for insertion at the back of the `VecDeque`.
///
/// Using this method with placement syntax is equivalent to [`push_back`](#method.push_back),
/// but may be more efficient.
///
/// # Examples
///
/// ```
/// #![feature(collection_placement)]
/// #![feature(placement_in_syntax)]
///
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
/// buf.place_back() <- 3;
/// buf.place_back() <- 4;
/// assert_eq!(&buf, &[3, 4]);
/// ```
#[unstable(feature = "collection_placement",
reason = "placement protocol is subject to change",
issue = "30172")]
pub fn place_back(&mut self) -> PlaceBack<T> {
PlaceBack { vec_deque: self }
}
/// Returns a place for insertion at the front of the `VecDeque`.
///
/// Using this method with placement syntax is equivalent to [`push_front`](#method.push_front),
/// but may be more efficient.
///
/// # Examples
///
/// ```
/// #![feature(collection_placement)]
/// #![feature(placement_in_syntax)]
///
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
/// buf.place_front() <- 3;
/// buf.place_front() <- 4;
/// assert_eq!(&buf, &[4, 3]);
/// ```
#[unstable(feature = "collection_placement",
reason = "placement protocol is subject to change",
issue = "30172")]
pub fn place_front(&mut self) -> PlaceFront<T> {
PlaceFront { vec_deque: self }
}
2013-06-25 15:08:47 -04:00
}
impl<T: Clone> VecDeque<T> {
/// Modifies the `VecDeque` in-place so that `len()` is equal to new_len,
2017-03-10 12:11:13 -06:00
/// either by removing excess elements or by appending clones of `value` to the back.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
2015-01-25 22:05:03 +01:00
/// buf.push_back(5);
/// buf.push_back(10);
/// buf.push_back(15);
/// assert_eq!(buf, [5, 10, 15]);
///
/// buf.resize(2, 0);
/// assert_eq!(buf, [5, 10]);
///
/// buf.resize(5, 20);
/// assert_eq!(buf, [5, 10, 20, 20, 20]);
/// ```
#[stable(feature = "deque_extras", since = "1.16.0")]
2015-02-04 21:17:19 -05:00
pub fn resize(&mut self, new_len: usize, value: T) {
let len = self.len();
if new_len > len {
self.extend(repeat(value).take(new_len - len))
} else {
self.truncate(new_len);
}
}
}
/// Returns the index in the underlying buffer for a given logical element index.
#[inline]
2015-02-04 21:17:19 -05:00
fn wrap_index(index: usize, size: usize) -> usize {
// size is always a power of 2
debug_assert!(size.is_power_of_two());
index & (size - 1)
}
/// Returns the two slices that cover the `VecDeque`'s valid range
2016-12-20 09:54:00 +05:30
trait RingSlices: Sized {
fn slice(self, from: usize, to: usize) -> Self;
fn split_at(self, i: usize) -> (Self, Self);
fn ring_slices(buf: Self, head: usize, tail: usize) -> (Self, Self) {
let contiguous = tail <= head;
if contiguous {
let (empty, buf) = buf.split_at(0);
(buf.slice(tail, head), empty)
} else {
let (mid, right) = buf.split_at(tail);
let (left, _) = mid.split_at(head);
(right, left)
}
}
}
impl<'a, T> RingSlices for &'a [T] {
fn slice(self, from: usize, to: usize) -> Self {
&self[from..to]
}
fn split_at(self, i: usize) -> (Self, Self) {
(*self).split_at(i)
}
}
impl<'a, T> RingSlices for &'a mut [T] {
fn slice(self, from: usize, to: usize) -> Self {
&mut self[from..to]
}
fn split_at(self, i: usize) -> (Self, Self) {
(*self).split_at_mut(i)
}
}
/// Calculate the number of elements left to be read in the buffer
#[inline]
2015-02-04 21:17:19 -05:00
fn count(tail: usize, head: usize, size: usize) -> usize {
// size is always a power of 2
(head.wrapping_sub(tail)) & (size - 1)
}
/// An iterator over the elements of a `VecDeque`.
///
/// This `struct` is created by the [`iter`] method on [`VecDeque`]. See its
/// documentation for more.
///
/// [`iter`]: struct.VecDeque.html#method.iter
/// [`VecDeque`]: struct.VecDeque.html
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-11-24 11:23:48 +13:00
pub struct Iter<'a, T: 'a> {
ring: &'a [T],
2015-02-04 21:17:19 -05:00
tail: usize,
2015-11-24 11:23:48 +13:00
head: usize,
}
#[stable(feature = "collection_debug", since = "1.17.0")]
impl<'a, T: 'a + fmt::Debug> fmt::Debug for Iter<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Iter")
2017-04-17 18:06:43 +02:00
.field(&self.ring)
.field(&self.tail)
.field(&self.head)
.finish()
}
}
// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
2015-11-16 19:54:28 +03:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Clone for Iter<'a, T> {
fn clone(&self) -> Iter<'a, T> {
Iter {
ring: self.ring,
tail: self.tail,
2015-11-24 11:23:48 +13:00
head: self.head,
}
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<&'a T> {
if self.tail == self.head {
return None;
}
let tail = self.tail;
self.tail = wrap_index(self.tail.wrapping_add(1), self.ring.len());
2014-12-30 10:51:18 -08:00
unsafe { Some(self.ring.get_unchecked(tail)) }
}
#[inline]
2015-02-04 21:17:19 -05:00
fn size_hint(&self) -> (usize, Option<usize>) {
let len = count(self.tail, self.head, self.ring.len());
(len, Some(len))
2013-07-16 01:13:26 +02:00
}
fn fold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
2016-12-20 09:54:00 +05:30
where F: FnMut(Acc, Self::Item) -> Acc
{
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
accum = front.iter().fold(accum, &mut f);
back.iter().fold(accum, &mut f)
}
2013-06-25 15:08:47 -04:00
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a T> {
if self.tail == self.head {
return None;
}
self.head = wrap_index(self.head.wrapping_sub(1), self.ring.len());
2014-12-30 10:51:18 -08:00
unsafe { Some(self.ring.get_unchecked(self.head)) }
}
2013-06-25 15:08:47 -04:00
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for Iter<'a, T> {
fn is_empty(&self) -> bool {
self.head == self.tail
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Iter<'a, T> {}
/// A mutable iterator over the elements of a `VecDeque`.
///
/// This `struct` is created by the [`iter_mut`] method on [`VecDeque`]. See its
/// documentation for more.
///
/// [`iter_mut`]: struct.VecDeque.html#method.iter_mut
/// [`VecDeque`]: struct.VecDeque.html
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-11-24 11:23:48 +13:00
pub struct IterMut<'a, T: 'a> {
ring: &'a mut [T],
2015-02-04 21:17:19 -05:00
tail: usize,
head: usize,
}
#[stable(feature = "collection_debug", since = "1.17.0")]
impl<'a, T: 'a + fmt::Debug> fmt::Debug for IterMut<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("IterMut")
2017-04-17 18:06:43 +02:00
.field(&self.ring)
.field(&self.tail)
.field(&self.head)
.finish()
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
#[inline]
fn next(&mut self) -> Option<&'a mut T> {
if self.tail == self.head {
return None;
}
let tail = self.tail;
self.tail = wrap_index(self.tail.wrapping_add(1), self.ring.len());
2014-11-22 21:34:11 -05:00
unsafe {
let elem = self.ring.get_unchecked_mut(tail);
Some(&mut *(elem as *mut _))
}
}
#[inline]
2015-02-04 21:17:19 -05:00
fn size_hint(&self) -> (usize, Option<usize>) {
let len = count(self.tail, self.head, self.ring.len());
(len, Some(len))
}
fn fold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
2016-12-20 09:54:00 +05:30
where F: FnMut(Acc, Self::Item) -> Acc
{
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
accum = front.iter_mut().fold(accum, &mut f);
back.iter_mut().fold(accum, &mut f)
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a mut T> {
if self.tail == self.head {
return None;
}
self.head = wrap_index(self.head.wrapping_sub(1), self.ring.len());
2014-11-22 21:34:11 -05:00
unsafe {
let elem = self.ring.get_unchecked_mut(self.head);
Some(&mut *(elem as *mut _))
2014-11-22 21:34:11 -05:00
}
}
2013-06-25 15:08:47 -04:00
}
2012-01-11 12:49:33 +01:00
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
fn is_empty(&self) -> bool {
self.head == self.tail
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for IterMut<'a, T> {}
/// An owning iterator over the elements of a `VecDeque`.
///
2017-04-21 16:09:28 +02:00
/// This `struct` is created by the [`into_iter`] method on [`VecDeque`][`VecDeque`]
/// (provided by the `IntoIterator` trait). See its documentation for more.
///
/// [`into_iter`]: struct.VecDeque.html#method.into_iter
/// [`VecDeque`]: struct.VecDeque.html
#[derive(Clone)]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<T> {
inner: VecDeque<T>,
2014-11-22 21:34:11 -05:00
}
#[stable(feature = "collection_debug", since = "1.17.0")]
impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("IntoIter")
2017-04-17 18:06:43 +02:00
.field(&self.inner)
.finish()
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
impl<T> Iterator for IntoIter<T> {
type Item = T;
2014-11-22 21:34:11 -05:00
#[inline]
fn next(&mut self) -> Option<T> {
self.inner.pop_front()
}
#[inline]
2015-02-04 21:17:19 -05:00
fn size_hint(&self) -> (usize, Option<usize>) {
2014-11-22 21:34:11 -05:00
let len = self.inner.len();
(len, Some(len))
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
impl<T> DoubleEndedIterator for IntoIter<T> {
2014-11-22 21:34:11 -05:00
#[inline]
fn next_back(&mut self) -> Option<T> {
self.inner.pop_back()
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {
fn is_empty(&self) -> bool {
self.inner.is_empty()
}
}
2014-11-22 21:34:11 -05:00
#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}
/// A draining iterator over the elements of a `VecDeque`.
///
/// This `struct` is created by the [`drain`] method on [`VecDeque`]. See its
/// documentation for more.
///
/// [`drain`]: struct.VecDeque.html#method.drain
/// [`VecDeque`]: struct.VecDeque.html
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[stable(feature = "drain", since = "1.6.0")]
pub struct Drain<'a, T: 'a> {
after_tail: usize,
after_head: usize,
iter: Iter<'a, T>,
deque: Shared<VecDeque<T>>,
}
#[stable(feature = "collection_debug", since = "1.17.0")]
impl<'a, T: 'a + fmt::Debug> fmt::Debug for Drain<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Drain")
2017-04-17 18:06:43 +02:00
.field(&self.after_tail)
.field(&self.after_head)
.field(&self.iter)
.finish()
}
}
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[stable(feature = "drain", since = "1.6.0")]
unsafe impl<'a, T: Sync> Sync for Drain<'a, T> {}
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[stable(feature = "drain", since = "1.6.0")]
unsafe impl<'a, T: Send> Send for Drain<'a, T> {}
#[stable(feature = "drain", since = "1.6.0")]
impl<'a, T: 'a> Drop for Drain<'a, T> {
fn drop(&mut self) {
2015-01-10 21:50:07 -05:00
for _ in self.by_ref() {}
let source_deque = unsafe { self.deque.as_mut() };
// T = source_deque_tail; H = source_deque_head; t = drain_tail; h = drain_head
//
// T t h H
// [. . . o o x x o o . . .]
//
let orig_tail = source_deque.tail;
let drain_tail = source_deque.head;
let drain_head = self.after_tail;
let orig_head = self.after_head;
let tail_len = count(orig_tail, drain_tail, source_deque.cap());
let head_len = count(drain_head, orig_head, source_deque.cap());
// Restore the original head value
source_deque.head = orig_head;
match (tail_len, head_len) {
(0, 0) => {
source_deque.head = 0;
source_deque.tail = 0;
}
(0, _) => {
source_deque.tail = drain_head;
}
(_, 0) => {
source_deque.head = drain_tail;
}
2016-12-20 09:54:00 +05:30
_ => unsafe {
if tail_len <= head_len {
source_deque.tail = source_deque.wrap_sub(drain_head, tail_len);
source_deque.wrap_copy(source_deque.tail, orig_tail, tail_len);
} else {
source_deque.head = source_deque.wrap_add(drain_tail, head_len);
source_deque.wrap_copy(drain_tail, drain_head, head_len);
}
2016-12-20 09:54:00 +05:30
},
}
}
}
#[stable(feature = "drain", since = "1.6.0")]
2015-01-01 23:15:35 -05:00
impl<'a, T: 'a> Iterator for Drain<'a, T> {
type Item = T;
#[inline]
fn next(&mut self) -> Option<T> {
2015-11-24 11:23:48 +13:00
self.iter.next().map(|elt| unsafe { ptr::read(elt) })
}
#[inline]
2015-02-04 21:17:19 -05:00
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
#[stable(feature = "drain", since = "1.6.0")]
2015-01-01 23:15:35 -05:00
impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<T> {
2015-11-24 11:23:48 +13:00
self.iter.next_back().map(|elt| unsafe { ptr::read(elt) })
}
}
#[stable(feature = "drain", since = "1.6.0")]
2015-01-01 23:15:35 -05:00
impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: 'a> FusedIterator for Drain<'a, T> {}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: PartialEq> PartialEq for VecDeque<A> {
fn eq(&self, other: &VecDeque<A>) -> bool {
if self.len() != other.len() {
return false;
}
let (sa, sb) = self.as_slices();
let (oa, ob) = other.as_slices();
if sa.len() == oa.len() {
sa == oa && sb == ob
} else if sa.len() < oa.len() {
// Always divisible in three sections, for example:
// self: [a b c|d e f]
// other: [0 1 2 3|4 5]
// front = 3, mid = 1,
// [a b c] == [0 1 2] && [d] == [3] && [e f] == [4 5]
let front = sa.len();
let mid = oa.len() - front;
let (oa_front, oa_mid) = oa.split_at(front);
let (sb_mid, sb_back) = sb.split_at(mid);
debug_assert_eq!(sa.len(), oa_front.len());
debug_assert_eq!(sb_mid.len(), oa_mid.len());
debug_assert_eq!(sb_back.len(), ob.len());
sa == oa_front && sb_mid == oa_mid && sb_back == ob
} else {
let front = oa.len();
let mid = sa.len() - front;
let (sa_front, sa_mid) = sa.split_at(front);
let (ob_mid, ob_back) = ob.split_at(mid);
debug_assert_eq!(sa_front.len(), oa.len());
debug_assert_eq!(sa_mid.len(), ob_mid.len());
debug_assert_eq!(sb.len(), ob_back.len());
sa_front == oa && sa_mid == ob_mid && sb == ob_back
}
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Eq> Eq for VecDeque<A> {}
macro_rules! __impl_slice_eq1 {
($Lhs: ty, $Rhs: ty) => {
__impl_slice_eq1! { $Lhs, $Rhs, Sized }
};
($Lhs: ty, $Rhs: ty, $Bound: ident) => {
#[stable(feature = "vec-deque-partial-eq-slice", since = "1.17.0")]
impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
fn eq(&self, other: &$Rhs) -> bool {
if self.len() != other.len() {
return false;
}
let (sa, sb) = self.as_slices();
let (oa, ob) = other[..].split_at(sa.len());
sa == oa && sb == ob
}
}
}
}
__impl_slice_eq1! { VecDeque<A>, Vec<B> }
__impl_slice_eq1! { VecDeque<A>, &'b [B] }
__impl_slice_eq1! { VecDeque<A>, &'b mut [B] }
macro_rules! array_impls {
($($N: expr)+) => {
$(
__impl_slice_eq1! { VecDeque<A>, [B; $N] }
__impl_slice_eq1! { VecDeque<A>, &'b [B; $N] }
__impl_slice_eq1! { VecDeque<A>, &'b mut [B; $N] }
)+
}
}
array_impls! {
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: PartialOrd> PartialOrd for VecDeque<A> {
fn partial_cmp(&self, other: &VecDeque<A>) -> Option<Ordering> {
self.iter().partial_cmp(other.iter())
2014-07-26 23:18:56 -04:00
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Ord> Ord for VecDeque<A> {
#[inline]
fn cmp(&self, other: &VecDeque<A>) -> Ordering {
self.iter().cmp(other.iter())
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Hash> Hash for VecDeque<A> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.len().hash(state);
let (a, b) = self.as_slices();
Hash::hash_slice(a, state);
Hash::hash_slice(b, state);
}
}
2014-07-26 22:33:47 -04:00
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> Index<usize> for VecDeque<A> {
2015-01-03 10:40:10 -05:00
type Output = A;
#[inline]
fn index(&self, index: usize) -> &A {
self.get(index).expect("Out of bounds access")
}
2015-01-03 10:40:10 -05:00
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> IndexMut<usize> for VecDeque<A> {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut A {
self.get_mut(index).expect("Out of bounds access")
}
2015-01-03 10:40:10 -05:00
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> FromIterator<A> for VecDeque<A> {
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> VecDeque<A> {
let iterator = iter.into_iter();
2013-07-30 02:06:49 +02:00
let (lower, _) = iterator.size_hint();
let mut deq = VecDeque::with_capacity(lower);
2013-07-30 02:06:49 +02:00
deq.extend(iterator);
deq
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> IntoIterator for VecDeque<T> {
type Item = T;
type IntoIter = IntoIter<T>;
/// Consumes the list into a front-to-back iterator yielding elements by
/// value.
fn into_iter(self) -> IntoIter<T> {
2015-11-24 11:23:48 +13:00
IntoIter { inner: self }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> IntoIterator for &'a VecDeque<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> IntoIterator for &'a mut VecDeque<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
2015-01-07 22:01:05 -05:00
fn into_iter(mut self) -> IterMut<'a, T> {
self.iter_mut()
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> Extend<A> for VecDeque<A> {
2015-11-24 11:23:48 +13:00
fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T) {
for elt in iter {
self.push_back(elt);
}
}
}
2015-06-03 12:38:42 +02:00
#[stable(feature = "extend_ref", since = "1.2.0")]
impl<'a, T: 'a + Copy> Extend<&'a T> for VecDeque<T> {
2015-11-24 11:23:48 +13:00
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
2015-06-03 12:38:42 +02:00
self.extend(iter.into_iter().cloned());
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
2014-06-04 16:15:04 +02:00
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list().entries(self).finish()
2014-06-04 16:15:04 +02:00
}
}
2015-03-11 19:44:02 -05:00
#[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")]
impl<T> From<Vec<T>> for VecDeque<T> {
fn from(mut other: Vec<T>) -> Self {
unsafe {
let other_buf = other.as_mut_ptr();
let mut buf = RawVec::from_raw_parts(other_buf, other.capacity());
let len = other.len();
mem::forget(other);
// We need to extend the buf if it's not a power of two, too small
// or doesn't have at least one free space
2016-12-20 09:54:00 +05:30
if !buf.cap().is_power_of_two() || (buf.cap() < (MINIMUM_CAPACITY + 1)) ||
(buf.cap() == len) {
let cap = cmp::max(buf.cap() + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
buf.reserve_exact(len, cap - len);
}
VecDeque {
tail: 0,
head: len,
2016-12-20 09:54:00 +05:30
buf: buf,
}
}
}
}
#[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")]
impl<T> From<VecDeque<T>> for Vec<T> {
fn from(other: VecDeque<T>) -> Self {
unsafe {
let buf = other.buf.ptr();
let len = other.len();
let tail = other.tail;
let head = other.head;
let cap = other.cap();
// Need to move the ring to the front of the buffer, as vec will expect this.
if other.is_contiguous() {
ptr::copy(buf.offset(tail as isize), buf, len);
} else {
if (tail - head) >= cmp::min((cap - tail), head) {
// There is enough free space in the centre for the shortest block so we can
// do this in at most three copy moves.
if (cap - tail) > head {
// right hand block is the long one; move that enough for the left
2016-12-20 09:54:00 +05:30
ptr::copy(buf.offset(tail as isize),
buf.offset((tail - head) as isize),
cap - tail);
// copy left in the end
ptr::copy(buf, buf.offset((cap - head) as isize), head);
// shift the new thing to the start
2016-12-20 09:54:00 +05:30
ptr::copy(buf.offset((tail - head) as isize), buf, len);
} else {
// left hand block is the long one, we can do it in two!
2016-12-20 09:54:00 +05:30
ptr::copy(buf, buf.offset((cap - tail) as isize), head);
ptr::copy(buf.offset(tail as isize), buf, cap - tail);
}
} else {
// Need to use N swaps to move the ring
// We can use the space at the end of the ring as a temp store
let mut left_edge: usize = 0;
let mut right_edge: usize = tail;
// The general problem looks like this
// GHIJKLM...ABCDEF - before any swaps
// ABCDEFM...GHIJKL - after 1 pass of swaps
// ABCDEFGHIJM...KL - swap until the left edge reaches the temp store
// - then restart the algorithm with a new (smaller) store
// Sometimes the temp store is reached when the right edge is at the end
// of the buffer - this means we've hit the right order with fewer swaps!
// E.g
// EF..ABCD
// ABCDEF.. - after four only swaps we've finished
while left_edge < len && right_edge != cap {
let mut right_offset = 0;
for i in left_edge..right_edge {
right_offset = (i - left_edge) % (cap - right_edge);
let src: isize = (right_edge + right_offset) as isize;
ptr::swap(buf.offset(i as isize), buf.offset(src));
}
let n_ops = right_edge - left_edge;
left_edge += n_ops;
right_edge += right_offset + 1;
}
}
}
let out = Vec::from_raw_parts(buf, len, cap);
mem::forget(other);
out
}
}
}
/// A place for insertion at the back of a `VecDeque`.
///
/// See [`VecDeque::place_back`](struct.VecDeque.html#method.place_back) for details.
#[must_use = "places do nothing unless written to with `<-` syntax"]
#[unstable(feature = "collection_placement",
reason = "struct name and placement protocol are subject to change",
issue = "30172")]
#[derive(Debug)]
pub struct PlaceBack<'a, T: 'a> {
vec_deque: &'a mut VecDeque<T>,
}
#[unstable(feature = "collection_placement",
reason = "placement protocol is subject to change",
issue = "30172")]
impl<'a, T> Placer<T> for PlaceBack<'a, T> {
type Place = PlaceBack<'a, T>;
fn make_place(self) -> Self {
self.vec_deque.grow_if_necessary();
self
}
}
#[unstable(feature = "collection_placement",
reason = "placement protocol is subject to change",
issue = "30172")]
impl<'a, T> Place<T> for PlaceBack<'a, T> {
fn pointer(&mut self) -> *mut T {
unsafe { self.vec_deque.ptr().offset(self.vec_deque.head as isize) }
}
}
#[unstable(feature = "collection_placement",
reason = "placement protocol is subject to change",
issue = "30172")]
impl<'a, T> InPlace<T> for PlaceBack<'a, T> {
type Owner = &'a mut T;
unsafe fn finalize(mut self) -> &'a mut T {
let head = self.vec_deque.head;
self.vec_deque.head = self.vec_deque.wrap_add(head, 1);
&mut *(self.vec_deque.ptr().offset(head as isize))
}
}
/// A place for insertion at the front of a `VecDeque`.
///
/// See [`VecDeque::place_front`](struct.VecDeque.html#method.place_front) for details.
#[must_use = "places do nothing unless written to with `<-` syntax"]
#[unstable(feature = "collection_placement",
reason = "struct name and placement protocol are subject to change",
issue = "30172")]
#[derive(Debug)]
pub struct PlaceFront<'a, T: 'a> {
vec_deque: &'a mut VecDeque<T>,
}
#[unstable(feature = "collection_placement",
reason = "placement protocol is subject to change",
issue = "30172")]
impl<'a, T> Placer<T> for PlaceFront<'a, T> {
type Place = PlaceFront<'a, T>;
fn make_place(self) -> Self {
self.vec_deque.grow_if_necessary();
self
}
}
#[unstable(feature = "collection_placement",
reason = "placement protocol is subject to change",
issue = "30172")]
impl<'a, T> Place<T> for PlaceFront<'a, T> {
fn pointer(&mut self) -> *mut T {
let tail = self.vec_deque.wrap_sub(self.vec_deque.tail, 1);
unsafe { self.vec_deque.ptr().offset(tail as isize) }
}
}
#[unstable(feature = "collection_placement",
reason = "placement protocol is subject to change",
issue = "30172")]
impl<'a, T> InPlace<T> for PlaceFront<'a, T> {
type Owner = &'a mut T;
unsafe fn finalize(mut self) -> &'a mut T {
self.vec_deque.tail = self.vec_deque.wrap_sub(self.vec_deque.tail, 1);
&mut *(self.vec_deque.ptr().offset(self.vec_deque.tail as isize))
}
}
2015-03-11 19:44:02 -05:00
#[cfg(test)]
mod tests {
2015-03-11 19:44:02 -05:00
use test;
use super::VecDeque;
#[bench]
fn bench_push_back_100(b: &mut test::Bencher) {
let mut deq = VecDeque::with_capacity(101);
b.iter(|| {
for i in 0..100 {
deq.push_back(i);
}
deq.head = 0;
deq.tail = 0;
})
}
#[bench]
fn bench_push_front_100(b: &mut test::Bencher) {
let mut deq = VecDeque::with_capacity(101);
b.iter(|| {
for i in 0..100 {
deq.push_front(i);
}
deq.head = 0;
deq.tail = 0;
})
}
#[bench]
fn bench_pop_back_100(b: &mut test::Bencher) {
2015-11-24 11:23:48 +13:00
let mut deq = VecDeque::<i32>::with_capacity(101);
2015-03-11 19:44:02 -05:00
b.iter(|| {
deq.head = 100;
deq.tail = 0;
while !deq.is_empty() {
test::black_box(deq.pop_back());
}
})
}
#[bench]
fn bench_pop_front_100(b: &mut test::Bencher) {
let mut deq = VecDeque::<i32>::with_capacity(101);
b.iter(|| {
deq.head = 100;
deq.tail = 0;
while !deq.is_empty() {
test::black_box(deq.pop_front());
}
})
}
#[test]
fn test_swap_front_back_remove() {
fn test(back: bool) {
// This test checks that every single combination of tail position and length is tested.
// Capacity 15 should be large enough to cover every case.
let mut tester = VecDeque::with_capacity(15);
let usable_cap = tester.capacity();
let final_len = usable_cap / 2;
for len in 0..final_len {
let expected: VecDeque<_> = if back {
2015-03-11 19:44:02 -05:00
(0..len).collect()
} else {
(0..len).rev().collect()
};
for tail_pos in 0..usable_cap {
tester.tail = tail_pos;
tester.head = tail_pos;
if back {
for i in 0..len * 2 {
tester.push_front(i);
}
for i in 0..len {
assert_eq!(tester.swap_remove_back(i), Some(len * 2 - 1 - i));
2015-03-11 19:44:02 -05:00
}
} else {
for i in 0..len * 2 {
tester.push_back(i);
}
for i in 0..len {
let idx = tester.len() - 1 - i;
assert_eq!(tester.swap_remove_front(idx), Some(len * 2 - 1 - i));
2015-03-11 19:44:02 -05:00
}
}
2015-07-09 21:57:21 -07:00
assert!(tester.tail < tester.cap());
assert!(tester.head < tester.cap());
2015-03-11 19:44:02 -05:00
assert_eq!(tester, expected);
}
}
}
test(true);
test(false);
}
#[test]
fn test_insert() {
// This test checks that every single combination of tail position, length, and
// insertion position is tested. Capacity 15 should be large enough to cover every case.
let mut tester = VecDeque::with_capacity(15);
// can't guarantee we got 15, so have to get what we got.
// 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
// this test isn't covering what it wants to
let cap = tester.capacity();
// len is the length *after* insertion
for len in 1..cap {
// 0, 1, 2, .., len - 1
let expected = (0..).take(len).collect::<VecDeque<_>>();
2015-03-11 19:44:02 -05:00
for tail_pos in 0..cap {
for to_insert in 0..len {
tester.tail = tail_pos;
tester.head = tail_pos;
for i in 0..len {
if i != to_insert {
tester.push_back(i);
}
}
tester.insert(to_insert, to_insert);
2015-07-09 21:57:21 -07:00
assert!(tester.tail < tester.cap());
assert!(tester.head < tester.cap());
2015-03-11 19:44:02 -05:00
assert_eq!(tester, expected);
}
}
}
}
#[test]
fn test_remove() {
// This test checks that every single combination of tail position, length, and
// removal position is tested. Capacity 15 should be large enough to cover every case.
let mut tester = VecDeque::with_capacity(15);
// can't guarantee we got 15, so have to get what we got.
// 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
// this test isn't covering what it wants to
let cap = tester.capacity();
// len is the length *after* removal
for len in 0..cap - 1 {
// 0, 1, 2, .., len - 1
let expected = (0..).take(len).collect::<VecDeque<_>>();
2015-03-11 19:44:02 -05:00
for tail_pos in 0..cap {
for to_remove in 0..len + 1 {
tester.tail = tail_pos;
tester.head = tail_pos;
for i in 0..len {
if i == to_remove {
tester.push_back(1234);
}
tester.push_back(i);
}
if to_remove == len {
tester.push_back(1234);
}
tester.remove(to_remove);
2015-07-09 21:57:21 -07:00
assert!(tester.tail < tester.cap());
assert!(tester.head < tester.cap());
2015-03-11 19:44:02 -05:00
assert_eq!(tester, expected);
}
}
}
}
#[test]
fn test_drain() {
let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
let cap = tester.capacity();
for len in 0..cap + 1 {
for tail in 0..cap + 1 {
for drain_start in 0..len + 1 {
for drain_end in drain_start..len + 1 {
tester.tail = tail;
tester.head = tail;
for i in 0..len {
tester.push_back(i);
}
// Check that we drain the correct values
2015-11-24 11:23:48 +13:00
let drained: VecDeque<_> = tester.drain(drain_start..drain_end).collect();
let drained_expected: VecDeque<_> = (drain_start..drain_end).collect();
assert_eq!(drained, drained_expected);
// We shouldn't have changed the capacity or made the
// head or tail out of bounds
assert_eq!(tester.capacity(), cap);
assert!(tester.tail < tester.cap());
assert!(tester.head < tester.cap());
// We should see the correct values in the VecDeque
2015-11-24 11:23:48 +13:00
let expected: VecDeque<_> = (0..drain_start)
2016-12-20 09:54:00 +05:30
.chain(drain_end..len)
.collect();
assert_eq!(expected, tester);
}
}
}
}
}
2015-03-11 19:44:02 -05:00
#[test]
fn test_shrink_to_fit() {
// This test checks that every single combination of head and tail position,
// is tested. Capacity 15 should be large enough to cover every case.
let mut tester = VecDeque::with_capacity(15);
// can't guarantee we got 15, so have to get what we got.
// 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
// this test isn't covering what it wants to
let cap = tester.capacity();
tester.reserve(63);
let max_cap = tester.capacity();
for len in 0..cap + 1 {
// 0, 1, 2, .., len - 1
let expected = (0..).take(len).collect::<VecDeque<_>>();
2015-03-11 19:44:02 -05:00
for tail_pos in 0..max_cap + 1 {
tester.tail = tail_pos;
tester.head = tail_pos;
tester.reserve(63);
for i in 0..len {
tester.push_back(i);
}
tester.shrink_to_fit();
assert!(tester.capacity() <= cap);
2015-07-09 21:57:21 -07:00
assert!(tester.tail < tester.cap());
assert!(tester.head < tester.cap());
2015-03-11 19:44:02 -05:00
assert_eq!(tester, expected);
}
}
}
#[test]
fn test_split_off() {
// This test checks that every single combination of tail position, length, and
// split position is tested. Capacity 15 should be large enough to cover every case.
let mut tester = VecDeque::with_capacity(15);
// can't guarantee we got 15, so have to get what we got.
// 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
// this test isn't covering what it wants to
let cap = tester.capacity();
// len is the length *before* splitting
for len in 0..cap {
// index to split at
for at in 0..len + 1 {
// 0, 1, 2, .., at - 1 (may be empty)
let expected_self = (0..).take(at).collect::<VecDeque<_>>();
2015-03-11 19:44:02 -05:00
// at, at + 1, .., len - 1 (may be empty)
let expected_other = (at..).take(len - at).collect::<VecDeque<_>>();
2015-03-11 19:44:02 -05:00
for tail_pos in 0..cap {
tester.tail = tail_pos;
tester.head = tail_pos;
for i in 0..len {
tester.push_back(i);
}
let result = tester.split_off(at);
2015-07-09 21:57:21 -07:00
assert!(tester.tail < tester.cap());
assert!(tester.head < tester.cap());
assert!(result.tail < result.cap());
assert!(result.head < result.cap());
2015-03-11 19:44:02 -05:00
assert_eq!(tester, expected_self);
assert_eq!(result, expected_other);
}
}
}
}
#[test]
fn test_from_vec() {
use super::super::vec::Vec;
for cap in 0..35 {
for len in 0..cap + 1 {
let mut vec = Vec::with_capacity(cap);
vec.extend(0..len);
let vd = VecDeque::from(vec.clone());
assert!(vd.cap().is_power_of_two());
assert_eq!(vd.len(), vec.len());
assert!(vd.into_iter().eq(vec));
}
}
}
#[test]
fn test_vec_from_vecdeque() {
use super::super::vec::Vec;
fn create_vec_and_test_convert(cap: usize, offset: usize, len: usize) {
let mut vd = VecDeque::with_capacity(cap);
for _ in 0..offset {
vd.push_back(0);
vd.pop_front();
}
vd.extend(0..len);
let vec: Vec<_> = Vec::from(vd.clone());
assert_eq!(vec.len(), vd.len());
assert!(vec.into_iter().eq(vd));
}
for cap_pwr in 0..7 {
// Make capacity as a (2^x)-1, so that the ring size is 2^x
let cap = (2i32.pow(cap_pwr) - 1) as usize;
// In these cases there is enough free space to solve it with copies
2016-12-20 09:54:00 +05:30
for len in 0..((cap + 1) / 2) {
// Test contiguous cases
2016-12-20 09:54:00 +05:30
for offset in 0..(cap - len) {
create_vec_and_test_convert(cap, offset, len)
}
// Test cases where block at end of buffer is bigger than block at start
2016-12-20 09:54:00 +05:30
for offset in (cap - len)..(cap - (len / 2)) {
create_vec_and_test_convert(cap, offset, len)
}
// Test cases where block at start of buffer is bigger than block at end
2016-12-20 09:54:00 +05:30
for offset in (cap - (len / 2))..cap {
create_vec_and_test_convert(cap, offset, len)
}
}
// Now there's not (necessarily) space to straighten the ring with simple copies,
// the ring will use swapping when:
// (cap + 1 - offset) > (cap + 1 - len) && (len - (cap + 1 - offset)) > (cap + 1 - len))
// right block size > free space && left block size > free space
2016-12-20 09:54:00 +05:30
for len in ((cap + 1) / 2)..cap {
// Test contiguous cases
2016-12-20 09:54:00 +05:30
for offset in 0..(cap - len) {
create_vec_and_test_convert(cap, offset, len)
}
// Test cases where block at end of buffer is bigger than block at start
2016-12-20 09:54:00 +05:30
for offset in (cap - len)..(cap - (len / 2)) {
create_vec_and_test_convert(cap, offset, len)
}
// Test cases where block at start of buffer is bigger than block at end
2016-12-20 09:54:00 +05:30
for offset in (cap - (len / 2))..cap {
create_vec_and_test_convert(cap, offset, len)
}
}
}
}
2015-03-11 19:44:02 -05:00
}