Add fallible box allocator APIs (Box::try_new_*_in()
)
This commit is contained in:
parent
353f3a3846
commit
d116f48788
1 changed files with 85 additions and 1 deletions
|
@ -153,7 +153,7 @@ use core::pin::Pin;
|
||||||
use core::ptr::{self, Unique};
|
use core::ptr::{self, Unique};
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
|
||||||
use crate::alloc::{handle_alloc_error, Allocator, Global, Layout};
|
use crate::alloc::{handle_alloc_error, AllocError, Allocator, Global, Layout};
|
||||||
use crate::borrow::Cow;
|
use crate::borrow::Cow;
|
||||||
use crate::raw_vec::RawVec;
|
use crate::raw_vec::RawVec;
|
||||||
use crate::str::from_boxed_utf8_unchecked;
|
use crate::str::from_boxed_utf8_unchecked;
|
||||||
|
@ -267,6 +267,31 @@ impl<T, A: Allocator> Box<T, A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocates memory in the given allocator then places `x` into it,
|
||||||
|
/// returning an error if the allocation fails
|
||||||
|
///
|
||||||
|
/// This doesn't actually allocate if `T` is zero-sized.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(allocator_api)]
|
||||||
|
///
|
||||||
|
/// use std::alloc::System;
|
||||||
|
///
|
||||||
|
/// let five = Box::try_new_in(5, System)?;
|
||||||
|
/// # Ok::<(), std::alloc::AllocError>(())
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
|
#[inline]
|
||||||
|
pub fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError> {
|
||||||
|
let mut boxed = Self::try_new_uninit_in(alloc)?;
|
||||||
|
unsafe {
|
||||||
|
boxed.as_mut_ptr().write(x);
|
||||||
|
Ok(boxed.assume_init())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Constructs a new box with uninitialized contents in the provided allocator.
|
/// Constructs a new box with uninitialized contents in the provided allocator.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -295,6 +320,36 @@ impl<T, A: Allocator> Box<T, A> {
|
||||||
unsafe { Box::from_raw_in(ptr.as_ptr(), alloc) }
|
unsafe { Box::from_raw_in(ptr.as_ptr(), alloc) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs a new box with uninitialized contents in the provided allocator,
|
||||||
|
/// returning an error if the allocation fails
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(allocator_api, new_uninit)]
|
||||||
|
///
|
||||||
|
/// use std::alloc::System;
|
||||||
|
///
|
||||||
|
/// let mut five = Box::<u32, _>::try_new_uninit_in(System)?;
|
||||||
|
///
|
||||||
|
/// let five = unsafe {
|
||||||
|
/// // Deferred initialization:
|
||||||
|
/// five.as_mut_ptr().write(5);
|
||||||
|
///
|
||||||
|
/// five.assume_init()
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// assert_eq!(*five, 5);
|
||||||
|
/// # Ok::<(), std::alloc::AllocError>(())
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
|
// #[unstable(feature = "new_uninit", issue = "63291")]
|
||||||
|
pub fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> {
|
||||||
|
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
||||||
|
let ptr = alloc.allocate(layout)?.cast();
|
||||||
|
unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Constructs a new `Box` with uninitialized contents, with the memory
|
/// Constructs a new `Box` with uninitialized contents, with the memory
|
||||||
/// being filled with `0` bytes in the provided allocator.
|
/// being filled with `0` bytes in the provided allocator.
|
||||||
///
|
///
|
||||||
|
@ -324,6 +379,35 @@ impl<T, A: Allocator> Box<T, A> {
|
||||||
unsafe { Box::from_raw_in(ptr.as_ptr(), alloc) }
|
unsafe { Box::from_raw_in(ptr.as_ptr(), alloc) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs a new `Box` with uninitialized contents, with the memory
|
||||||
|
/// being filled with `0` bytes in the provided allocator.
|
||||||
|
///
|
||||||
|
/// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
|
||||||
|
/// of this method.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(allocator_api, new_uninit)]
|
||||||
|
///
|
||||||
|
/// use std::alloc::System;
|
||||||
|
///
|
||||||
|
/// let zero = Box::<u32, _>::try_new_zeroed_in(System)?;
|
||||||
|
/// let zero = unsafe { zero.assume_init() };
|
||||||
|
///
|
||||||
|
/// assert_eq!(*zero, 0);
|
||||||
|
/// # Ok::<(), std::alloc::AllocError>(())
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [zeroed]: mem::MaybeUninit::zeroed
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
|
// #[unstable(feature = "new_uninit", issue = "63291")]
|
||||||
|
pub fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> {
|
||||||
|
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
||||||
|
let ptr = alloc.allocate_zeroed(layout)?.cast();
|
||||||
|
unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement `Unpin`, then
|
/// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement `Unpin`, then
|
||||||
/// `x` will be pinned in memory and unable to be moved.
|
/// `x` will be pinned in memory and unable to be moved.
|
||||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
|
|
Loading…
Reference in a new issue