[−][src]Crate thinbox
thinbox
provides an alternative implementation of the standard Rust
Box
container which has a pointer-sized representation in all cases.
This property is mainly useful in niche Foreign-Function-Interface
use-cases. You should probably not use thinbox
unless you wish to use
unsized types as opaque data crossing an FFI boundary.
In particular, the author has found this crate useful in passing around Rust closure types as userdata pointers in several C-language FFI projects.
Example
This use-case for ThinBox
is achieved by leveraging the unsize
function to create a representation of a trait which is single-pointer-
sized.
use std::mem; use thinbox::ThinBox; trait Animal { fn speak(&self); } struct Dog { name: &'static str, loud: bool, } impl Animal for Dog { fn speak(&self) { if self.loud { println!("WOOF!"); } else { println!("woof!"); } } } fn main() { // Create a loud dog named "Woofers", but forget that he's a dog and that // he's loud by unsizing. let thin: ThinBox<dyn Animal> = ThinBox::unsize(Dog { name: "Woofers", loud: true }); // Move to a single-pointer-sized representation. let raw = ThinBox::into_raw(thin); assert_eq!(mem::size_of_val(&raw), mem::size_of::<*mut ()>()); // Restore the dynamic representation from the raw representation. let thin = unsafe { ThinBox::<dyn Animal>::from_raw(raw) }; // "WOOF!" thin.speak(); }
Testing
thinbox
has been tested with Miri, which has revealed no violations of
Stacked Borrows.
Implementation Details
ThinBox
is currently implemented as a pointer to Box
-managed memory
if T
is sized and as a pointer to a Box
-managed structure containing a
vptr and value if T
is unsized. Since the vptr is not stored in the
Box
, ThinBox
is thus single-pointer-sized in all cases.
These implementation details are not guaranteed to be preserved across releases.
Structs
ThinBox | A consistently-sized pointer type for heap allocation. |
Functions
is_unsized | Returns |