pub struct Box<T: ?Sized, A: Allocator = Global> { /* private fields */ }
Expand description
A pointer type that uniquely owns a heap allocation of type T
.
Implementations§
Source§impl<T> Box<T, Global>
impl<T> Box<T, Global>
Sourcepub fn try_new(value: T) -> Result<Self, AllocError>
pub fn try_new(value: T) -> Result<Self, AllocError>
Allocates memory on the heap and then places x
into it.
This doesn’t actually allocate if T
is zero-sized.
§Examples
use rune::alloc::Box;
let five = Box::try_new(5)?;
Sourcepub fn try_pin(x: T) -> Result<Pin<Box<T>>, AllocError>
pub fn try_pin(x: T) -> Result<Pin<Box<T>>, AllocError>
Constructs a new Pin<Box<T>>
. If T
does not implement Unpin
,
then x
will be pinned in memory and unable to be moved.
Constructing and pinning of the Box
can also be done in two steps:
Box::try?pin(x)
does the same as
Box::into_pin([Box::try?new](x))
. Consider using
into_pin
if you already have a Box<T>
, or if you
want to construct a (pinned) Box
in a different way than with
Box::try_new
.
Source§impl<T: ?Sized> Box<T>
impl<T: ?Sized> Box<T>
Sourcepub fn from_std(b: Box<T>) -> Result<Self, Error>
pub fn from_std(b: Box<T>) -> Result<Self, Error>
Convert from a std Box
.
This causes the underlying allocation to be accounted for by the
Global
allocator.
A caveat of this method is that the allocation is already in use, but
this might still be necessary because we want access to certain methods
in std Box
such as the ability to coerce to unsized values.
§Examples
use rune::alloc::{Box, Vec};
use rune::alloc::limit;
use std::boxed::Box as StdBox;
assert_eq!(limit::get(), usize::MAX);
let b: StdBox<dyn Iterator<Item = u32>> = StdBox::new(1..3);
let mut b = Box::from_std(b)?;
assert_eq!(b.next(), Some(1));
assert_eq!(b.next(), Some(2));
assert_eq!(b.next(), None);
assert!(limit::get() < usize::MAX);
drop(b);
assert_eq!(limit::get(), usize::MAX);
Source§impl<T, A: Allocator> Box<T, A>
impl<T, A: Allocator> Box<T, A>
Sourcepub fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError>
pub fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError>
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
use rune::alloc::Box;
use rune::alloc::alloc::Global;
let five = Box::try_new_in(5, Global)?;
Sourcepub fn try_new_uninit_in(alloc: A) -> Result<Box<MaybeUninit<T>, A>, AllocError>where
A: Allocator,
pub fn try_new_uninit_in(alloc: A) -> Result<Box<MaybeUninit<T>, A>, AllocError>where
A: Allocator,
Constructs a new box with uninitialized contents in the provided allocator, returning an error if the allocation fails
§Examples
use rune::alloc::Box;
use rune::alloc::alloc::Global;
let mut five = Box::<u32>::try_new_uninit_in(Global)?;
let five: Box<u32> = unsafe {
// Deferred initialization:
five.as_mut_ptr().write(5);
five.assume_init()
};
assert_eq!(*five, 5);
Sourcepub fn into_inner(boxed: Self) -> T
pub fn into_inner(boxed: Self) -> T
Consumes the Box
, returning the wrapped value.
Source§impl<T: ?Sized, A: Allocator> Box<T, A>
impl<T: ?Sized, A: Allocator> Box<T, A>
Sourcepub fn leak<'a>(b: Self) -> &'a mut Twhere
A: 'a,
pub fn leak<'a>(b: Self) -> &'a mut Twhere
A: 'a,
Consumes and leaks the Box
, returning a mutable reference, &'a mut T
. Note that the type T
must outlive the chosen lifetime 'a
. If the
type has only static references, or none at all, then this may be chosen
to be 'static
.
This function is mainly useful for data that lives for the remainder of
the program’s life. Dropping the returned reference will cause a memory
leak. If this is not acceptable, the reference should first be wrapped
with the Box::from_raw_in
function producing a Box
. This Box
can
then be dropped which will properly destroy T
and release the
allocated memory.
Note: this is an associated function, which means that you have to call
it as Box::leak(b)
instead of b.leak()
. This is so that there is no
conflict with a method on the inner type.
§Examples
Simple usage:
use rune::alloc::Box;
let x = Box::try_new(41)?;
let static_ref: &'static mut usize = Box::leak(x);
*static_ref += 1;
assert_eq!(*static_ref, 42);
Unsized data:
use rune::alloc::{try_vec, Box};
let x = try_vec![1, 2, 3].try_into_boxed_slice()?;
let static_ref = Box::leak(x);
static_ref[0] = 4;
assert_eq!(*static_ref, [4, 2, 3]);
Sourcepub fn into_pin(boxed: Self) -> Pin<Self>where
A: 'static,
pub fn into_pin(boxed: Self) -> Pin<Self>where
A: 'static,
Converts a Box<T>
into a Pin<Box<T>>
. If T
does not implement Unpin
, then
*boxed
will be pinned in memory and unable to be moved.
This conversion does not allocate on the heap and happens in place.
This is also available via From
.
Constructing and pinning a Box
with Box::into_pin([Box::try?new](x))
can also be written more concisely using [Box::try?pin](x)
.
This into_pin
method is useful if you already have a Box<T>
, or you are
constructing a (pinned) Box
in a different way than with Box::try_new
.
§Notes
It’s not recommended that crates add an impl like From<Box<T>> for Pin<T>
,
as it’ll introduce an ambiguity when calling Pin::from
.
A demonstration of such a poor impl is shown below.
use rune::alloc::Box;
struct Foo; // A type defined in this crate.
impl From<Box<()>> for Pin<Foo> {
fn from(_: Box<()>) -> Pin<Foo> {
Pin::new(Foo)
}
}
let foo = Box::try_new(())?;
let bar = Pin::from(foo);
Sourcepub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self
pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self
Constructs a box from a raw pointer in the given allocator.
After calling this function, the raw pointer is owned by the resulting
Box
. Specifically, the Box
destructor will call the destructor of
T
and free the allocated memory. For this to be safe, the memory must
have been allocated in accordance with the memory layout used by Box
.
§Safety
This function is unsafe because improper use may lead to memory problems. For example, a double-free may occur if the function is called twice on the same raw pointer.
§Examples
Recreate a Box
which was previously converted to a raw pointer using
Box::into_raw_with_allocator
:
use rune::alloc::Box;
use rune::alloc::alloc::Global;
let x = Box::try_new_in(5, Global)?;
let (ptr, alloc) = Box::into_raw_with_allocator(x);
let x = unsafe { Box::from_raw_in(ptr, alloc) };
Manually create a Box
from scratch by using the system allocator:
use core::alloc::Layout;
use rune::alloc::Box;
use rune::alloc::alloc::{Allocator, Global};
unsafe {
let ptr = Global.allocate(Layout::new::<i32>())?.as_ptr() as *mut i32;
// In general .write is required to avoid attempting to destruct
// the (uninitialized) previous contents of `ptr`, though for this
// simple example `*ptr = 5` would have worked as well.
ptr.write(5);
let x = Box::from_raw_in(ptr, Global);
}
Sourcepub fn into_raw_with_allocator(b: Self) -> (*mut T, A)
pub fn into_raw_with_allocator(b: Self) -> (*mut T, A)
Consumes the Box
, returning a wrapped raw pointer and the allocator.
The pointer will be properly aligned and non-null.
After calling this function, the caller is responsible for the
memory previously managed by the Box
. In particular, the
caller should properly destroy T
and release the memory, taking
into account the memory layout used by Box
. The easiest way to
do this is to convert the raw pointer back into a Box
with the
Box::from_raw_in
function, allowing the Box
destructor to perform
the cleanup.
Note: this is an associated function, which means that you have
to call it as Box::into_raw_with_allocator(b)
instead of b.into_raw_with_allocator()
. This
is so that there is no conflict with a method on the inner type.
§Examples
Converting the raw pointer back into a Box
with Box::from_raw_in
for automatic cleanup:
use rune::alloc::{Box, String};
use rune::alloc::alloc::Global;
let x = Box::try_new_in(String::try_from("Hello")?, Global)?;
let (ptr, alloc) = Box::into_raw_with_allocator(x);
let x = unsafe { Box::from_raw_in(ptr, alloc) };
Manual cleanup by explicitly running the destructor and deallocating the memory:
use core::alloc::Layout;
use core::ptr::{self, NonNull};
use rune::alloc::{Box, String};
use rune::alloc::alloc::{Allocator, Global};
let x = Box::try_new_in(String::try_from("Hello")?, Global)?;
let (ptr, alloc) = Box::into_raw_with_allocator(x);
unsafe {
ptr::drop_in_place(ptr);
let non_null = NonNull::new_unchecked(ptr);
alloc.deallocate(non_null.cast(), Layout::new::<String>());
}
Source§impl<T, A: Allocator> Box<MaybeUninit<T>, A>
impl<T, A: Allocator> Box<MaybeUninit<T>, A>
Sourcepub unsafe fn assume_init(self) -> Box<T, A>
pub unsafe fn assume_init(self) -> Box<T, A>
Converts to Box<T, A>
.
§Safety
As with MaybeUninit::assume_init
,
it is up to the caller to guarantee that the value
really is in an initialized state.
Calling this when the content is not yet fully initialized
causes immediate undefined behavior.
§Examples
use rune::alloc::Box;
use rune::alloc::alloc::Global;
let mut five = Box::<u32>::try_new_uninit_in(Global)?;
let five: Box<u32> = unsafe {
// Deferred initialization:
five.as_mut_ptr().write(5);
five.assume_init()
};
assert_eq!(*five, 5);
Source§impl<T, A: Allocator> Box<[T], A>
impl<T, A: Allocator> Box<[T], A>
Sourcepub fn try_new_uninit_slice_in(
len: usize,
alloc: A,
) -> Result<Box<[MaybeUninit<T>], A>, Error>
pub fn try_new_uninit_slice_in( len: usize, alloc: A, ) -> Result<Box<[MaybeUninit<T>], A>, Error>
Constructs a new boxed slice with uninitialized contents. Returns an error if the allocation fails
§Examples
use rune::alloc::Box;
use rune::alloc::alloc::Global;
let mut values = Box::<[u32]>::try_new_uninit_slice_in(3, Global)?;
let values = unsafe {
// Deferred initialization:
values[0].as_mut_ptr().write(1);
values[1].as_mut_ptr().write(2);
values[2].as_mut_ptr().write(3);
values.assume_init()
};
assert_eq!(*values, [1, 2, 3]);
Source§impl<T, A: Allocator> Box<[MaybeUninit<T>], A>
impl<T, A: Allocator> Box<[MaybeUninit<T>], A>
Sourcepub unsafe fn assume_init(self) -> Box<[T], A>
pub unsafe fn assume_init(self) -> Box<[T], A>
Converts to Box<[T], A>
.
§Safety
As with MaybeUninit::assume_init
,
it is up to the caller to guarantee that the values
really are in an initialized state.
Calling this when the content is not yet fully initialized
causes immediate undefined behavior.
§Examples
use rune::alloc::Box;
use rune::alloc::alloc::Global;
let mut values = Box::<[u32]>::try_new_uninit_slice_in(3, Global)?;
let values = unsafe {
// Deferred initialization:
values[0].as_mut_ptr().write(1);
values[1].as_mut_ptr().write(2);
values[2].as_mut_ptr().write(3);
values.assume_init()
};
assert_eq!(*values, [1, 2, 3]);
Trait Implementations§
Source§impl<T: ?Sized, A: Allocator> BorrowMut<T> for Box<T, A>
impl<T: ?Sized, A: Allocator> BorrowMut<T> for Box<T, A>
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<'de, T> Deserialize<'de> for Box<[T]>where
T: Deserialize<'de>,
impl<'de, T> Deserialize<'de> for Box<[T]>where
T: Deserialize<'de>,
Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Source§impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box<T>
impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box<T>
Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Source§impl<'de> Deserialize<'de> for Box<str>
impl<'de> Deserialize<'de> for Box<str>
Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Source§impl<T, A: Allocator> From<Box<[T], A>> for Vec<T, A>
impl<T, A: Allocator> From<Box<[T], A>> for Vec<T, A>
Source§fn from(s: Box<[T], A>) -> Self
fn from(s: Box<[T], A>) -> Self
Convert a boxed slice into a vector by transferring ownership of the existing heap allocation.
§Examples
use rune::alloc::{Box, Vec};
use rune::alloc::try_vec;
let s: Box<[i32]> = Box::try_from([10, 40, 30])?;
let x: Vec<i32> = Vec::from(s);
assert_eq!(x, [10, 40, 30]);
let s: Box<[i32]> = try_vec![10, 40, 30].try_into_boxed_slice()?;
let x: Vec<i32> = Vec::from(s);
assert_eq!(x, [10, 40, 30]);
Source§impl<T: ?Sized, A> From<Box<T, A>> for Pin<Box<T, A>>where
A: 'static + Allocator,
impl<T: ?Sized, A> From<Box<T, A>> for Pin<Box<T, A>>where
A: 'static + Allocator,
Source§fn from(boxed: Box<T, A>) -> Self
fn from(boxed: Box<T, A>) -> Self
Converts a Box<T>
into a Pin<Box<T>>
. If T
does not implement
Unpin
, then *boxed
will be pinned in memory and unable to be
moved.
This conversion does not allocate on the heap and happens in place.
This is also available via Box::into_pin
.
Constructing and pinning a Box
with
<Pin<Box<T>>>::from([Box::try?new](x))
can also be
written more concisely using [Box::try?pin](x)
. This
From
implementation is useful if you already have a Box<T>
, or you
are constructing a (pinned) Box
in a different way than with
Box::try_new
.
Source§impl<A: Allocator> From<Box<str, A>> for String<A>
impl<A: Allocator> From<Box<str, A>> for String<A>
Source§fn from(s: Box<str, A>) -> String<A>
fn from(s: Box<str, A>) -> String<A>
Converts the given boxed str
slice to a String
.
It is notable that the str
slice is owned.
§Examples
Basic usage:
use rune::alloc::{Box, String};
let s1: String = String::try_from("hello world")?;
let s2: Box<str> = s1.try_into_boxed_str()?;
let s3: String = String::from(s2);
assert_eq!("hello world", s3);