Expand description
§sized-dst
This crate provides Dst, an owned container for dynamically-sized types (DSTs) that’s backed by inline memory. The main use-case is owned trait objects without heap allocation. You can think of it as a stack-only version of Box<dyn Trait>.
This crate currently requires nightly, since it relies on Unsize and pointer metadata.
The layout of sized_dst::Dst consists of the DST metadata (for trait objects, this is the vtable pointer) and a fixed block of memory storing the actual object. This allows it to live entirely on the stack or even a static variable. The size and alignment of its memory block are specified by generic parameters, so a sized_dst::Dst can only store objects that fit in its memory block. If the object does not fulfill the size or alignment requirements, the constructor of sized_dst::Dst will emit a compile-time error.
use sized_dst::{Dst, max_size};
trait Draw {
fn draw(&self);
}
struct Button {
height: u32,
width: u32,
name: &'static str,
}
impl Draw for Button {
fn draw(&self) { /* draw the button */ }
}
struct Checkbox {
on: bool,
}
impl Draw for Checkbox {
fn draw(&self) { /* draw the checkbox */ }
}
struct Text(&'static str);
impl Draw for Text {
fn draw(&self) { /* draw the text */ }
}
struct Blob([u8; 100]);
impl Draw for Blob {
fn draw(&self) { /* draw the blob */ }
}
impl Draw for u32 {
fn draw(&self) { /* draw the u32 */ }
}
fn main() {
// Each Dst stores a `dyn Draw` up to a fixed capacity, which is set via `max_size` to
// the size of the biggest trait object we're using.
let drawables: &[Dst<dyn Draw, { max_size!(Checkbox, Text, Button) }>] = &[
Dst::new(Checkbox { on: true }),
Dst::new(Text("lorem ipsum")),
Dst::new(Button {
height: 20,
width: 20,
name: "PANIC BUTTON",
}),
Dst::new(1u32), // u32 is smaller than the fixed capacity we specified, so we can use it
// Dst::new(Blob([0; 100])) This would not compile, because Blob doesn't fit in Dst
];
// Perform dynamic dispatch over the Draw trait
for d in drawables {
d.draw();
}
}Compared to Box<dyn Trait>, Dst requires no indirection or allocation, making it more cache-friendly and usable in environments with no allocator. In exchange, Dst can only store objects up to a fixed size, making it less flexible than Box<dyn Trait>. In a way, Dst offers a compromise between enums and boxed trait objects.
§Optional Features
std: Enable implementations ofstdtraits.
If you to change the alignment requirements of your DST (for example, your type may need to be
aligned to a 32-byte boundary), see DstBase, which is also where most of the documentation
lives.
Macros§
- max_
size - Given multiple type names, return the size of the biggest type.
Structs§
- A1
- 1-byte alignment
- A2
- 2-byte alignment
- A4
- 4-byte alignment
- A8
- 8-byte alignment
- A16
- 16-byte alignment
- A32
- 32-byte alignment
- A64
- 64-byte alignment
- DstBase
- Sized object that stores a DST object, such as a trait object, on the stack.
Traits§
- Alignment
- A marker trait for an alignment value.
Type Aliases§
- Dst
DstBasewith the alignment ofusize. This is almost always what you want to use.- DstA1
DstBasestoring an object with alignment of 1 byte- DstA2
DstBasestoring an object with alignment of 2 bytes- DstA4
DstBasestoring an object with alignment of 4 bytes- DstA8
DstBasestoring an object with alignment of 8 bytes- DstA16
DstBasestoring an object with alignment of 16 bytes- DstA32
DstBasestoring an object with alignment of 32 bytes- DstA64
DstBasestoring an object with alignment of 64 bytes- DstPtr
Dstwith the size and alignment ofusize. This can be used to represent bothdynpointers anddynobjects smaller than a pointer.