Expand description
A no_std
, zero-dependency crate for the creation and management of NaN-boxed types with
Box
-like semantics and tagged pointers, tagged pointers and a macro interface to safely
create NaN-boxed enums.
§Quickstart
First, add the crate to your Cargo.lock
(Note: for variable reserved widths, see the features section)
tagged_box = "0.1.0"
The recommend way to use this crate is through the tagged_box!
macro, as it’s a safe
interface for using NaN-boxed enums.
Next, for using the tagged_box!
macro, add the following to the top of your file
use tagged_box::{tagged_box, TaggableContainer, TaggableInner};
Then you can use the macro as follows
tagged_box! {
#[derive(Debug, Clone, PartialEq)]
struct Container, enum Item {
Integer(i32),
Boolean(bool),
String(String),
}
}
let container = Container::from(String::from("Hello from tagged-box!"));
assert_eq!(
container.into_inner(),
Item::String(String::from("Hello from tagged-box!"))
);
For working with NaN-boxes or TaggedBox
es, simply add
use tagged_box::TaggedBox;
And for TaggedPointer
s use
use tagged_box::TaggedPointer;
§What this crate does
This crate implements NaN-Boxing and Tagged Pointers, which are a way to store extra data in the unused bits of pointers.
While the two differ in implementation, they are semantically the same. In this crate, the TaggedBox
type allows you to store
anywhere from 7 to 16 bits of arbitrary data in your pointer, depending on the features enabled. For explanation’s sake,
I’ll be using the 48bits
feature to explain, as it’s the default and leads to the cleanest examples.
The pointers this applies to are 64 bits long, looking something like this
0000 0000 0000 0000
However, not all of these bits are used for the actual addressing of memory, so most pointers look like this
0000 FFFF FFFF FFFF
^^^^
Free Data!
Those first 16 bits are free data, just begging to be used, and that’s what TaggedPointer
does. TaggedPointer
simply
manages the pointer and the data (referred to as a ‘discriminant’ throughout this crate), making sure you get a pointer when you
need it and data when you need it, and not mixing those two up.
TaggedBox
goes one layer higher, storing an enum discriminant (Indicated by the type parameter) and directly storing the enum
variant’s inner value to the heap. In short, TaggedBox
is like a Box
and an enum rolled into one.
Ramping the abstraction up one more notch, we have the tagged_box!
macro, which creates a container-type struct and an
associated TaggedBox
-backed enum that can be seamlessly transferred between.
§Cargo Features
This crate has a few features that change the number of free and reserved bits:
48bits
(On by default): 48 bits of reserved pointer, 16 bits for data49bits
: 49 bits of reserved pointer, 15 bits for data50bits
: 50 bits of reserved pointer, 14 bits for data51bits
: 51 bits of reserved pointer, 13 bits for data52bits
: 52 bits of reserved pointer, 12 bits for data53bits
: 53 bits of reserved pointer, 11 bits for data54bits
: 54 bits of reserved pointer, 10 bits for data55bits
: 55 bits of reserved pointer, 9 bits for data56bits
: 56 bits of reserved pointer, 8 bits for data57bits
: 57 bits of reserved pointer, 7 bits for data
However, only one of these may be active at a time, otherwise a compile_error
will be emitted.
To select a feature, put the following in your Cargo.toml
[dependencies.tagged_box]
version = "0.1.0"
default-features = false
features = ["50bits"] # Select your feature here
Modules§
- Stores variables that change upon different reserved pointer widths, as set by features
- A guide to manually implementing a tagged enum
Macros§
- Constructs a wrapper type and an associated enum to be stored as a
TaggedBox
that can be used safely.
For more implementation details, see manually implementing a tagged enum
Structs§
- A tagged box, associated with a variable type (enum, integer, etc.) able to be extracted from the underlying
TaggedPointer
- A pointer that holds a data pointer plus additional data stored as a
Discriminant
Note: The discriminant must be <=MAX_DISCRIMINANT
, which is feature-dependent
Traits§
- A helper trait for containers that hold a
TaggedBox
associated with a specific enum. - Represents a value able to be stored in a
TaggedBox
.