Skip to content

Commit 7769c7e

Browse files
authored
Rollup merge of rust-lang#40389 - F001:placementVecDeque, r=nagisa
Implement placement-in protocol for `VecDeque` CC rust-lang#30172 r? @nagisa
2 parents 1beff33 + 8062cfb commit 7769c7e

File tree

3 files changed

+184
-26
lines changed

3 files changed

+184
-26
lines changed

src/libcollections/vec_deque.rs

+160-25
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use core::cmp::Ordering;
2222
use core::fmt;
2323
use core::iter::{repeat, FromIterator, FusedIterator};
2424
use core::mem;
25-
use core::ops::{Index, IndexMut};
25+
use core::ops::{Index, IndexMut, Place, Placer, InPlace};
2626
use core::ptr;
2727
use core::ptr::Shared;
2828
use core::slice;
@@ -1087,14 +1087,7 @@ impl<T> VecDeque<T> {
10871087
/// ```
10881088
#[stable(feature = "rust1", since = "1.0.0")]
10891089
pub fn push_front(&mut self, value: T) {
1090-
if self.is_full() {
1091-
let old_cap = self.cap();
1092-
self.buf.double();
1093-
unsafe {
1094-
self.handle_cap_increase(old_cap);
1095-
}
1096-
debug_assert!(!self.is_full());
1097-
}
1090+
self.grow_if_necessary();
10981091

10991092
self.tail = self.wrap_sub(self.tail, 1);
11001093
let tail = self.tail;
@@ -1117,14 +1110,7 @@ impl<T> VecDeque<T> {
11171110
/// ```
11181111
#[stable(feature = "rust1", since = "1.0.0")]
11191112
pub fn push_back(&mut self, value: T) {
1120-
if self.is_full() {
1121-
let old_cap = self.cap();
1122-
self.buf.double();
1123-
unsafe {
1124-
self.handle_cap_increase(old_cap);
1125-
}
1126-
debug_assert!(!self.is_full());
1127-
}
1113+
self.grow_if_necessary();
11281114

11291115
let head = self.head;
11301116
self.head = self.wrap_add(self.head, 1);
@@ -1257,14 +1243,7 @@ impl<T> VecDeque<T> {
12571243
#[stable(feature = "deque_extras_15", since = "1.5.0")]
12581244
pub fn insert(&mut self, index: usize, value: T) {
12591245
assert!(index <= self.len(), "index out of bounds");
1260-
if self.is_full() {
1261-
let old_cap = self.cap();
1262-
self.buf.double();
1263-
unsafe {
1264-
self.handle_cap_increase(old_cap);
1265-
}
1266-
debug_assert!(!self.is_full());
1267-
}
1246+
self.grow_if_necessary();
12681247

12691248
// Move the least number of elements in the ring buffer and insert
12701249
// the given object
@@ -1762,6 +1741,69 @@ impl<T> VecDeque<T> {
17621741
self.truncate(len - del);
17631742
}
17641743
}
1744+
1745+
// This may panic or abort
1746+
#[inline]
1747+
fn grow_if_necessary(&mut self) {
1748+
if self.is_full() {
1749+
let old_cap = self.cap();
1750+
self.buf.double();
1751+
unsafe {
1752+
self.handle_cap_increase(old_cap);
1753+
}
1754+
debug_assert!(!self.is_full());
1755+
}
1756+
}
1757+
1758+
/// Returns a place for insertion at the back of the `VecDeque`.
1759+
///
1760+
/// Using this method with placement syntax is equivalent to [`push_back`](#method.push_back),
1761+
/// but may be more efficient.
1762+
///
1763+
/// # Examples
1764+
///
1765+
/// ```
1766+
/// #![feature(collection_placement)]
1767+
/// #![feature(placement_in_syntax)]
1768+
///
1769+
/// use std::collections::VecDeque;
1770+
///
1771+
/// let mut buf = VecDeque::new();
1772+
/// buf.place_back() <- 3;
1773+
/// buf.place_back() <- 4;
1774+
/// assert_eq!(&buf, &[3, 4]);
1775+
/// ```
1776+
#[unstable(feature = "collection_placement",
1777+
reason = "placement protocol is subject to change",
1778+
issue = "30172")]
1779+
pub fn place_back(&mut self) -> PlaceBack<T> {
1780+
PlaceBack { vec_deque: self }
1781+
}
1782+
1783+
/// Returns a place for insertion at the front of the `VecDeque`.
1784+
///
1785+
/// Using this method with placement syntax is equivalent to [`push_front`](#method.push_front),
1786+
/// but may be more efficient.
1787+
///
1788+
/// # Examples
1789+
///
1790+
/// ```
1791+
/// #![feature(collection_placement)]
1792+
/// #![feature(placement_in_syntax)]
1793+
///
1794+
/// use std::collections::VecDeque;
1795+
///
1796+
/// let mut buf = VecDeque::new();
1797+
/// buf.place_front() <- 3;
1798+
/// buf.place_front() <- 4;
1799+
/// assert_eq!(&buf, &[4, 3]);
1800+
/// ```
1801+
#[unstable(feature = "collection_placement",
1802+
reason = "placement protocol is subject to change",
1803+
issue = "30172")]
1804+
pub fn place_front(&mut self) -> PlaceFront<T> {
1805+
PlaceFront { vec_deque: self }
1806+
}
17651807
}
17661808

17671809
impl<T: Clone> VecDeque<T> {
@@ -2442,6 +2484,98 @@ impl<T> From<VecDeque<T>> for Vec<T> {
24422484
}
24432485
}
24442486

