lkml.org 
[lkml]   [2022]   [Dec]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 12/28] rust: alloc: add `RawVec::try_with_capacity_in()` constructor
    Date
    From: Miguel Ojeda <ojeda@kernel.org>

    Add the `RawVec::try_with_capacity_in()` constructor as the fallible
    version of `RawVec::with_capacity_in()`.

    The implementation follows the original.

    The infallible constructor is implemented in terms of the private
    `RawVec::allocate_in()` constructor, thus also add the private
    `RawVec::try_allocate_in()` constructor following the other.

    It will be used to implement `Vec::try_with_capacity{,_in}()` in
    the next patch.

    Reviewed-by: Gary Guo <gary@garyguo.net>
    Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
    ---
    rust/alloc/raw_vec.rs | 34 +++++++++++++++++++++++++++++++++-
    1 file changed, 33 insertions(+), 1 deletion(-)

    diff --git a/rust/alloc/raw_vec.rs b/rust/alloc/raw_vec.rs
    index daf5f2da7168..c342f3843972 100644
    --- a/rust/alloc/raw_vec.rs
    +++ b/rust/alloc/raw_vec.rs
    @@ -20,11 +20,11 @@ use crate::collections::TryReserveErrorKind::*;
    #[cfg(test)]
    mod tests;

    -#[cfg(not(no_global_oom_handling))]
    enum AllocInit {
    /// The contents of the new memory are uninitialized.
    Uninitialized,
    /// The new memory is guaranteed to be zeroed.
    + #[allow(dead_code)]
    Zeroed,
    }

    @@ -133,6 +133,14 @@ impl<T, A: Allocator> RawVec<T, A> {
    Self::allocate_in(capacity, AllocInit::Uninitialized, alloc)
    }

    + /// Like `try_with_capacity`, but parameterized over the choice of
    + /// allocator for the returned `RawVec`.
    + #[allow(dead_code)]
    + #[inline]
    + pub fn try_with_capacity_in(capacity: usize, alloc: A) -> Result<Self, TryReserveError> {
    + Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc)
    + }
    +
    /// Like `with_capacity_zeroed`, but parameterized over the choice
    /// of allocator for the returned `RawVec`.
    #[cfg(not(no_global_oom_handling))]
    @@ -203,6 +211,30 @@ impl<T, A: Allocator> RawVec<T, A> {
    }
    }

    + fn try_allocate_in(capacity: usize, init: AllocInit, alloc: A) -> Result<Self, TryReserveError> {
    + // Don't allocate here because `Drop` will not deallocate when `capacity` is 0.
    + if mem::size_of::<T>() == 0 || capacity == 0 {
    + return Ok(Self::new_in(alloc));
    + }
    +
    + let layout = Layout::array::<T>(capacity).map_err(|_| CapacityOverflow)?;
    + alloc_guard(layout.size())?;
    + let result = match init {
    + AllocInit::Uninitialized => alloc.allocate(layout),
    + AllocInit::Zeroed => alloc.allocate_zeroed(layout),
    + };
    + let ptr = result.map_err(|_| AllocError { layout, non_exhaustive: () })?;
    +
    + // Allocators currently return a `NonNull<[u8]>` whose length
    + // matches the size requested. If that ever changes, the capacity
    + // here should change to `ptr.len() / mem::size_of::<T>()`.
    + Ok(Self {
    + ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) },
    + cap: capacity,
    + alloc,
    + })
    + }
    +
    /// Reconstitutes a `RawVec` from a pointer, capacity, and allocator.
    ///
    /// # Safety
    --
    2.38.1
    \
     
     \ /
      Last update: 2022-12-02 17:19    [W:4.306 / U:0.092 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site