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