2487+
/// A place for insertion at the back of a `VecDeque`.
2488+
///
2489+
/// See [`VecDeque::place_back`](struct.VecDeque.html#method.place_back) for details.
2490+
#[must_use = "places do nothing unless written to with `<-` syntax"]
2491+
#[unstable(feature = "collection_placement",
2492+
reason = "struct name and placement protocol are subject to change",
2493+
issue = "30172")]
2494+
#[derive(Debug)]
2495+
pub struct PlaceBack<'a, T: 'a> {
2496+
vec_deque: &'a mut VecDeque<T>,
2497+
}
2498+
2499+
#[unstable(feature = "collection_placement",
2500+
reason = "placement protocol is subject to change",
2501+
issue = "30172")]
2502+
impl<'a, T> Placer<T> for PlaceBack<'a, T> {
2503+
type Place = PlaceBack<'a, T>;
2504+
2505+
fn make_place(self) -> Self {
2506+
self.vec_deque.grow_if_necessary();
2507+
self
2508+
}
2509+
}
2510+
2511+
#[unstable(feature = "collection_placement",
2512+
reason = "placement protocol is subject to change",
2513+
issue = "30172")]
2514+
impl<'a, T> Place<T> for PlaceBack<'a, T> {
2515+
fn pointer(&mut self) -> *mut T {
2516+
unsafe { self.vec_deque.ptr().offset(self.vec_deque.head as isize) }
2517+
}
2518+
}
2519+
2520+
#[unstable(feature = "collection_placement",
2521+
reason = "placement protocol is subject to change",
2522+
issue = "30172")]
2523+
impl<'a, T> InPlace<T> for PlaceBack<'a, T> {
2524+
type Owner = &'a mut T;
2525+
2526+
unsafe fn finalize(mut self) -> &'a mut T {
2527+
let head = self.vec_deque.head;
2528+
self.vec_deque.head = self.vec_deque.wrap_add(head, 1);
2529+
&mut *(self.vec_deque.ptr().offset(head as isize))
2530+
}
2531+
}
2532+
2533+
/// A place for insertion at the front of a `VecDeque`.
2534+
///
2535+
/// See [`VecDeque::place_front`](struct.VecDeque.html#method.place_front) for details.
2536+
#[must_use = "places do nothing unless written to with `<-` syntax"]
2537+
#[unstable(feature = "collection_placement",
2538+
reason = "struct name and placement protocol are subject to change",
2539+
issue = "30172")]
2540+
#[derive(Debug)]
2541+
pub struct PlaceFront<'a, T: 'a> {
2542+
vec_deque: &'a mut VecDeque<T>,
2543+
}
2544+
2545+
#[unstable(feature = "collection_placement",
2546+
reason = "placement protocol is subject to change",
2547+
issue = "30172")]
2548+
impl<'a, T> Placer<T> for PlaceFront<'a, T> {
2549+
type Place = PlaceFront<'a, T>;
2550+
2551+
fn make_place(self) -> Self {
2552+
self.vec_deque.grow_if_necessary();
2553+
self
2554+
}
2555+
}
2556+
2557+
#[unstable(feature = "collection_placement",
2558+
reason = "placement protocol is subject to change",
2559+
issue = "30172")]
2560+
impl<'a, T> Place<T> for PlaceFront<'a, T> {
2561+
fn pointer(&mut self) -> *mut T {
2562+
let tail = self.vec_deque.wrap_sub(self.vec_deque.tail, 1);
2563+
unsafe { self.vec_deque.ptr().offset(tail as isize) }
2564+
}
2565+
}
2566+
2567+
#[unstable(feature = "collection_placement",
2568+
reason = "placement protocol is subject to change",
2569+
issue = "30172")]
2570+
impl<'a, T> InPlace<T> for PlaceFront<'a, T> {
2571+
type Owner = &'a mut T;
2572+
2573+
unsafe fn finalize(mut self) -> &'a mut T {
2574+
self.vec_deque.tail = self.vec_deque.wrap_sub(self.vec_deque.tail, 1);
2575+
&mut *(self.vec_deque.ptr().offset(self.vec_deque.tail as isize))
2576+
}
2577+
}
2578+
24452579
#[cfg(test)]
24462580
mod tests {
24472581
use test;
@@ -2797,4 +2931,5 @@ mod tests {
27972931
}
27982932
}
27992933
}
2934+
28002935
}

src/libcollectionstest/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
extern crate collections;
3333
extern crate test;
3434
extern crate std_unicode;
35+
extern crate core;
3536

3637
use std::hash::{Hash, Hasher};
3738
use std::collections::hash_map::DefaultHasher;

src/libcollectionstest/vec_deque.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use std::collections::VecDeque;
1212
use std::fmt::Debug;
13-
use std::collections::vec_deque::Drain;
13+
use std::collections::vec_deque::{Drain};
1414

1515
use self::Taggy::*;
1616
use self::Taggypar::*;
@@ -1000,3 +1000,25 @@ fn test_is_empty() {
10001000
assert!(v.iter_mut().is_empty());
10011001
assert!(v.into_iter().is_empty());
10021002
}
1003+
1004+
#[test]
1005+
fn test_placement_in() {
1006+
let mut buf: VecDeque<isize> = VecDeque::new();
1007+
buf.place_back() <- 1;
1008+
buf.place_back() <- 2;
1009+
assert_eq!(buf, [1,2]);
1010+
1011+
buf.place_front() <- 3;
1012+
buf.place_front() <- 4;
1013+
assert_eq!(buf, [4,3,1,2]);
1014+
1015+
{
1016+
let ptr_head = buf.place_front() <- 5;
1017+
assert_eq!(*ptr_head, 5);
1018+
}
1019+
{
1020+
let ptr_tail = buf.place_back() <- 6;
1021+
assert_eq!(*ptr_tail, 6);
1022+
}
1023+
assert_eq!(buf, [5,4,3,1,2,6]);
1024+
}

0 commit comments

Comments
 (0)