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
enum
can 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
Aligned
trait.
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
Foo
must be 2 pointers wide.- If
Foo
is smaller, it is already in the compact representation. - If
Foo
is larger, this crate cannot compress it into ausize
.
- If
Foo
must 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
Foo
must have enough alignment to store the tag. - Each variant of
Foo
must 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
The compact representation of
T
. Only one pointer wide.Traits
Mark that a pointer type is properly aligned and can be used in
EnumPtr
.