@@ -395,37 +395,8 @@ impl<T, A: AllocRef> RawVec<T, A> {
395
395
// of the code that doesn't depend on `T` as possible is in functions that
396
396
// are non-generic over `T`.
397
397
fn grow_amortized ( & mut self , len : usize , additional : usize ) -> Result < ( ) , TryReserveError > {
398
- // This is ensured by the calling contexts.
399
- debug_assert ! ( additional > 0 ) ;
400
-
401
- if mem:: size_of :: < T > ( ) == 0 {
402
- // Since we return a capacity of `usize::MAX` when `elem_size` is
403
- // 0, getting to here necessarily means the `RawVec` is overfull.
404
- return Err ( CapacityOverflow ) ;
405
- }
406
-
407
- // Nothing we can really do about these checks, sadly.
408
- let required_cap = len. checked_add ( additional) . ok_or ( CapacityOverflow ) ?;
409
-
410
- // This guarantees exponential growth. The doubling cannot overflow
411
- // because `cap <= isize::MAX` and the type of `cap` is `usize`.
412
- let cap = cmp:: max ( self . cap * 2 , required_cap) ;
413
-
414
- // Tiny Vecs are dumb. Skip to:
415
- // - 8 if the element size is 1, because any heap allocators is likely
416
- // to round up a request of less than 8 bytes to at least 8 bytes.
417
- // - 4 if elements are moderate-sized (<= 1 KiB).
418
- // - 1 otherwise, to avoid wasting too much space for very short Vecs.
419
- // Note that `min_non_zero_cap` is computed statically.
420
398
let elem_size = mem:: size_of :: < T > ( ) ;
421
- let min_non_zero_cap = if elem_size == 1 {
422
- 8
423
- } else if elem_size <= 1024 {
424
- 4
425
- } else {
426
- 1
427
- } ;
428
- let cap = cmp:: max ( min_non_zero_cap, cap) ;
399
+ let cap = cap_amortized ( elem_size, len, additional, self . cap ) ?;
429
400
430
401
let elem_layout = Layout :: new :: < T > ( ) ;
431
402
@@ -478,6 +449,46 @@ impl<T, A: AllocRef> RawVec<T, A> {
478
449
}
479
450
}
480
451
452
+ // This function is outside `RawVec` to minimize compile times. See the comment
453
+ // above `RawVec::grow_amortized` for details.
454
+ #[ inline]
455
+ fn cap_amortized (
456
+ elem_size : usize ,
457
+ len : usize ,
458
+ additional : usize ,
459
+ curr_cap : usize ,
460
+ ) -> Result < usize , TryReserveError > {
461
+ // This is ensured by the calling contexts.
462
+ debug_assert ! ( additional > 0 ) ;
463
+
464
+ // Tiny Vecs are dumb. Skip to:
465
+ // - 8 if the element size is 1, because any heap allocators is likely
466
+ // to round up a request of less than 8 bytes to at least 8 bytes.
467
+ // - 4 if elements are moderate-sized (<= 1 KiB).
468
+ // - 1 otherwise, to avoid wasting too much space for very short Vecs.
469
+ // Note that `min_non_zero_cap` is computed statically.
470
+ let min_non_zero_cap = if elem_size == 0 {
471
+ // Since we return a capacity of `usize::MAX` when `elem_size` is
472
+ // 0, getting to here necessarily means the `RawVec` is overfull.
473
+ return Err ( CapacityOverflow ) ;
474
+ } else if elem_size == 1 {
475
+ 8
476
+ } else if elem_size <= 1024 {
477
+ 4
478
+ } else {
479
+ 1
480
+ } ;
481
+
482
+ // Nothing we can really do about these checks, sadly.
483
+ let required_cap = len. checked_add ( additional) . ok_or ( CapacityOverflow ) ?;
484
+
485
+ // This guarantees exponential growth. The doubling cannot overflow
486
+ // because `cap <= isize::MAX` and the type of `cap` is `usize`.
487
+ let cap = cmp:: max ( curr_cap * 2 , required_cap) ;
488
+
489
+ Ok ( cmp:: max ( min_non_zero_cap, cap) )
490
+ }
491
+
481
492
// This function is outside `RawVec` to minimize compile times. See the comment
482
493
// above `RawVec::grow_amortized` for details. (The `A` parameter isn't
483
494
// significant, because the number of different `A` types seen in practice is
0 commit comments