diff options
Diffstat (limited to 'vendor/mac/src/mem.rs')
-rw-r--r-- | vendor/mac/src/mem.rs | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/vendor/mac/src/mem.rs b/vendor/mac/src/mem.rs new file mode 100644 index 000000000..49cf5f1b1 --- /dev/null +++ b/vendor/mac/src/mem.rs @@ -0,0 +1,44 @@ +//! Macros for low-level memory manipulation. + +/// Make a tuple of the addresses of some of a struct's fields. +/// +/// This is useful when you are transmuting between struct types +/// and would like an additional dynamic check that the layouts +/// match. It's difficult to make such an assertion statically +/// in Rust at present. +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate mac; +/// use std::mem; +/// +/// # fn main() { +/// struct Foo { x: i32, y: i32 } +/// struct Bar { x: u32, y: u32 } +/// +/// let foo = Foo { x: 3, y: 4 }; +/// let old_addrs = addrs_of!(foo => x, y); +/// +/// let bar = unsafe { +/// mem::transmute::<&Foo, &Bar>(&foo) +/// }; +/// let new_addrs = addrs_of!(bar => x, y); +/// assert_eq!(old_addrs, new_addrs); +/// +/// assert_eq!(bar.x, 3); +/// assert_eq!(bar.y, 4); +/// # } +/// ``` +#[macro_export] +macro_rules! addrs_of { + ($obj:expr => $($field:ident),+) => { + ( // make a tuple + $( + unsafe { + ::std::mem::transmute::<_, usize>(&$obj.$field) + } + ),+ + ) + } +} |