@@ -77,7 +77,7 @@ use core::hash::{self, Hash};
7777use core:: intrinsics:: { arith_offset, assume} ;
7878use core:: iter:: { FromIterator , FusedIterator , TrustedLen } ;
7979use core:: mem;
80- use core:: ops:: { Index , IndexMut } ;
80+ use core:: ops:: { InPlace , Index , IndexMut , Place , Placer } ;
8181use core:: ops;
8282use core:: ptr;
8383use core:: ptr:: Shared ;
@@ -1246,6 +1246,29 @@ impl<T: Clone> Vec<T> {
12461246 pub fn extend_from_slice ( & mut self , other : & [ T ] ) {
12471247 self . spec_extend ( other. iter ( ) )
12481248 }
1249+
1250+ /// Returns a place for insertion at the back of the `Vec`.
1251+ ///
1252+ /// Using this method with placement syntax is equivalent to [`push`](#method.push),
1253+ /// but may be more efficient.
1254+ ///
1255+ /// # Examples
1256+ ///
1257+ /// ```
1258+ /// #![feature(collection_placement)]
1259+ /// #![feature(placement_in_syntax)]
1260+ ///
1261+ /// let mut vec = vec![1, 2];
1262+ /// vec.place_back() <- 3;
1263+ /// vec.place_back() <- 4;
1264+ /// assert_eq!(&vec, &[1, 2, 3, 4]);
1265+ /// ```
1266+ #[ unstable( feature = "collection_placement" ,
1267+ reason = "placement protocol is subject to change" ,
1268+ issue = "30172" ) ]
1269+ pub fn place_back ( & mut self ) -> PlaceBack < T > {
1270+ PlaceBack { vec : self }
1271+ }
12491272}
12501273
12511274// Set the length of the vec when the `SetLenOnDrop` value goes out of scope.
@@ -2119,3 +2142,52 @@ impl<'a, T> ExactSizeIterator for Drain<'a, T> {
21192142
21202143#[ unstable( feature = "fused" , issue = "35602" ) ]
21212144impl < ' a , T > FusedIterator for Drain < ' a , T > { }
2145+
2146+ /// A place for insertion at the back of a `Vec`.
2147+ ///
2148+ /// See [`Vec::place_back`](struct.Vec.html#method.place_back) for details.
2149+ #[ must_use = "places do nothing unless written to with `<-` syntax" ]
2150+ #[ unstable( feature = "collection_placement" ,
2151+ reason = "struct name and placement protocol are subject to change" ,
2152+ issue = "30172" ) ]
2153+ pub struct PlaceBack < ' a , T : ' a > {
2154+ vec : & ' a mut Vec < T > ,
2155+ }
2156+
2157+ #[ unstable( feature = "collection_placement" ,
2158+ reason = "placement protocol is subject to change" ,
2159+ issue = "30172" ) ]
2160+ impl < ' a , T > Placer < T > for PlaceBack < ' a , T > {
2161+ type Place = PlaceBack < ' a , T > ;
2162+
2163+ fn make_place ( self ) -> Self {
2164+ // This will panic or abort if we would allocate > isize::MAX bytes
2165+ // or if the length increment would overflow for zero-sized types.
2166+ if self . vec . len == self . vec . buf . cap ( ) {
2167+ self . vec . buf . double ( ) ;
2168+ }
2169+ self
2170+ }
2171+ }
2172+
2173+ #[ unstable( feature = "collection_placement" ,
2174+ reason = "placement protocol is subject to change" ,
2175+ issue = "30172" ) ]
2176+ impl < ' a , T > Place < T > for PlaceBack < ' a , T > {
2177+ fn pointer ( & mut self ) -> * mut T {
2178+ unsafe { self . vec . as_mut_ptr ( ) . offset ( self . vec . len as isize ) }
2179+ }
2180+ }
2181+
2182+ #[ unstable( feature = "collection_placement" ,
2183+ reason = "placement protocol is subject to change" ,
2184+ issue = "30172" ) ]
2185+ impl < ' a , T > InPlace < T > for PlaceBack < ' a , T > {
2186+ type Owner = & ' a mut T ;
2187+
2188+ unsafe fn finalize ( mut self ) -> & ' a mut T {
2189+ let ptr = self . pointer ( ) ;
2190+ self . vec . len += 1 ;
2191+ & mut * ptr
2192+ }
2193+ }
0 commit comments