Rollup merge of #40389 - F001:placementVecDeque, r=nagisa
Implement placement-in protocol for `VecDeque` CC #30172 r? @nagisa
This commit is contained in:
commit
dcf41821b8
|
@ -22,7 +22,7 @@ use core::cmp::Ordering;
|
|||
use core::fmt;
|
||||
use core::iter::{repeat, FromIterator, FusedIterator};
|
||||
use core::mem;
|
||||
use core::ops::{Index, IndexMut};
|
||||
use core::ops::{Index, IndexMut, Place, Placer, InPlace};
|
||||
use core::ptr;
|
||||
use core::ptr::Shared;
|
||||
use core::slice;
|
||||
|
@ -1087,14 +1087,7 @@ impl<T> VecDeque<T> {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn push_front(&mut self, value: T) {
|
||||
if self.is_full() {
|
||||
let old_cap = self.cap();
|
||||
self.buf.double();
|
||||
unsafe {
|
||||
self.handle_cap_increase(old_cap);
|
||||
}
|
||||
debug_assert!(!self.is_full());
|
||||
}
|
||||
self.grow_if_necessary();
|
||||
|
||||
self.tail = self.wrap_sub(self.tail, 1);
|
||||
let tail = self.tail;
|
||||
|
@ -1117,14 +1110,7 @@ impl<T> VecDeque<T> {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn push_back(&mut self, value: T) {
|
||||
if self.is_full() {
|
||||
let old_cap = self.cap();
|
||||
self.buf.double();
|
||||
unsafe {
|
||||
self.handle_cap_increase(old_cap);
|
||||
}
|
||||
debug_assert!(!self.is_full());
|
||||
}
|
||||
self.grow_if_necessary();
|
||||
|
||||
let head = self.head;
|
||||
self.head = self.wrap_add(self.head, 1);
|
||||
|
@ -1257,14 +1243,7 @@ impl<T> VecDeque<T> {
|
|||
#[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");
|
||||
if self.is_full() {
|
||||
let old_cap = self.cap();
|
||||
self.buf.double();
|
||||
unsafe {
|
||||
self.handle_cap_increase(old_cap);
|
||||
}
|
||||
debug_assert!(!self.is_full());
|
||||
}
|
||||
self.grow_if_necessary();
|
||||
|
||||
// Move the least number of elements in the ring buffer and insert
|
||||
// the given object
|
||||
|
@ -1762,6 +1741,69 @@ impl<T> VecDeque<T> {
|
|||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> VecDeque<T> {
|
||||
|
@ -2442,6 +2484,98 @@ impl<T> From<VecDeque<T>> for Vec<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// 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))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use test;
|
||||
|
@ -2797,4 +2931,5 @@ mod tests {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
extern crate collections;
|
||||
extern crate test;
|
||||
extern crate std_unicode;
|
||||
extern crate core;
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt::Debug;
|
||||
use std::collections::vec_deque::Drain;
|
||||
use std::collections::vec_deque::{Drain};
|
||||
|
||||
use self::Taggy::*;
|
||||
use self::Taggypar::*;
|
||||
|
@ -1000,3 +1000,25 @@ fn test_is_empty() {
|
|||
assert!(v.iter_mut().is_empty());
|
||||
assert!(v.into_iter().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_placement_in() {
|
||||
let mut buf: VecDeque<isize> = VecDeque::new();
|
||||
buf.place_back() <- 1;
|
||||
buf.place_back() <- 2;
|
||||
assert_eq!(buf, [1,2]);
|
||||
|
||||
buf.place_front() <- 3;
|
||||
buf.place_front() <- 4;
|
||||
assert_eq!(buf, [4,3,1,2]);
|
||||
|
||||
{
|
||||
let ptr_head = buf.place_front() <- 5;
|
||||
assert_eq!(*ptr_head, 5);
|
||||
}
|
||||
{
|
||||
let ptr_tail = buf.place_back() <- 6;
|
||||
assert_eq!(*ptr_tail, 6);
|
||||
}
|
||||
assert_eq!(buf, [5,4,3,1,2,6]);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue