1//! Macros for low-level memory manipulation.
2
3/// Make a tuple of the addresses of some of a struct's fields.
4///
5/// This is useful when you are transmuting between struct types
6/// and would like an additional dynamic check that the layouts
7/// match. It's difficult to make such an assertion statically
8/// in Rust at present.
9///
10/// # Example
11///
12/// ```
13/// # #[macro_use] extern crate mac;
14/// use std::mem;
15///
16/// # fn main() {
17/// struct Foo { x: i32, y: i32 }
18/// struct Bar { x: u32, y: u32 }
19///
20/// let foo = Foo { x: 3, y: 4 };
21/// let old_addrs = addrs_of!(foo => x, y);
22///
23/// let bar = unsafe {
24/// mem::transmute::<&Foo, &Bar>(&foo)
25/// };
26/// let new_addrs = addrs_of!(bar => x, y);
27/// assert_eq!(old_addrs, new_addrs);
28///
29/// assert_eq!(bar.x, 3);
30/// assert_eq!(bar.y, 4);
31/// # }
32/// ```
33#[macro_export]
34macro_rules! addrs_of {
35 ($obj:expr => $($field:ident),+) => {
36 ( // make a tuple
37 $(
38 unsafe {
39 ::std::mem::transmute::<_, usize>(&$obj.$field)
40 }
41 ),+
42 )
43 }
44}
45