1// implements the unary operator "op &T"
2// based on "op T" where T is expected to be `Copy`able
3macro_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
23macro_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
66macro_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.
84macro_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.
149macro_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