@@ -211,64 +211,6 @@ impl<T, A: AllocRef> RawVec<T, A> {
211211 }
212212 }
213213
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-
272214 /// Ensures that the buffer contains at least enough space to hold
273215 /// `used_capacity + needed_extra_capacity` elements. If it doesn't already have
274216 /// enough capacity, will reallocate enough space plus comfortable slack
@@ -336,7 +278,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
336278 needed_extra_capacity : usize ,
337279 ) -> Result < ( ) , TryReserveError > {
338280 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 )
340282 } else {
341283 Ok ( ( ) )
342284 }
@@ -363,7 +305,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
363305 // This is more readable than putting this in one line:
364306 // `!self.needs_to_grow(...) || self.grow(...).is_ok()`
365307 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 )
367309 . is_ok ( )
368310 } else {
369311 true
@@ -405,7 +347,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
405347 needed_extra_capacity : usize ,
406348 ) -> Result < ( ) , TryReserveError > {
407349 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 )
409351 } else {
410352 Ok ( ( ) )
411353 }
@@ -432,9 +374,8 @@ impl<T, A: AllocRef> RawVec<T, A> {
432374
433375#[ derive( Copy , Clone ) ]
434376enum 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 ,
438379}
439380use Strategy :: * ;
440381
@@ -459,6 +400,8 @@ impl<T, A: AllocRef> RawVec<T, A> {
459400 fn grow (
460401 & mut self ,
461402 strategy : Strategy ,
403+ used_capacity : usize ,
404+ needed_extra_capacity : usize ,
462405 placement : ReallocPlacement ,
463406 init : AllocInit ,
464407 ) -> Result < ( ) , TryReserveError > {
@@ -469,23 +412,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
469412 return Err ( CapacityOverflow ) ;
470413 }
471414 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 => {
489416 // Nothing we can really do about these checks, sadly.
490417 let required_cap =
491418 used_capacity. checked_add ( needed_extra_capacity) . ok_or ( CapacityOverflow ) ?;
@@ -495,7 +422,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
495422 let cap = cmp:: max ( double_cap, required_cap) ;
496423 Layout :: array :: < T > ( cap) . map_err ( |_| CapacityOverflow ) ?
497424 }
498- Exact { used_capacity , needed_extra_capacity } => {
425+ Exact => {
499426 let cap =
500427 used_capacity. checked_add ( needed_extra_capacity) . ok_or ( CapacityOverflow ) ?;
501428 Layout :: array :: < T > ( cap) . map_err ( |_| CapacityOverflow ) ?
0 commit comments