1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
#[macro_export] macro_rules! ENUM { {enum $name:ident { $($variant:ident = $value:expr,)+ }} => { pub type $name = u32; $(pub const $variant: $name = $value;)+ }; {enum $name:ident { $variant:ident = $value:expr, $($rest:tt)* }} => { pub type $name = u32; pub const $variant: $name = $value; ENUM!{@gen $name $variant, $($rest)*} }; {enum $name:ident { $variant:ident, $($rest:tt)* }} => { ENUM!{enum $name { $variant = 0, $($rest)* }} }; {@gen $name:ident $base:ident,} => {}; {@gen $name:ident $base:ident, $variant:ident = $value:expr, $($rest:tt)*} => { pub const $variant: $name = $value; ENUM!{@gen $name $variant, $($rest)*} }; {@gen $name:ident $base:ident, $variant:ident, $($rest:tt)*} => { pub const $variant: $name = $base + 1u32; ENUM!{@gen $name $variant, $($rest)*} }; } #[macro_export] macro_rules! STRUCT { (#[debug] $($rest:tt)*) => ( STRUCT!{#[cfg_attr(feature = "impl-debug", derive(Debug))] $($rest)*} ); ($(#[$attrs:meta])* struct $name:ident { $($field:ident: $ftype:ty,)+ }) => ( #[repr(C)] #[derive(Copy)] $(#[$attrs])* pub struct $name { $(pub $field: $ftype,)+ } impl Clone for $name { #[inline] fn clone(&self) -> $name { *self } } #[cfg(feature = "impl-default")] impl Default for $name { #[inline] fn default() -> $name { unsafe { std::mem::zeroed() } } } ); } macro_rules! UNION { ($(#[$attrs:meta])* union $name:ident { [$stype:ty; $ssize:expr], $($variant:ident $variant_mut:ident: $ftype:ty,)+ }) => ( #[repr(C)] $(#[$attrs])* pub struct $name([$stype; $ssize]); impl Copy for $name {} impl Clone for $name { #[inline] fn clone(&self) -> $name { *self } } #[cfg(feature = "impl-default")] impl Default for $name { #[inline] fn default() -> $name { unsafe { std::mem::zeroed() } } } impl $name {$( #[inline] pub unsafe fn $variant(&self) -> &$ftype { &*(self as *const _ as *const $ftype) } #[inline] pub unsafe fn $variant_mut(&mut self) -> &mut $ftype { &mut *(self as *mut _ as *mut $ftype) } )+} ); ($(#[$attrs:meta])* union $name:ident { [$stype32:ty; $ssize32:expr] [$stype64:ty; $ssize64:expr], $($variant:ident $variant_mut:ident: $ftype:ty,)+ }) => ( #[repr(C)] $(#[$attrs])* #[cfg(target_arch = "x86")] pub struct $name([$stype32; $ssize32]); #[repr(C)] $(#[$attrs])* #[cfg(target_pointer_width = "64")] pub struct $name([$stype64; $ssize64]); impl Copy for $name {} impl Clone for $name { #[inline] fn clone(&self) -> $name { *self } } #[cfg(feature = "impl-default")] impl Default for $name { #[inline] fn default() -> $name { unsafe { std::mem::zeroed() } } } impl $name {$( #[inline] pub unsafe fn $variant(&self) -> &$ftype { &*(self as *const _ as *const $ftype) } #[inline] pub unsafe fn $variant_mut(&mut self) -> &mut $ftype { &mut *(self as *mut _ as *mut $ftype) } )+} ); }