xref: /rust-libc-0.2.174/src/macros.rs (revision a097ff6d)
1 /// A macro for defining #[cfg] if-else statements.
2 ///
3 /// This is similar to the `if/elif` C preprocessor macro by allowing definition
4 /// of a cascade of `#[cfg]` cases, emitting the implementation which matches
5 /// first.
6 ///
7 /// This allows you to conveniently provide a long list #[cfg]'d blocks of code
8 /// without having to rewrite each clause multiple times.
9 macro_rules! cfg_if {
10     ($(
11         if #[cfg($($meta:meta),*)] { $($it:item)* }
12     ) else * else {
13         $($it2:item)*
14     }) => {
15         __cfg_if_items! {
16             () ;
17             $( ( ($($meta),*) ($($it)*) ), )*
18             ( () ($($it2)*) ),
19         }
20     }
21 }
22 
23 macro_rules! __cfg_if_items {
24     (($($not:meta,)*) ; ) => {};
25     (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
26         __cfg_if_apply! { cfg(all(not(any($($not),*)), $($m,)*)), $($it)* }
27         __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* }
28     }
29 }
30 
31 macro_rules! __cfg_if_apply {
32     ($m:meta, $($it:item)*) => {
33         $(#[$m] $it)*
34     }
35 }
36 
37 macro_rules! s {
38     ($($(#[$attr:meta])* pub struct $i:ident { $($field:tt)* })*) => ($(
39         __item! {
40             #[repr(C)]
41             $(#[$attr])*
42             pub struct $i { $($field)* }
43         }
44         impl ::dox::Copy for $i {}
45         impl ::dox::Clone for $i {
46             fn clone(&self) -> $i { *self }
47         }
48     )*)
49 }
50 
51 macro_rules! f {
52     ($(pub fn $i:ident($($arg:ident: $argty:ty),*) -> $ret:ty {
53         $($body:stmt);*
54     })*) => ($(
55         #[inline]
56         #[cfg(not(dox))]
57         pub unsafe extern fn $i($($arg: $argty),*) -> $ret {
58             $($body);*
59         }
60 
61         #[cfg(dox)]
62         #[allow(dead_code)]
63         pub unsafe extern fn $i($($arg: $argty),*) -> $ret {
64             loop {}
65         }
66     )*)
67 }
68 
69 macro_rules! __item {
70     ($i:item) => ($i)
71 }
72 
73 #[cfg(test)]
74 mod tests {
75     cfg_if! {
76         if #[cfg(test)] {
77             use std::option::Option as Option2;
78             fn works1() -> Option2<u32> { Some(1) }
79         } else {
80             fn works1() -> Option<u32> { None }
81         }
82     }
83 
84     cfg_if! {
85         if #[cfg(foo)] {
86             fn works2() -> bool { false }
87         } else if #[cfg(test)] {
88             fn works2() -> bool { true }
89         } else {
90             fn works2() -> bool { false }
91         }
92     }
93 
94     cfg_if! {
95         if #[cfg(foo)] {
96             fn works3() -> bool { false }
97         } else {
98             fn works3() -> bool { true }
99         }
100     }
101 
102     #[test]
103     fn it_works() {
104         assert!(works1().is_some());
105         assert!(works2());
106         assert!(works3());
107     }
108 }
109