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, $(#[$attr:meta])+) => {
5
        $(#[$attr])+
6
        impl const $imp for &$t {
7
            type Output = <$t as $imp>::Output;
8

            
9
            #[inline]
10
            fn $method(self) -> <$t as $imp>::Output {
11
                $imp::$method(*self)
12
            }
13
        }
14
    }
15
}
16

            
17
// implements binary operators "&T op U", "T op &U", "&T op &U"
18
// based on "T op U" where T and U are expected to be `Copy`able
19
macro_rules! forward_ref_binop {
20
    (impl $imp:ident, $method:ident for $t:ty, $u:ty, $(#[$attr:meta])+) => {
21
        $(#[$attr])+
22
        impl const $imp<$u> for &$t {
23
            type Output = <$t as $imp<$u>>::Output;
24

            
25
            #[inline]
26
            #[track_caller]
27
12000002
            fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
28
12000002
                $imp::$method(*self, other)
29
12000002
            }
30
        }
31

            
32
        $(#[$attr])+
33
        impl const $imp<&$u> for $t {
34
            type Output = <$t as $imp<$u>>::Output;
35

            
36
            #[inline]
37
            #[track_caller]
38
            fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
39
                $imp::$method(self, *other)
40
            }
41
        }
42

            
43
        $(#[$attr])+
44
        impl const $imp<&$u> for &$t {
45
            type Output = <$t as $imp<$u>>::Output;
46

            
47
            #[inline]
48
            #[track_caller]
49
1
            fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
50
1
                $imp::$method(*self, *other)
51
1
            }
52
        }
53
    }
54
}
55

            
56
// implements "T op= &U", based on "T op= U"
57
// where U is expected to be `Copy`able
58
macro_rules! forward_ref_op_assign {
59
    (impl $imp:ident, $method:ident for $t:ty, $u:ty, $(#[$attr:meta])+) => {
60
        $(#[$attr])+
61
        impl const $imp<&$u> for $t {
62
            #[inline]
63
            #[track_caller]
64
9993
            fn $method(&mut self, other: &$u) {
65
9993
                $imp::$method(self, *other);
66
9993
            }
67
        }
68
    }
69
}
70

            
71
/// Creates a zero-size type similar to a closure type, but named.
72
#[cfg(not(feature = "ferrocene_certified"))]
73
macro_rules! impl_fn_for_zst {
74
    ($(
75
        $( #[$attr: meta] )*
76
        struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
77
            |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
78
            $body: block;
79
    )+) => {
80
        $(
81
            $( #[$attr] )*
82
            struct $Name;
83

            
84
            impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name {
85
                #[inline]
86
                extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
87
                    $body
88
                }
89
            }
90

            
91
            impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name {
92
                #[inline]
93
                extern "rust-call" fn call_mut(
94
                    &mut self,
95
                    ($( $arg, )*): ($( $ArgTy, )*)
96
                ) -> $ReturnTy {
97
                    Fn::call(&*self, ($( $arg, )*))
98
                }
99
            }
100

            
101
            impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name {
102
                type Output = $ReturnTy;
103

            
104
                #[inline]
105
                extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
106
                    Fn::call(&self, ($( $arg, )*))
107
                }
108
            }
109
        )+
110
    }
111
}