2次发布

0.1.1 2020年3月8日
0.1.0 2020年3月8日

#332 in 嵌入式开发

Download history 11/week @ 2023-11-30 19/week @ 2023-12-07 22/week @ 2023-12-14 19/week @ 2023-12-21 10/week @ 2023-12-28 15/week @ 2024-01-04 29/week @ 2024-01-11 12/week @ 2024-01-18 3/week @ 2024-01-25 7/week @ 2024-02-01 21/week @ 2024-02-08 30/week @ 2024-02-15 43/week @ 2024-02-22 38/week @ 2024-02-29 42/week @ 2024-03-07 22/week @ 2024-03-14

每月 148次下载
12 个crates中使用(通过 litl

MIT/Apache

72KB
964

Tagged-box

Crates.io Docs.rs GitHub LOC

一个无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

无运行时依赖

特性