Skip to main content

ExBox

Struct ExBox 

Source
pub struct ExBox<'a, T> { /* private fields */ }
Expand description

A pointer type for a single heap-allocated value with an explicit allocator.

§Ownership and Dropping

ExBox uniquely owns the value it points to. On drop:

  1. T’s destructor is called via drop_in_place.
  2. The backing memory is returned to the allocator.

§Zero-Sized Types

For ZSTs (size_of::<T>() == 0) no allocation is performed; ptr is set to NonNull::dangling() and dealloc is not called on drop.

§Lifetime

The allocator reference 'a must outlive the ExBox.

Implementations§

Source§

impl<'a, T> ExBox<'a, T>

Source

pub fn new(value: T, alloc: &'a dyn Allocator) -> Option<Self>

Allocates memory for T and moves value into it.

Returns None if the allocator fails.

§Example
let b = ExBox::new(42u64, &sys).unwrap();
assert_eq!(*b, 42);
Examples found in repository?
examples/box.rs (line 7)
4fn main() {
5    let alloc = SystemAllocator;
6
7    let boxed_int = ExBox::new(1337, &alloc).expect("Out of memory");
8
9    println!("Value: {}", *boxed_int);
10    
11    let val = ExBox::unbox(boxed_int);
12    println!("Unboxed: {}", val);
13}
More examples
Hide additional examples
examples/full.rs (line 14)
9fn main() {
10    let sys = CountingAllocator::new(SystemAllocator);
11    
12    println!("=== ExBox & SystemAllocator ===");
13    {
14        let b = ExBox::new(42, &sys).expect("Failed to alloc Box");
15        println!("Box value: {}", *b);
16    }
17    
18    let stats = sys.stats();
19    println!("Allocated: {} bytes", stats.bytes_allocated);
20    println!("Deallocated: {} bytes", stats.bytes_freed);
21    println!("Live bytes: {}\n", stats.bytes_live);
22
23    println!("=== ExVec & Arena (Linear Allocation) ===");
24    {
25        let arena = ArenaAllocator::new(&sys);
26        
27        let mut v = ExVec::new(&arena);
28        for i in 0..5 {
29            v.push(i * 10);
30        }
31        println!("Vec: {:?}", v.as_slice());
32        
33        arena.reset();
34        println!("Arena reset performed");
35    }
36
37    println!("\n=== ExString & Pool (Fixed Size Blocks) ===");
38    {
39        let pool = PoolAllocator::typed::<[u8; 64]>(&sys, 10)
40            .expect("Failed to create Pool");
41        
42        let mut s = ExString::new(&pool);
43        s.push_str("Hello from ZigZag!");
44        
45        println!("String in Pool: {}", s.as_str());
46        println!("Pool free slots: {}", pool.free_count());
47    }
48
49    println!("\n=== Final Global Stats ===");
50    let final_stats = sys.stats();
51    println!("Total count of alloc() calls: {}", final_stats.allocs);
52    println!("Total count of dealloc() calls: {}", final_stats.deallocs);
53    println!("Total bytes allocated: {}", final_stats.bytes_allocated);
54    println!("Total bytes freed: {}", final_stats.bytes_freed);
55    println!("Current leak/live size: {} bytes", final_stats.bytes_live);
56}
Source

pub fn new_zeroed(value: T, alloc: &'a dyn Allocator) -> Option<Self>

Allocates zero-filled memory for T, then moves value into it.

The allocation is zeroed before value is written, which may be useful for types with padding bytes that should be deterministic.

Returns None if the allocator fails.

Source

pub fn unbox(b: Self) -> T

Consumes the box, returns the inner value, and deallocates the backing memory.

§Implementation Note

We read the value out of the pointer and then call mem::forget on the ExBox to prevent the Drop implementation from running a second destructor or freeing the (already freed) memory.

Examples found in repository?
examples/box.rs (line 11)
4fn main() {
5    let alloc = SystemAllocator;
6
7    let boxed_int = ExBox::new(1337, &alloc).expect("Out of memory");
8
9    println!("Value: {}", *boxed_int);
10    
11    let val = ExBox::unbox(boxed_int);
12    println!("Unboxed: {}", val);
13}
Source

pub unsafe fn wipe(b: &mut Self)

Zeroes all bytes of the allocation in-place (without moving or dropping T).

§Safety

After this call, the memory backing *b contains all zeros. If T has any validity invariants (e.g. non-null pointers, non-zero discriminants) those invariants will be violated. Accessing *b after calling wipe is undefined behaviour unless T is a type for which all-zeros is a valid representation.

Source

pub fn as_ptr(b: &Self) -> *const T

Returns a raw const pointer to the contained value.

Source

pub fn as_mut_ptr(b: &mut Self) -> *mut T

Returns a raw mutable pointer to the contained value.

Trait Implementations§

Source§

impl<T: Debug> Debug for ExBox<'_, T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Deref for ExBox<'_, T>

Source§

type Target = T

The resulting type after dereferencing.
Source§

fn deref(&self) -> &T

Dereferences the value.
Source§

impl<T> DerefMut for ExBox<'_, T>

Source§

fn deref_mut(&mut self) -> &mut T

Mutably dereferences the value.
Source§

impl<T: Display> Display for ExBox<'_, T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Drop for ExBox<'_, T>

Source§

fn drop(&mut self)

Runs T’s destructor and returns the backing memory to the allocator.

Source§

impl<T: PartialEq> PartialEq for ExBox<'_, T>

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

§

impl<'a, T> Freeze for ExBox<'a, T>

§

impl<'a, T> !RefUnwindSafe for ExBox<'a, T>

§

impl<'a, T> !Send for ExBox<'a, T>

§

impl<'a, T> !Sync for ExBox<'a, T>

§

impl<'a, T> Unpin for ExBox<'a, T>

§

impl<'a, T> UnsafeUnpin for ExBox<'a, T>

§

impl<'a, T> !UnwindSafe for ExBox<'a, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.