@@ -211,64 +211,6 @@ impl<T, A: AllocRef> RawVec<T, A> {
211
211
}
212
212
}
213
213
214
- /// Doubles the size of the type's backing allocation. This is common enough
215
- /// to want to do that it's easiest to just have a dedicated method. Slightly
216
- /// more efficient logic can be provided for this than the general case.
217
- ///
218
- /// This function is ideal for when pushing elements one-at-a-time because
219
- /// you don't need to incur the costs of the more general computations
220
- /// reserve needs to do to guard against overflow. You do however need to
221
- /// manually check if your `len == capacity`.
222
- ///
223
- /// # Panics
224
- ///
225
- /// * Panics if `T` is zero-sized on the assumption that you managed to exhaust
226
- /// all `usize::MAX` slots in your imaginary buffer.
227
- /// * Panics on 32-bit platforms if the requested capacity exceeds
228
- /// `isize::MAX` bytes.
229
- ///
230
- /// # Aborts
231
- ///
232
- /// Aborts on OOM
233
- ///
234
- /// # Examples
235
- ///
236
- /// ```
237
- /// # #![feature(raw_vec_internals)]
238
- /// # extern crate alloc;
239
- /// # use std::ptr;
240
- /// # use alloc::raw_vec::RawVec;
241
- /// struct MyVec<T> {
242
- /// buf: RawVec<T>,
243
- /// len: usize,
244
- /// }
245
- ///
246
- /// impl<T> MyVec<T> {
247
- /// pub fn push(&mut self, elem: T) {
248
- /// if self.len == self.buf.capacity() { self.buf.double(); }
249
- /// // double would have aborted or panicked if the len exceeded
250
- /// // `isize::MAX` so this is safe to do unchecked now.
251
- /// unsafe {
252
- /// ptr::write(self.buf.ptr().add(self.len), elem);
253
- /// }
254
- /// self.len += 1;
255
- /// }
256
- /// }
257
- /// # fn main() {
258
- /// # let mut vec = MyVec { buf: RawVec::new(), len: 0 };
259
- /// # vec.push(1);
260
- /// # }
261
- /// ```
262
- #[ inline( never) ]
263
- #[ cold]
264
- pub fn double ( & mut self ) {
265
- match self . grow ( Double , MayMove , Uninitialized ) {
266
- Err ( CapacityOverflow ) => capacity_overflow ( ) ,
267
- Err ( AllocError { layout, .. } ) => handle_alloc_error ( layout) ,
268
- Ok ( ( ) ) => { /* yay */ }
269
- }
270
- }
271
-
272
214
/// Ensures that the buffer contains at least enough space to hold
273
215
/// `used_capacity + needed_extra_capacity` elements. If it doesn't already have
274
216
/// enough capacity, will reallocate enough space plus comfortable slack
@@ -336,7 +278,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
336
278
needed_extra_capacity : usize ,
337
279
) -> Result < ( ) , TryReserveError > {
338
280
if self . needs_to_grow ( used_capacity, needed_extra_capacity) {
339
- self . grow ( Amortized { used_capacity, needed_extra_capacity } , MayMove , Uninitialized )
281
+ self . grow ( Amortized , used_capacity, needed_extra_capacity, MayMove , Uninitialized )
340
282
} else {
341
283
Ok ( ( ) )
342
284
}
@@ -363,7 +305,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
363
305
// This is more readable than putting this in one line:
364
306
// `!self.needs_to_grow(...) || self.grow(...).is_ok()`
365
307
if self . needs_to_grow ( used_capacity, needed_extra_capacity) {
366
- self . grow ( Amortized { used_capacity, needed_extra_capacity } , InPlace , Uninitialized )
308
+ self . grow ( Amortized , used_capacity, needed_extra_capacity, InPlace , Uninitialized )
367
309
. is_ok ( )
368
310
} else {
369
311
true
@@ -405,7 +347,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
405
347
needed_extra_capacity : usize ,
406
348
) -> Result < ( ) , TryReserveError > {
407
349
if self . needs_to_grow ( used_capacity, needed_extra_capacity) {
408
- self . grow ( Exact { used_capacity, needed_extra_capacity } , MayMove , Uninitialized )
350
+ self . grow ( Exact , used_capacity, needed_extra_capacity, MayMove , Uninitialized )
409
351
} else {
410
352
Ok ( ( ) )
411
353
}
@@ -432,9 +374,8 @@ impl<T, A: AllocRef> RawVec<T, A> {
432
374
433
375
#[ derive( Copy , Clone ) ]
434
376
enum Strategy {
435
- Double ,
436
- Amortized { used_capacity : usize , needed_extra_capacity : usize } ,
437
- Exact { used_capacity : usize , needed_extra_capacity : usize } ,
377
+ Amortized ,
378
+ Exact ,
438
379
}
439
380
use Strategy :: * ;
440
381
@@ -459,6 +400,8 @@ impl<T, A: AllocRef> RawVec<T, A> {
459
400
fn grow (
460
401
& mut self ,
461
402
strategy : Strategy ,
403
+ used_capacity : usize ,
404
+ needed_extra_capacity : usize ,
462
405
placement : ReallocPlacement ,
463
406
init : AllocInit ,
464
407
) -> Result < ( ) , TryReserveError > {
@@ -469,23 +412,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
469
412
return Err ( CapacityOverflow ) ;
470
413
}
471
414
let new_layout = match strategy {
472
- Double => unsafe {
473
- // Since we guarantee that we never allocate more than `isize::MAX` bytes,
474
- // `elem_size * self.cap <= isize::MAX` as a precondition, so this can't overflow.
475
- // Additionally the alignment will never be too large as to "not be satisfiable",
476
- // so `Layout::from_size_align` will always return `Some`.
477
- //
478
- // TL;DR, we bypass runtime checks due to dynamic assertions in this module,
479
- // allowing us to use `from_size_align_unchecked`.
480
- let cap = if self . cap == 0 {
481
- // Skip to 4 because tiny `Vec`'s are dumb; but not if that would cause overflow.
482
- if elem_size > usize:: MAX / 8 { 1 } else { 4 }
483
- } else {
484
- self . cap * 2
485
- } ;
486
- Layout :: from_size_align_unchecked ( cap * elem_size, mem:: align_of :: < T > ( ) )
487
- } ,
488
- Amortized { used_capacity, needed_extra_capacity } => {
415
+ Amortized => {
489
416
// Nothing we can really do about these checks, sadly.
490
417
let required_cap =
491
418
used_capacity. checked_add ( needed_extra_capacity) . ok_or ( CapacityOverflow ) ?;
@@ -495,7 +422,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
495
422
let cap = cmp:: max ( double_cap, required_cap) ;
496
423
Layout :: array :: < T > ( cap) . map_err ( |_| CapacityOverflow ) ?
497
424
}
498
- Exact { used_capacity , needed_extra_capacity } => {
425
+ Exact => {
499
426
let cap =
500
427
used_capacity. checked_add ( needed_extra_capacity) . ok_or ( CapacityOverflow ) ?;
501
428
Layout :: array :: < T > ( cap) . map_err ( |_| CapacityOverflow ) ?
0 commit comments