2次发布
0.1.1 | 2020年3月8日 |
---|---|
0.1.0 | 2020年3月8日 |
#332 in 嵌入式开发
每月 148次下载
在 12 个crates中使用(通过 litl)
72KB
964 行
Tagged-box
一个无std、零依赖的crate,用于创建和管理带有类似Box语义和标记指针的NaN-boxed类型,以及用于安全创建标记枚举的宏接口。
快速入门
首先,将crate添加到您的Cargo.lock
(注意:有关可变保留宽度,请参阅功能部分)
tagged_box = "0.1.0"
然后,为了使用宏,将以下内容添加到文件顶部
use tagged_box::{tagged_box, TaggableContainer, TaggableInner};
然后您可以使用宏如下
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!"))
);
对于与NaN-box交互,只需添加
use tagged_box::TaggedBox;
而对于标记指针使用
use tagged_box::TaggedPointer;
这个crate的功能
这个crate实现了NaN-Boxing和标记指针,这是在指针的未使用位中存储额外数据的一种方法。虽然这两种方法在实现上有所不同,但它们在语义上是相同的。在这个crate中,TaggedBox
类型允许您根据启用的功能在指针中存储从7位到16位的任意数据。为了解释,我将使用48bits
功能进行说明,因为它是默认的,并且可以产生最干净的示例。
此功能适用于64位长度的指针,看起来像这样
0000 0000 0000 0000
然而,并不是所有这些位都用于实际的内存寻址,所以大多数指针看起来像这样
0000 FFFF FFFF FFFF
^^^^
Free Data!
那些第一个16位是空闲数据,正等着被使用,这正是TaggedPointer
所做的。简单地说,TaggedPointer
管理指针和数据(在这个crate中称为'discriminant'),确保您在需要时获得指针,需要时获得数据,并且不会混淆这两者。
TaggedBox
再高一层,存储一个enum
discriminant(由类型参数指示)并将枚举变体的内部值直接存储到堆中。简而言之,TaggedBox
就像是一个Box
和一个枚举的结合体。
将抽象层次再提升一级,我们有了 tagged_box!
宏,它创建了一个容器类型的结构体以及一个相关的 TaggedBox
支持的枚举类型,这些类型可以无缝地相互转换。
Cargo 特性
此crate有几个特性会改变自由和保留位的数量
48bits
(默认启用):48位保留指针,16位用于数据49bits
:49位保留指针,15位用于数据50bits
:50位保留指针,14位用于数据51bits
:51位保留指针,13位用于数据52bits
:52位保留指针,12位用于数据53bits
:53位保留指针,11位用于数据54bits
:54位保留指针,10位用于数据55bits
:55位保留指针,9位用于数据56bits
:56位保留指针,8位用于数据57bits
:57位保留指针,7位用于数据
但是,一次只能激活其中之一,否则将发出一个 compile_error
。
要选择一个特性,请在您的 Cargo.toml
文件中添加以下内容
[dependencies.tagged_box]
version = "0.1.0"
default-features = false
features = ["50bits"] # Select your feature here