[][src]Struct tagged_box::TaggedBox

#[repr(transparent)]
pub struct TaggedBox<T> { /* fields omitted */ }

A tagged box, associated with a variable type (enum, integer, etc.) able to be extracted from the underlying TaggedPointer

Methods

impl<T> TaggedBox<T>[src]

pub fn new<U>(val: U, discriminant: Discriminant) -> Self[src]

Creates a new TaggedBox from a value and its discriminant

Examples

enum Communication {
    Message(String),
    Letter(Vec<Paper>),
}

let tagged_message: TaggedBox<Communication> = TaggedBox::new(String::from("Foobar is a timeless classic"), 0);

Make sure to retrieve the correct type from the TaggedBox, or you will encounter undefined behavior!

This is alright, because we stored a String onto the heap and we are retrieving a String with into_inner

unsafe {
    let message = TaggedBox::into_inner::<String>(tagged_message);

    assert_eq!(&message, "Foobar is a timeless classic");
}

This is UB, because we stored a String onto the heap and are retreving a Vec<Paper

unsafe {
    let letter = TaggedBox::into_inner::<Vec<Paper>>(tagged_message); // UB!
}

pub unsafe fn as_ref<U>(&self) -> &U[src]

Returns an immutable reference to the value stored on the heap

Safety

The type provided as U must be the same type as allocated by new, and any actions done with the value must not move it

Example

enum Bricks {
    Red(usize),
}

let red_brick: TaggedBox<Bricks> = TaggedBox::new(100_usize, 0);

unsafe {
    // We allocated a usize, so we can retrieve one
    assert_eq!(red_brick.as_ref::<usize>(), &100);
}

pub unsafe fn as_mut_ref<U>(&mut self) -> &mut U[src]

Returns an immutable reference to the value stored on the heap

Safety

The type provided as U must be the same type as allocated by new, and any actions done with the value must not move it

Example

enum Bricks {
    Red(usize),
}

let mut red_brick: TaggedBox<Bricks> = TaggedBox::new(100_usize, 0);

unsafe {
    assert_eq!(red_brick.as_ref::<usize>(), &100);

    // We allocated a usize, so we can retrieve one and change it
    *red_brick.as_mut_ref::<usize>() = 300;

    assert_eq!(red_brick.as_ref::<usize>(), &300);
}

#[must_use] pub unsafe fn into_inner<U>(tagged: Self) -> U[src]

Return the boxed value contained in the TaggedPointer

Safety

The type provided as U must be the same type as allocated by new

Example

enum Bricks {
    Red(usize),
}

let red_brick: TaggedBox<Bricks> = TaggedBox::new(100_usize, 0);

unsafe {
    // We allocated a usize, so we can retrieve one
    let mut number_bricks: usize = TaggedBox::into_inner(red_brick);

    assert_eq!(number_bricks, 100);
}

pub fn into_raw<U>(tagged: Self) -> *mut U[src]

Consumes the TaggedBox, returning a raw pointer.

The pointer will be properly aligned and non-null, and the caller is responsible for managing the memory allocated by TaggedBox.

Example

let tagged_box: TaggedBox<InnerValue> = TaggedBox::new([10u8; 10], 8);

// Get the raw pointer to the heap-allocated value
let raw: *mut [u8; 10] = TaggedBox::into_raw(tagged_box);

unsafe {
    assert_eq!(*raw, [10; 10]);
}

pub unsafe fn into_box<U>(tagged: Self) -> Box<U>[src]

Creates a Box from the provided TaggedBox
Trusts that the type provided as U is valid for the allocated layout.

Safety

The type provided as U must be the same type that the instance of TaggedBox was initialized with.

Example

let tagged_box: TaggedBox<InnerValue> = TaggedBox::new([10u8; 10], 8);

unsafe {
    // Get the Boxed value
    let boxed: Box<[u8; 10]> = TaggedBox::into_box(tagged_box);
}

pub unsafe fn from_raw<U>(raw: *mut U, discriminant: Discriminant) -> Self[src]

Constructs a TaggedBox from a raw pointer and a discriminant.

Trusts that the provided pointer is valid and non-null, as well as that the memory allocated is the method same as allocated by TaggedBox. TaggedBox uses the standard allocator

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.

Example

let tagged_box: TaggedBox<InnerValue> = TaggedBox::new(vec![100_usize, 200, 300], 10);

// Turn the tagged box into a raw pointer and its discriminant
let discriminant = tagged_box.discriminant();
let raw_box: *mut Vec<usize> = TaggedBox::into_raw(tagged_box);

unsafe {
    assert_eq!(*raw_box, vec![100, 200, 300]);

    let tagged_box: TaggedBox<InnerValue> = TaggedBox::from_raw(raw_box, discriminant);
     
    assert_eq!(TaggedBox::into_inner::<Vec<usize>>(tagged_box), vec![100, 200, 300]);
}

pub const fn discriminant(&self) -> Discriminant[src]

Fetches the discriminant of a TaggedBox

Examples

let tagged_box: TaggedBox<InnerValue> = TaggedBox::new(0x00, 11);

assert_eq!(tagged_box.discriminant(), 11);

pub const fn as_ptr<U>(&self) -> *const U[src]

Retrieves a raw pointer to the data owned by TaggedBox, see TaggedPointer::as_ptr
The caller must ensure that the returned pointer is never written to. If you need to mutate the contents of the tagged pointer, use as_mut_ptr.

enum Bricks {
    Red(usize),
}

let red_brick: TaggedBox<Bricks> = TaggedBox::new(100_usize, 0);

unsafe {
    assert_eq!(*red_brick.as_ptr::<usize>(), 100);
}

pub fn as_mut_ptr<U>(&mut self) -> *mut U[src]

Retrieves a raw pointer to the data owned by TaggedBox, see TaggedPointer::as_mut_ptr
It is your responsibility to make sure that the string slice only gets modified in a way that it remains valid

Example

enum Bricks {
    Red(usize),
}

let mut red_brick: TaggedBox<Bricks> = TaggedBox::new(100_usize, 0);

unsafe {
    *red_brick.as_mut_ptr::<usize>() = 100_000;

    assert_eq!(TaggedBox::into_inner::<usize>(red_brick), 100_000);
}

Trait Implementations

impl<T: TaggableInner> Binary for TaggedBox<T>[src]

impl<T> Clone for TaggedBox<T> where
    T: TaggableInner + Clone
[src]

impl<T> Copy for TaggedBox<T> where
    T: TaggableInner + Copy
[src]

impl<T> Debug for TaggedBox<T> where
    T: TaggableInner + Debug + Clone
[src]

impl<T> Display for TaggedBox<T> where
    T: TaggableInner + Display + Clone
[src]

impl<T> Eq for TaggedBox<T> where
    T: TaggableInner + Eq
[src]

impl<T: TaggableInner> LowerHex for TaggedBox<T>[src]

impl<T: TaggableInner> Octal for TaggedBox<T>[src]

impl<T> Ord for TaggedBox<T> where
    T: TaggableInner + Ord
[src]

impl<T> PartialEq<TaggedBox<T>> for TaggedBox<T> where
    T: TaggableInner + PartialEq<T>, 
[src]

impl<T> PartialOrd<TaggedBox<T>> for TaggedBox<T> where
    T: TaggableInner + PartialOrd<T>, 
[src]

impl<T: TaggableInner> UpperHex for TaggedBox<T>[src]

Auto Trait Implementations

impl<T> Send for TaggedBox<T> where
    T: Send

impl<T> Sync for TaggedBox<T> where
    T: Sync

impl<T> Unpin for TaggedBox<T> where
    T: Unpin

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.