@@ -22,7 +22,7 @@ use core::cmp::Ordering;
22
22
use core:: fmt;
23
23
use core:: iter:: { repeat, FromIterator , FusedIterator } ;
24
24
use core:: mem;
25
- use core:: ops:: { Index , IndexMut } ;
25
+ use core:: ops:: { Index , IndexMut , Place , Placer , InPlace } ;
26
26
use core:: ptr;
27
27
use core:: ptr:: Shared ;
28
28
use core:: slice;
@@ -1087,14 +1087,7 @@ impl<T> VecDeque<T> {
1087
1087
/// ```
1088
1088
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1089
1089
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 ( ) ;
1098
1091
1099
1092
self . tail = self . wrap_sub ( self . tail , 1 ) ;
1100
1093
let tail = self . tail ;
@@ -1117,14 +1110,7 @@ impl<T> VecDeque<T> {
1117
1110
/// ```
1118
1111
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1119
1112
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 ( ) ;
1128
1114
1129
1115
let head = self . head ;
1130
1116
self . head = self . wrap_add ( self . head , 1 ) ;
@@ -1257,14 +1243,7 @@ impl<T> VecDeque<T> {
1257
1243
#[ stable( feature = "deque_extras_15" , since = "1.5.0" ) ]
1258
1244
pub fn insert ( & mut self , index : usize , value : T ) {
1259
1245
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 ( ) ;
1268
1247
1269
1248
// Move the least number of elements in the ring buffer and insert
1270
1249
// the given object
@@ -1762,6 +1741,69 @@ impl<T> VecDeque<T> {
1762
1741
self . truncate ( len - del) ;
1763
1742
}
1764
1743
}
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
+ }
1765
1807
}
1766
1808
1767
1809
impl < T : Clone > VecDeque < T > {
@@ -2442,6 +2484,98 @@ impl<T> From<VecDeque<T>> for Vec<T> {
2442
2484
}
2443
2485
}
2444
2486
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
+
2445
2579
#[ cfg( test) ]
2446
2580
mod tests {
2447
2581
use test;
@@ -2797,4 +2931,5 @@ mod tests {
2797
2931
}
2798
2932
}
2799
2933
}
2934
+
2800
2935
}
0 commit comments