6个版本
0.3.2 | 2023年3月27日 |
---|---|
0.3.1 | 2023年3月27日 |
0.2.0 | 2023年3月26日 |
0.1.1 | 2023年3月26日 |
101 在 无标准库
73 每月下载量
60KB
693 行
cbitmap
传统、紧凑和核心(无std)位图。
使用场景
当您想要维护一个包含大量但固定数量的位的位图时,建议您使用此crate。特别是,当您关心内存使用/对齐时,因为cbitmap
几乎不浪费空间。
例如,您可能想要管理一组资源,这些资源可以用两种状态来描述,位图非常适合您。
如果您想维护一组小的标志,如2或3,我们建议使用flagset。
位图最全面和成熟的实现可能是bitvec。如果您关心成熟度,建议您使用它。
此外,bitset-core是另一个强大的crate,它实现了紧凑的位图特质。然而,bitset-core
和cbitmap
之间的实现相当不同。
此外,cbitmap
的性能尚未经过测试,因为它处于alpha版本。如果您最关心性能,请在选择之前仔细考虑。
功能
我们提供了一个crate::bitmap::Bitmap
类型
pub struct Bitmap<const BYTES: usize> {
bits: [u8; BYTES],
}
建议您使用宏来创建新的位图
use cbitmap::bitmap::*;
let map = newmap!(0b_01; 2);
请参阅crate::he_lang
。
位图可以通过传统的方式操作,如Bitmap::test()
、Bitmap::set()
、Bitmap::reset()
、Bitmap::flip()
和Bitmap::at()
。请参阅文档以获取详细示例。
位图实际上是 u8
数组的包装 [u8; BYTES]
。它可以放在内存的多个地方。例如,如果映射相对较小,如8或16位,您可以在栈上安全地放置它。如果它更大,如256或1024位,您可能希望将其放在堆上。
示例
下面是一个简单的例子
use cbitmap::bitmap::*;
// A macro are provided to create a bitmap.
let mut map = newmap!(;16);
// There is a set of methods to manipulate the bitmap:
map.set(10);
map.reset(10);
map.flip(10);
// Some C++ like methods are provided:
assert_eq!(map.test(10), true);
assert_eq!(map.any(), true);
assert_eq!(map.none(), false);
// Also provide other useful methods:
assert_eq!(map.find_first_one(), 10);
// You can access a single bit using wrappers:
let mut bit = map.at_mut(10);
assert_eq!(*bit, true);
bit.flip();
assert_eq!(*map.at(10), false);
请参阅 Bitmap
的文档和示例目录,以获取详细示例。
您可以使用 cargo run --example <name>
来运行我们提供的示例。一个简单的示例是 bitmap-base
,另一个关于实际应用的详细示例是 bitmap-usecase
,其中位图用于管理原始内存资源。
当前约束
泛型常量表达式
位图通过 BYTES
指定其字节数。这与C++中的传统 bitset<N>
略有不同,其中 N
表示位大小。我们以这种方式实现位图,以保持在rust-stable上,因为 #![feature(generic_const_exprs)]
尚未支持,因此不允许这样做
// requiring #![feature(generic_const_exprs)]
pub struct Bitmap<const N: usize> {
bits: [u8; (N + 7) / 8],
}
我们提供了一种替代方法,让您指定位大小。宏 crate::newmap
实现了这一点
const BITS: usize = 16;
let map = newmap!(;BITS);
let another = newmap!(;BITS * 2);
原则上,在实例化结构体时使用 constexpr 是可能的
// allowed:
let map = Bitmap::<{64 / 8}>::new();
索引
C++ 中的 bitset<N>
可以通过索引运算符 []
进行索引。我们在实现此功能时遇到了一些问题。具体来说,为结构体实现 core::ops::IndexMut
如此
impl IndexMut for T {
type Output = U;
fn index(&mut self, index: usize) -> &mut Self::Output { ... }
}
&mut Self::Output
中的引用要求 self
拥有索引输出。
在 Bitmap
中,Output
必须是 "bits"。有必要使用包装类型来提供访问单个位的接口。我们提供了 BitRef
和 BitRefMut
作为包装器。
然而,位图不应该包含大量的包装器,以便节省内存。
由于这个问题,我们只提供了 Bitmap::at_mut()
作为方法来多重索引位图。
值得注意的是,我们提供了 Bitmap::at()
来获取 BitRef
,我们还提供了不可变的 Index
。然而,由于类似的问题,不可变的 Index
只返回一个 bool
值,而不是 BitRef
。
更新内容
-
0.3.2
-
- 添加
Index
。
- 添加
-
- 添加
as_ref()
、as_mut()
、as_ptr()
和as_mut_ptr()
。
- 添加
-
- 将通用方法如
set()
封装到特质中。
- 将通用方法如
-
0.3.1
-
- 添加基本基准测试。
-
- 添加与 C++ 兼容的新方法:
Bitmap::any()
、Bitmap::none()
、Bitmap::all()
、Bitmap::count()
和Bitmap::test()
。
- 添加与 C++ 兼容的新方法:
-
- 添加有用方法:[
Bitmap::find_first_one()
]、[Bitmap::find_first_zero()
]。
- 添加有用方法:[
-
- 添加示例
bitmap-usecase
,展示使用 bitmap 管理原始内存资源的情况。
- 添加示例
-
0.3.0
-
- 通过删除
Option
优化内存使用(bitmap 的大小比泛型大 1 字节,这不利于内存对齐)。
- 通过删除
-
- 添加新方法:FillPrefix。
-
- 改进宏的创建:现在长度参数接收 const 表达式。
-
0.2.0
-
- 添加构建宏。
-
0.1.1
-
- 更新文档。
-
0.1.0
-
- 首次发布。