1 个不稳定版本

0.1.0 2023 年 8 月 9 日

#2223Rust 模式

Apache-2.0

55KB
702

gep

gep,一个更好的指针算术库。

名称 gep 来自 LLVM 的 getelementptr 指令,臭名昭著的指针算术操作。

该库提供了两种新的指针类型,[Ptr::at()] 和 NonNull::,它们具有非常相似的 API;分别对应于 *mut Tcore::ptr::NonNull

它还提供了 Rust 版本的 memcpymemmovememset

偏移量

该库提供的首要操作是 [Ptr::at()],这是一个通用的指针算术操作。例如,它将接受任何整数作为输入,而不仅仅是 isize(尽管,像 [<*mut T>::offset],偏移量值必须是有效的,可以转换为 isize)。

let mut ints = [0i32; 6];
let p = Ptr::from(&mut ints).element();

unsafe {
  // Pointer to the 4th element.
  let q = p.at(4);
  q.write(42);

  // Many operations have an `*_at` variant that internally calls .at().
  q.write_at(-1, 55);
}

assert_eq!(ints, [0, 0, 0, 55, 42, 0]);

默认情况下,at() 在元素的多倍上工作。要进行直接字节偏移,可以使用 offset::ByteOffset 类型。

use gep::offset::ByteOffset;

let mut ints = [0i32; 6];
let p = Ptr::from(&mut ints).element();

unsafe {
  p.write_at(ByteOffset(4), 4242);
}

assert_eq!(ints[1], 4242);

也可以使用“字段偏移量”(通过offset::Field类型)直接访问结构体的字段,而无需创建指向可能无效数据的中间引用。

use gep::offset::Field;

struct Foo {
  a: i32,
  b: [i32; 3],
}

let foo = Foo { a: 0, b: [1, 2, 3] };

let p = Ptr::from(&foo);
let value = unsafe {
  p.read_at(gep::field!(Foo.b[1]))
};

assert_eq!(value, 2);

许可证:Apache-2.0

无运行时依赖