@@ -20,7 +20,7 @@ use crate::collections::TryReserveError::{self, *};
20
20
#[ cfg( test) ]
21
21
mod tests;
22
22
23
- #[ cfg ( not ( no_global_oom_handling ) ) ]
23
+ #[ allow ( dead_code ) ]
24
24
enum AllocInit {
25
25
/// The contents of the new memory are uninitialized.
26
26
Uninitialized ,
@@ -93,6 +93,16 @@ impl<T> RawVec<T, Global> {
93
93
Self :: with_capacity_in ( capacity, Global )
94
94
}
95
95
96
+ /// Tries to create a `RawVec` (on the system heap) with exactly the
97
+ /// capacity and alignment requirements for a `[T; capacity]`. This is
98
+ /// equivalent to calling `RawVec::new` when `capacity` is `0` or `T` is
99
+ /// zero-sized. Note that if `T` is zero-sized this means you will
100
+ /// *not* get a `RawVec` with the requested capacity.
101
+ #[ inline]
102
+ pub fn try_with_capacity ( capacity : usize ) -> Result < Self , TryReserveError > {
103
+ Self :: try_with_capacity_in ( capacity, Global )
104
+ }
105
+
96
106
/// Like `with_capacity`, but guarantees the buffer is zeroed.
97
107
#[ cfg( not( no_global_oom_handling) ) ]
98
108
#[ inline]
@@ -144,6 +154,13 @@ impl<T, A: Allocator> RawVec<T, A> {
144
154
Self :: allocate_in ( capacity, AllocInit :: Uninitialized , alloc)
145
155
}
146
156
157
+ /// Like `try_with_capacity`, but parameterized over the choice of
158
+ /// allocator for the returned `RawVec`.
159
+ #[ inline]
160
+ pub fn try_with_capacity_in ( capacity : usize , alloc : A ) -> Result < Self , TryReserveError > {
161
+ Self :: try_allocate_in ( capacity, AllocInit :: Uninitialized , alloc)
162
+ }
163
+
147
164
/// Like `with_capacity_zeroed`, but parameterized over the choice
148
165
/// of allocator for the returned `RawVec`.
149
166
#[ cfg( not( no_global_oom_handling) ) ]
@@ -218,6 +235,29 @@ impl<T, A: Allocator> RawVec<T, A> {
218
235
}
219
236
}
220
237
238
+ fn try_allocate_in ( capacity : usize , init : AllocInit , alloc : A ) -> Result < Self , TryReserveError > {
239
+ if mem:: size_of :: < T > ( ) == 0 {
240
+ return Ok ( Self :: new_in ( alloc) ) ;
241
+ }
242
+
243
+ let layout = Layout :: array :: < T > ( capacity) ?;
244
+ alloc_guard ( layout. size ( ) ) ?;
245
+ let result = match init {
246
+ AllocInit :: Uninitialized => alloc. allocate ( layout) ,
247
+ AllocInit :: Zeroed => alloc. allocate_zeroed ( layout) ,
248
+ } ;
249
+ let ptr = match result {
250
+ Ok ( ptr) => ptr,
251
+ Err ( _) => return Err ( TryReserveError :: AllocError { layout, non_exhaustive : ( ) } ) ,
252
+ } ;
253
+
254
+ Ok ( Self {
255
+ ptr : unsafe { Unique :: new_unchecked ( ptr. cast ( ) . as_ptr ( ) ) } ,
256
+ cap : Self :: capacity_from_bytes ( ptr. len ( ) ) ,
257
+ alloc,
258
+ } )
259
+ }
260
+
221
261
/// Reconstitutes a `RawVec` from a pointer, capacity, and allocator.
222
262
///
223
263
/// # Safety
@@ -394,6 +434,16 @@ impl<T, A: Allocator> RawVec<T, A> {
394
434
pub fn shrink_to_fit ( & mut self , amount : usize ) {
395
435
handle_reserve ( self . shrink ( amount) ) ;
396
436
}
437
+
438
+ /// Tries to shrink the allocation down to the specified amount. If the given amount
439
+ /// is 0, actually completely deallocates.
440
+ ///
441
+ /// # Panics
442
+ ///
443
+ /// Panics if the given amount is *larger* than the current capacity.
444
+ pub fn try_shrink_to_fit ( & mut self , amount : usize ) -> Result < ( ) , TryReserveError > {
445
+ self . shrink ( amount)
446
+ }
397
447
}
398
448
399
449
impl < T , A : Allocator > RawVec < T , A > {
@@ -465,7 +515,7 @@ impl<T, A: Allocator> RawVec<T, A> {
465
515
Ok ( ( ) )
466
516
}
467
517
468
- #[ cfg( not( no_global_oom_handling) ) ]
518
+ // TODO: Why this was marked as ` #[cfg(not(no_global_oom_handling))]`?
469
519
fn shrink ( & mut self , amount : usize ) -> Result < ( ) , TryReserveError > {
470
520
assert ! ( amount <= self . capacity( ) , "Tried to shrink to a larger capacity" ) ;
471
521
0 commit comments