rust_utils/
macros.rs

1#[macro_export]
2macro_rules! cfg_group {
3    ($($item:item)*) => {
4        $($item)*
5    }
6}
7
8/// Calculates the offset of the specified field from the start of the named struct.
9#[macro_export]
10macro_rules! offset_of {
11    ($ty: path, $field: tt) => {{
12        use ::core::mem::MaybeUninit;
13        use ::core::primitive::{u8, usize};
14        use ::core::ptr;
15
16        #[allow(
17            unused_unsafe,
18            clippy::as_conversions,
19            clippy::unneeded_field_pattern,
20            clippy::undocumented_unsafe_blocks
21        )]
22        const OFFSET: usize = unsafe {
23            // ensure the type is a named struct
24            // ensure the field exists and is accessible
25            let $ty { $field: _, .. };
26
27            // const since 1.36
28            let uninit: MaybeUninit<$ty> = MaybeUninit::uninit();
29
30            // const since 1.59
31            // UnsafeCell needs feature(const_refs_to_cell)
32            let base_ptr: *const $ty = uninit.as_ptr();
33
34            // stable since 1.51
35            let field_ptr: *const _ = ptr::addr_of!((*base_ptr).$field);
36
37            // const since 1.38
38            let base_addr = base_ptr.cast::<u8>();
39            let field_addr = field_ptr.cast::<u8>();
40
41            // const since 1.65
42            field_addr.offset_from(base_addr) as usize
43        };
44        OFFSET
45    }};
46}