| Crates.io | gep |
| lib.rs | gep |
| version | 0.1.0 |
| created_at | 2023-08-09 21:42:27.772363+00 |
| updated_at | 2023-08-09 21:42:27.772363+00 |
| description | `gep`, a better pointer arithmetic library. |
| homepage | https://github.com/mcy/gep |
| repository | https://github.com/mcy/gep |
| max_upload_size | |
| id | 940412 |
| size | 67,757 |
gep, a better pointer arithmetic library.
The name gep comes from LLVM's getelementptr instruction, the infamous
pointer arithmetic operation.
This library provides two new pointer types, [Ptr] and [NonNull], which
have very similar APIs; they correspond to *mut T and
[core::ptr::NonNull], respectively.
It also provides Rusty versions of [memcpy], [memmove], and [memset].
The premiere operation provided by this library is [Ptr::at()], which is
a generalized pointer arithmetic operation. For example, it will accept
any integer as input, not just isize (although, like [<*mut T>::offset],
the offset value must be valid to convert to 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]);
By default, at() works on multiples of elements. To do a direct byte
offset instead, you can use the [offset::ByteOffset] type instead.
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);
It's also possible to use "field offsets" (via the [offset::Field] type)
for accessing the fields of a struct directly, without creating intermediate
references to potentially invalid data.
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);
License: Apache-2.0