pub struct TaggedBox<T> { /* private fields */ }Expand description
A tagged box, associated with a variable type (enum, integer, etc.) able to be extracted from
the underlying TaggedPointer
Implementations§
Source§impl<T> TaggedBox<T>
impl<T> TaggedBox<T>
Sourcepub fn new<U>(val: U, discriminant: Discriminant) -> Self
pub fn new<U>(val: U, discriminant: Discriminant) -> Self
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!
}Sourcepub unsafe fn as_ref<U>(&self) -> &U
pub unsafe fn as_ref<U>(&self) -> &U
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);
}Sourcepub unsafe fn as_mut_ref<U>(&mut self) -> &mut U
pub unsafe fn as_mut_ref<U>(&mut self) -> &mut U
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);
}Sourcepub unsafe fn into_inner<U>(tagged: Self) -> U
pub unsafe fn into_inner<U>(tagged: Self) -> U
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);
}Sourcepub fn into_raw<U>(tagged: Self) -> *mut U
pub fn into_raw<U>(tagged: Self) -> *mut U
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]);
}Sourcepub unsafe fn into_box<U>(tagged: Self) -> Box<U>
pub unsafe fn into_box<U>(tagged: Self) -> Box<U>
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);
}Sourcepub unsafe fn from_raw<U>(raw: *mut U, discriminant: Discriminant) -> Self
pub unsafe fn from_raw<U>(raw: *mut U, discriminant: Discriminant) -> Self
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]);
}Sourcepub const fn discriminant(&self) -> Discriminant
pub const fn discriminant(&self) -> Discriminant
Fetches the discriminant of a TaggedBox
§Examples
let tagged_box: TaggedBox<InnerValue> = TaggedBox::new(0x00, 11);
assert_eq!(tagged_box.discriminant(), 11);Sourcepub const fn as_ptr<U>(&self) -> *const U
pub const fn as_ptr<U>(&self) -> *const U
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);
}Sourcepub fn as_mut_ptr<U>(&mut self) -> *mut U
pub fn as_mut_ptr<U>(&mut self) -> *mut U
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);
}