Crates.io | gep |
lib.rs | gep |
version | 0.1.0 |
source | src |
created_at | 2023-08-09 21:42:27.772363 |
updated_at | 2023-08-09 21:42:27.772363 |
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