Expand description
Basic Usage
use enum_ptr::{Compact, EnumPtr};
#[derive(EnumPtr)]
#[repr(C, usize)] // required
enum Foo<'a, 'b, T> {
A(&'a T),
B { ptr: &'b mut i64 },
C(Option<Box<i64>>),
D(),
E {},
F,
}
let compact_foo: Compact<_> = Foo::A(&0u64).into();
let original_foo: Foo<_> = compact_foo.into();- The
enumcan have generic parameters. - Its variants can be named (
X{...}), unnamed (X(...)), or units (X). - Each variant can have at most one field.
- Fields are required to implement the
Alignedtrait.
Extension
To use your own pointer types in the fields, you only need to implement
the Aligned trait for it. Note that you are responsible to ensure the
safety assertions of Aligned.
use enum_ptr::{Aligned, Compact, EnumPtr};
struct MyPtr<T>(*const T);
unsafe impl<T> Aligned for MyPtr<T> {
type Pointee = T;
}
#[derive(EnumPtr)]
#[repr(C, usize)]
enum Foo {
A(MyPtr<i64>),
B(MyPtr<u64>),
}Caveats
Due to safety issues, when the enum contains units, the generated code
will be less performant. You can substitute unit variants with pointers
to avoid this situation.
use enum_ptr::EnumPtr;
#[derive(EnumPtr)]
#[repr(C, usize)]
enum Foo {
A(Box<i64>),
B, // -> B(Option<Box<i64>>)
}Limitations
Suppose we are deriving from Foo, then
Foomust be 2 pointers wide.- If
Foois smaller, it is already in the compact representation. - If
Foois larger, this crate cannot compress it into ausize.
- If
Foomust have a#[repr(C, usize)].- According to the RFC and the Rust Reference,
#[repr(C, usize)]guarantees the memory layout and discriminant values. Thus, we can safely transmute between two representations.
- According to the RFC and the Rust Reference,
- Each variant of
Foomust have enough alignment to store the tag. - Each variant of
Foomust have at most one field.
Any violation of these rules will trigger a compilation error except the alignment rule. If not, please file an issue.
If some variant has no enough alignment, it will trigger a run-time panic. Otherwise, assertions will be optimized away.
Structs
Traits
Mark that a pointer type is properly aligned and can be used in
EnumPtr.