Expand description
Examples
use enum_ptr::{Aligned, Compact, EnumPtr, ShiftUsize, Unit};
#[derive(EnumPtr)]
#[repr(C, usize)] // required
enum Foo<'a, T: Aligned> {
A(T), // supports any `T: Aligned`
B(&'a u64),
C(Unit), // use `Unit` for unit variants
D(ShiftUsize<3>), // you can even use non-pointers
E(Box<i64>),
}
let compact_foo: Compact<_> = Foo::A(&1u64).into();
let original_foo: Foo<_> = compact_foo.into();Usage
This crate provides multiple APIs with different flavors.
Flavor 1: CompactCopy
If your enum type is Copy (e.g., consists of only &Ts), you can
convert it to CompactCopy. Each time you need to use it, just copy
and extract it. Easy-peasy!
Sadly, due to language limitations, we cannot combine Compact and
CompactCopy into one type.
Flavor 2: get_ref & get_mut
If your enum type is not Copy, and you happens to only have references
to the compact value, you can use get_ref and get_mut to get
references to the object that it points to.
For example, if you hold a compact Box<T>, you can use these APIs to
access &T and &mut T. Since there’s no Box<T> in the memory (but only
its compact form), we cannot create &Box<T> and &mut Box<T>. Check
FieldDeref and FieldDerefMut for more details.
Flavor 3: borrow & borrow_mut
get_ref and get_mut can be troublesome if you want to deal with
multiple variants at together. In that case, you can use
borrow and borrow_mut. They
will return derived reference types that you can match.
Flavor 4: map_ref & map_mut (legacy)
map_ref and map_mut will create
temporary objects that drop as soon as your closure ends. They can
sometimes be useful if you don’t want to derive reference objects.
Extension
All important traits are public. You can implement them for your own types.
Limitations
Suppose we are deriving from Foo, then
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 exactly one field.- Unit variants are not allowed due to performance concerns.
- If you need a unit variant, use
Unit.
- Each variant of
Foomust have enough alignment to store the tag.- Currently this crate cannot utilize high bits.
Any violation of these rules will either trigger a compilation error or a run-time panic. Passed assertions will be optimized out. That is to say, rule checks won’t affect the run-time performance.
Features
alloc(default) —Box,RcandArcsupport
Macros
Structs
- Compact representation of
T. Only one-pointer wide. isizethat shifts left byNbits.usizethat shifts left byNbits.- Placeholder of unit variants.
Traits
- Types (may not be pointers) that can be used in
EnumPtr. - Types that can be used by
get_refand to deriveCompactBorrow. - Types that can be used by
get_mutand to deriveCompactBorrowMut.
Derive Macros
- Derives conversions to and from
Compact.