3 个版本
使用旧的 Rust 2015
0.0.2 | 2016 年 3 月 8 日 |
---|---|
0.0.1 | 2016 年 3 月 8 日 |
0.0.0 | 2015 年 10 月 18 日 |
#4 在 #c-style
12KB
237 行
unsafe_unions
更新
(0.0.2):现在库可以在稳定版和 no_std 上运行。
缺点是,现在执行不同操作的方式有点奇怪:不再是不同命名的函数,而是现在有不同“模式”,每种模式对应一个操作。
.get_foo() => .by_ref().foo()
.get_foo_mut() => .by_mut().foo()
.read_foo() => .read().foo()
.write_foo(x) => .write().foo(x)
API
unsafe_unions!{
[pub] union $union: $repr {
$variant: $variant_ty,
...
}
...
}
$repr
应当是一个大于或等于最大字段大小的 POD 类型。这需要指定,因为我们目前还没有在编译时确定最大变体类型的方法。
生成方法:
/** $union/$union<()> (default mode) **/
/// Creates a new $union with uninitialized memory.
pub fn new() -> Self;
/// Creates a new $union with zeroed memory.
pub fn zeroed() -> Self;
/// Creates a new $union with uninitialized memory and writes `v` to it.
pub unsafe fn $variant(v: $variant_ty) -> Self;
pub fn repr(&self) -> &$repr;
pub fn repr_mut(&mut self) -> &mut $repr;
/// Enters by-ref mode.
pub fn by_ref(&self) -> &$union<ByRef>;
/// Enters by-mut mode.
pub fn by_mut(&mut self) -> &mut $union<ByMut>;
/// Enters read mode.
pub fn read(&self) -> &$union<Read>;
/// Enters write mode.
pub fn write(&mut self) -> &mut $union<Read>;
/** $union<ByRef> (by-ref mode) **/
/// Casts `&self` to `&$variant_ty`.
pub unsafe fn $variant(&self) -> &$variant_ty;
/** $union<ByMut> (by-mut mode) **/
/// Casts `&mut self` to `&mut $variant_ty`.
pub unsafe fn $variant(&mut self) -> &mut $variant_ty;
/** $union<Read> (read mode) **/
/// `ptr::read`-operation
pub unsafe fn $variant(&self) -> $variant_ty;
/** $union<Write> (write mode) **/
/// `ptr::write`-operation
pub unsafe fn $variant(&mut self, v: $variant_ty);
所有 $union
-类型也实现了 Clone
和 Copy
。
示例
#[macro_use]
extern crate unsafe_unions;
unsafe_unions!{
union UntaggedValue: [u64; 3] {
nil: (),
boolean: bool,
integer: i64,
floating: f64,
string: String,
}
}
fn main(){
unsafe {
let mut val: UntaggedValue = UntaggedValue::integer(200);
assert_eq!(*val.by_ref().integer(), 200);
*val.by_mut().boolean() = false;
assert_eq!(*val.by_ref().boolean(), false);
val.write().string("foobar".to_owned());
assert_eq!(&**val.by_ref().string(), "foobar");
drop(val.read().string());
}
}
待办事项
- 编写文档
- 编写测试