1 // implements the unary operator "op &T" 2 // based on "op T" where T is expected to be `Copy`able 3 macro_rules! forward_ref_unop { 4 (impl $imp:ident, $method:ident for $t:ty) => { 5 forward_ref_unop!(impl $imp, $method for $t, 6 #[stable(feature = "rust1", since = "1.0.0")]); 7 }; 8 (impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => { 9 #[$attr] 10 impl $imp for &$t { 11 type Output = <$t as $imp>::Output; 12 13 #[inline] 14 fn $method(self) -> <$t as $imp>::Output { 15 $imp::$method(*self) 16 } 17 } 18 } 19 } 20 21 // implements binary operators "&T op U", "T op &U", "&T op &U" 22 // based on "T op U" where T and U are expected to be `Copy`able 23 macro_rules! forward_ref_binop { 24 (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { 25 forward_ref_binop!(impl $imp, $method for $t, $u, 26 #[stable(feature = "rust1", since = "1.0.0")]); 27 }; 28 (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { 29 #[$attr] 30 impl<'a> $imp<$u> for &'a $t { 31 type Output = <$t as $imp<$u>>::Output; 32 33 #[inline] 34 fn $method(self, other: $u) -> <$t as $imp<$u>>::Output { 35 $imp::$method(*self, other) 36 } 37 } 38 39 #[$attr] 40 impl $imp<&$u> for $t { 41 type Output = <$t as $imp<$u>>::Output; 42 43 #[inline] 44 fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output { 45 $imp::$method(self, *other) 46 } 47 } 48 49 #[$attr] 50 impl $imp<&$u> for &$t { 51 type Output = <$t as $imp<$u>>::Output; 52 53 #[inline] 54 fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output { 55 $imp::$method(*self, *other) 56 } 57 } 58 } 59 } 60 61 // implements "T op= &U", based on "T op= U" 62 // where U is expected to be `Copy`able 63 macro_rules! forward_ref_op_assign { 64 (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { 65 forward_ref_op_assign!(impl $imp, $method for $t, $u, 66 #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); 67 }; 68 (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { 69 #[$attr] 70 impl $imp<&$u> for $t { 71 #[inline] 72 fn $method(&mut self, other: &$u) { 73 $imp::$method(self, *other); 74 } 75 } 76 } 77 } 78 79 /// Create a zero-size type similar to a closure type, but named. 80 macro_rules! impl_fn_for_zst { 81 ($( 82 $( #[$attr: meta] )* 83 struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn = 84 |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty 85 $body: block; 86 )+) => { 87 $( 88 $( #[$attr] )* 89 struct $Name; 90 91 impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name { 92 #[inline] 93 extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy { 94 $body 95 } 96 } 97 98 impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name { 99 #[inline] 100 extern "rust-call" fn call_mut( 101 &mut self, 102 ($( $arg, )*): ($( $ArgTy, )*) 103 ) -> $ReturnTy { 104 Fn::call(&*self, ($( $arg, )*)) 105 } 106 } 107 108 impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name { 109 type Output = $ReturnTy; 110 111 #[inline] 112 extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy { 113 Fn::call(&self, ($( $arg, )*)) 114 } 115 } 116 )+ 117 } 118 } 119 120 /// A macro for defining `#[cfg]` if-else statements. 121 /// 122 /// `cfg_if` is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade 123 /// of `#[cfg]` cases, emitting the implementation which matches first. 124 /// 125 /// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code without having to 126 /// rewrite each clause multiple times. 127 /// 128 /// # Example 129 /// 130 /// ```ignore(cannot-test-this-because-non-exported-macro) 131 /// cfg_if! { 132 /// if #[cfg(unix)] { 133 /// fn foo() { /* unix specific functionality */ } 134 /// } else if #[cfg(target_pointer_width = "32")] { 135 /// fn foo() { /* non-unix, 32-bit functionality */ } 136 /// } else { 137 /// fn foo() { /* fallback implementation */ } 138 /// } 139 /// } 140 /// 141 /// # fn main() {} 142 /// ``` 143 // This is a copy of `cfg_if!` from the `cfg_if` crate. 144 // The recursive invocations should use $crate if this is ever exported. 145 macro_rules! cfg_if { 146 // match if/else chains with a final `else` 147 ( 148 $( 149 if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* } 150 ) else+ 151 else { $( $e_tokens:tt )* } 152 ) => { 153 cfg_if! { 154 @__items () ; 155 $( 156 (( $i_meta ) ( $( $i_tokens )* )) , 157 )+ 158 (() ( $( $e_tokens )* )) , 159 } 160 }; 161 162 // Internal and recursive macro to emit all the items 163 // 164 // Collects all the previous cfgs in a list at the beginning, so they can be 165 // negated. After the semicolon is all the remaining items. 166 (@__items ( $( $_:meta , )* ) ; ) => {}; 167 ( 168 @__items ( $( $no:meta , )* ) ; 169 (( $( $yes:meta )? ) ( $( $tokens:tt )* )) , 170 $( $rest:tt , )* 171 ) => { 172 // Emit all items within one block, applying an appropriate #[cfg]. The 173 // #[cfg] will require all `$yes` matchers specified and must also negate 174 // all previous matchers. 175 #[cfg(all( 176 $( $yes , )? 177 not(any( $( $no ),* )) 178 ))] 179 cfg_if! { @__identity $( $tokens )* } 180 181 // Recurse to emit all other items in `$rest`, and when we do so add all 182 // our `$yes` matchers to the list of `$no` matchers as future emissions 183 // will have to negate everything we just matched as well. 184 cfg_if! { 185 @__items ( $( $no , )* $( $yes , )? ) ; 186 $( $rest , )* 187 } 188 }; 189 190 // Internal macro to make __apply work out right for different match types, 191 // because of how macros match/expand stuff. 192 (@__identity $( $tokens:tt )* ) => { 193 $( $tokens )* 194 }; 195 } 196