@@ -1191,6 +1191,73 @@ impl<T, A: Allocator> VecDeque<T, A> {
11911191 }
11921192 }
11931193
1194+ /// Shortens the deque, keeping the last `len` elements and dropping
1195+ /// the rest.
1196+ ///
1197+ /// If `len` is greater or equal to the deque's current length, this has
1198+ /// no effect.
1199+ ///
1200+ /// # Examples
1201+ ///
1202+ /// ```
1203+ /// # #![feature(vec_deque_truncate_front)]
1204+ /// use std::collections::VecDeque;
1205+ ///
1206+ /// let mut buf = VecDeque::new();
1207+ /// buf.push_front(5);
1208+ /// buf.push_front(10);
1209+ /// buf.push_front(15);
1210+ /// assert_eq!(buf, [15, 10, 5]);
1211+ /// assert_eq!(buf.as_slices(), (&[15, 10, 5][..], &[][..]));
1212+ /// buf.truncate_front(1);
1213+ /// assert_eq!(buf.as_slices(), (&[5][..], &[][..]));
1214+ /// ```
1215+ #[ unstable( feature = "vec_deque_truncate_front" , issue = "140667" ) ]
1216+ pub fn truncate_front ( & mut self , len : usize ) {
1217+ /// Runs the destructor for all items in the slice when it gets dropped (normally or
1218+ /// during unwinding).
1219+ struct Dropper < ' a , T > ( & ' a mut [ T ] ) ;
1220+
1221+ impl < ' a , T > Drop for Dropper < ' a , T > {
1222+ fn drop ( & mut self ) {
1223+ unsafe {
1224+ ptr:: drop_in_place ( self . 0 ) ;
1225+ }
1226+ }
1227+ }
1228+
1229+ unsafe {
1230+ if len >= self . len {
1231+ // No action is taken
1232+ return ;
1233+ }
1234+
1235+ let ( front, back) = self . as_mut_slices ( ) ;
1236+ if len > back. len ( ) {
1237+ // The 'back' slice remains unchanged.
1238+ // front.len() + back.len() == self.len, so 'end' is non-negative
1239+ // and end < front.len()
1240+ let end = front. len ( ) - ( len - back. len ( ) ) ;
1241+ let drop_front = front. get_unchecked_mut ( ..end) as * mut _ ;
1242+ self . head += end;
1243+ self . len = len;
1244+ ptr:: drop_in_place ( drop_front) ;
1245+ } else {
1246+ let drop_front = front as * mut _ ;
1247+ // 'end' is non-negative by the condition above
1248+ let end = back. len ( ) - len;
1249+ let drop_back = back. get_unchecked_mut ( ..end) as * mut _ ;
1250+ self . head = self . to_physical_idx ( self . len - len) ;
1251+ self . len = len;
1252+
1253+ // Make sure the second half is dropped even when a destructor
1254+ // in the first one panics.
1255+ let _back_dropper = Dropper ( & mut * drop_back) ;
1256+ ptr:: drop_in_place ( drop_front) ;
1257+ }
1258+ }
1259+ }
1260+
11941261 /// Returns a reference to the underlying allocator.
11951262 #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
11961263 #[ inline]
0 commit comments