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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
// 基于 "op T" 实现一元运算符 "op &T",其中 T 应该是可复制的
//
macro_rules! forward_ref_unop {
(impl $imp:ident, $method:ident for $t:ty) => {
forward_ref_unop!(impl $imp, $method for $t,
#[stable(feature = "rust1", since = "1.0.0")]);
};
(impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => {
#[$attr]
impl $imp for &$t {
type Output = <$t as $imp>::Output;
#[inline]
fn $method(self) -> <$t as $imp>::Output {
$imp::$method(*self)
}
}
}
}
// 基于 "T op U" 实现二进制运算符 "&T op U","T op &U","&T op &U",其中 T 和 U 应该是可复制的
//
macro_rules! forward_ref_binop {
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
forward_ref_binop!(impl $imp, $method for $t, $u,
#[stable(feature = "rust1", since = "1.0.0")]);
};
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
impl<'a> $imp<$u> for &'a $t {
type Output = <$t as $imp<$u>>::Output;
#[inline]
fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
$imp::$method(*self, other)
}
}
#[$attr]
impl $imp<&$u> for $t {
type Output = <$t as $imp<$u>>::Output;
#[inline]
fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
$imp::$method(self, *other)
}
}
#[$attr]
impl $imp<&$u> for &$t {
type Output = <$t as $imp<$u>>::Output;
#[inline]
fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
$imp::$method(*self, *other)
}
}
}
}
// 基于 "T op= U" 实现 "T op= &U",其中 U 应该是可复制的
//
macro_rules! forward_ref_op_assign {
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
forward_ref_op_assign!(impl $imp, $method for $t, $u,
#[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]);
};
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
impl $imp<&$u> for $t {
#[inline]
fn $method(&mut self, other: &$u) {
$imp::$method(self, *other);
}
}
}
}
/// 创建一个与闭包类型相似的零大小类型,但命名为。
macro_rules! impl_fn_for_zst {
($(
$( #[$attr: meta] )*
struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
|$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
$body: block;
)+) => {
$(
$( #[$attr] )*
struct $Name;
impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name {
#[inline]
extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
$body
}
}
impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name {
#[inline]
extern "rust-call" fn call_mut(
&mut self,
($( $arg, )*): ($( $ArgTy, )*)
) -> $ReturnTy {
Fn::call(&*self, ($( $arg, )*))
}
}
impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name {
type Output = $ReturnTy;
#[inline]
extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
Fn::call(&self, ($( $arg, )*))
}
}
)+
}
}
/// 用于定义 `#[cfg]` if-else 语句的宏。
///
/// `cfg_if` 类似于 `if/elif` C 预处理器宏,允许定义级联的 `#[cfg]` 情况,并发出首先匹配的实现。
///
///
/// 这使您可以方便地提供一长串 `#[cfg]` 代码块,而无需多次重写每个子句。
///
/// # Example
///
/// ```ignore(cannot-test-this-because-non-exported-macro)
/// cfg_if! {
/// if #[cfg(unix)] {
/// fn foo() { /* unix specific functionality */ }
/// } else if #[cfg(target_pointer_width = "32")] {
/// fn foo() { /* non-unix, 32-bit functionality */ }
/// } else {
/// fn foo() { /* fallback implementation */ }
/// }
/// }
///
/// # fn main() {}
/// ```
///
// 这是来自 `cfg_if` crate 的 `cfg_if!` 的副本。
// 如果它曾经被导出的话,递归调用应该使用 $crate。
macro_rules! cfg_if {
// 将 if/else 链与最后的 `else` 匹配
(
$(
if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
) else+
else { $( $e_tokens:tt )* }
) => {
cfg_if! {
@__items () ;
$(
(( $i_meta ) ( $( $i_tokens )* )) ,
)+
(() ( $( $e_tokens )* )) ,
}
};
// 用于发出所有项的内部宏和递归宏
//
// 在开始时将所有先前的 cfgs 收集在一个列表中,这样就可以对它们求反。
// 分号后是所有剩余的项。
(@__items ( $( $_:meta , )* ) ; ) => {};
(
@__items ( $( $no:meta , )* ) ;
(( $( $yes:meta )? ) ( $( $tokens:tt )* )) ,
$( $rest:tt , )*
) => {
// 应用适当的 #[cfg],发出一个块内的所有项。
// #[cfg] 将要求指定所有 `$yes` 匹配器,并且还必须否定所有以前的匹配器。
//
#[cfg(all(
$( $yes , )?
not(any( $( $no ),* ))
))]
cfg_if! { @__identity $( $tokens )* }
// 递归发射 `$rest` 中的所有其他项,当我们这样做时,将所有 `$yes` 匹配器添加到 `$no` 匹配器列表中,因为 future 发射也必须否定我们刚刚匹配的所有内容。
//
//
cfg_if! {
@__items ( $( $no , )* $( $yes , )? ) ;
$( $rest , )*
}
};
// 使 __apply 适合不同匹配类型的内部宏,因为宏是匹配或扩展内容的。
//
(@__identity $( $tokens:tt )* ) => {
$( $tokens )*
};
}