160636f74Sopenharmony_ci# memoffset #
260636f74Sopenharmony_ci
360636f74Sopenharmony_ci[![](https://img.shields.io/crates/v/memoffset.svg)](https://crates.io/crates/memoffset)
460636f74Sopenharmony_ci
560636f74Sopenharmony_ciC-Like `offset_of` functionality for Rust structs.
660636f74Sopenharmony_ci
760636f74Sopenharmony_ciIntroduces the following macros:
860636f74Sopenharmony_ci * `offset_of!` for obtaining the offset of a member of a struct.
960636f74Sopenharmony_ci * `offset_of_tuple!` for obtaining the offset of a member of a tuple. (Requires Rust 1.20+)
1060636f74Sopenharmony_ci * `offset_of_union!` for obtaining the offset of a member of a union.
1160636f74Sopenharmony_ci * `span_of!` for obtaining the range that a field, or fields, span.
1260636f74Sopenharmony_ci
1360636f74Sopenharmony_ci`memoffset` works under `no_std` environments.
1460636f74Sopenharmony_ci
1560636f74Sopenharmony_ci## Usage ##
1660636f74Sopenharmony_ciAdd the following dependency to your `Cargo.toml`:
1760636f74Sopenharmony_ci
1860636f74Sopenharmony_ci```toml
1960636f74Sopenharmony_ci[dependencies]
2060636f74Sopenharmony_cimemoffset = "0.8"
2160636f74Sopenharmony_ci```
2260636f74Sopenharmony_ci
2360636f74Sopenharmony_ciThese versions will compile fine with rustc versions greater or equal to 1.19.
2460636f74Sopenharmony_ci
2560636f74Sopenharmony_ci## Examples ##
2660636f74Sopenharmony_ci```rust
2760636f74Sopenharmony_ciuse memoffset::{offset_of, span_of};
2860636f74Sopenharmony_ci
2960636f74Sopenharmony_ci#[repr(C, packed)]
3060636f74Sopenharmony_cistruct Foo {
3160636f74Sopenharmony_ci    a: u32,
3260636f74Sopenharmony_ci    b: u32,
3360636f74Sopenharmony_ci    c: [u8; 5],
3460636f74Sopenharmony_ci    d: u32,
3560636f74Sopenharmony_ci}
3660636f74Sopenharmony_ci
3760636f74Sopenharmony_cifn main() {
3860636f74Sopenharmony_ci    assert_eq!(offset_of!(Foo, b), 4);
3960636f74Sopenharmony_ci    assert_eq!(offset_of!(Foo, d), 4+4+5);
4060636f74Sopenharmony_ci
4160636f74Sopenharmony_ci    assert_eq!(span_of!(Foo, a),        0..4);
4260636f74Sopenharmony_ci    assert_eq!(span_of!(Foo, a ..  c),  0..8);
4360636f74Sopenharmony_ci    assert_eq!(span_of!(Foo, a ..= c),  0..13);
4460636f74Sopenharmony_ci    assert_eq!(span_of!(Foo, ..= d),    0..17);
4560636f74Sopenharmony_ci    assert_eq!(span_of!(Foo, b ..),     4..17);
4660636f74Sopenharmony_ci}
4760636f74Sopenharmony_ci```
4860636f74Sopenharmony_ci
4960636f74Sopenharmony_ci## Usage in constants ##
5060636f74Sopenharmony_ci`memoffset` has support for compile-time `offset_of!` on rust>=1.65, or on older nightly compilers.
5160636f74Sopenharmony_ci
5260636f74Sopenharmony_ci### Usage on stable Rust ###
5360636f74Sopenharmony_ciConstant evaluation is automatically enabled and avilable on stable compilers starting with rustc 1.65.
5460636f74Sopenharmony_ci
5560636f74Sopenharmony_ciThis is an incomplete implementation with one caveat:
5660636f74Sopenharmony_ciDue to dependence on [`#![feature(const_refs_to_cell)]`](https://github.com/rust-lang/rust/issues/80384), you cannot get the offset of a `Cell` field in a const-context.
5760636f74Sopenharmony_ci
5860636f74Sopenharmony_ciThis means that if need to get the offset of a cell, you'll have to remain on nightly for now.
5960636f74Sopenharmony_ci
6060636f74Sopenharmony_ci### Usage on recent nightlies ###
6160636f74Sopenharmony_ci
6260636f74Sopenharmony_ciIf you're using a new-enough nightly and you require the ability to get the offset of a `Cell`,
6360636f74Sopenharmony_ciyou'll have to enable the `unstable_const` cargo feature, as well as enabling `const_refs_to_cell` in your crate root.
6460636f74Sopenharmony_ci
6560636f74Sopenharmony_ciDo note that `unstable_const` is an unstable feature that is set to be removed in a future version of `memoffset`.
6660636f74Sopenharmony_ci
6760636f74Sopenharmony_ciCargo.toml:
6860636f74Sopenharmony_ci```toml
6960636f74Sopenharmony_ci[dependencies.memoffset]
7060636f74Sopenharmony_civersion = "0.8"
7160636f74Sopenharmony_cifeatures = ["unstable_const"]
7260636f74Sopenharmony_ci```
7360636f74Sopenharmony_ci
7460636f74Sopenharmony_ciYour crate root: (`lib.rs`/`main.rs`)
7560636f74Sopenharmony_ci```rust,ignore
7660636f74Sopenharmony_ci#![feature(const_refs_to_cell)]
7760636f74Sopenharmony_ci```
7860636f74Sopenharmony_ci
7960636f74Sopenharmony_ci### Usage on older nightlies ###
8060636f74Sopenharmony_ciIn order to use it on an older nightly compiler, you must enable the `unstable_const` crate feature and several compiler features.
8160636f74Sopenharmony_ci
8260636f74Sopenharmony_ciYour crate root: (`lib.rs`/`main.rs`)
8360636f74Sopenharmony_ci```rust,ignore
8460636f74Sopenharmony_ci#![feature(const_ptr_offset_from, const_refs_to_cell)]
8560636f74Sopenharmony_ci```
86