@@ -1191,6 +1191,73 @@ impl<T, A: Allocator> VecDeque<T, A> {
1191
1191
}
1192
1192
}
1193
1193
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
+
1194
1261
/// Returns a reference to the underlying allocator.
1195
1262
#[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1196
1263
#[ inline]
0 commit comments