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 | /// Creates 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 | |