]> git.proxmox.com Git - rustc.git/blob - vendor/petgraph/src/visit/macros.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / vendor / petgraph / src / visit / macros.rs
1
2 /// Define a trait as usual, and a macro that can be used to instantiate
3 /// implementations of it.
4 ///
5 /// There *must* be section markers in the trait defition:
6 /// @section type for associated types
7 /// @section self for methods
8 /// @section nodelegate for arbitrary tail that is not forwarded.
9 macro_rules! trait_template {
10 ($(#[$doc:meta])* pub trait $name:ident $($methods:tt)*) => {
11 macro_rules! $name {
12 ($m:ident $extra:tt) => {
13 $m! {
14 $extra
15 pub trait $name $($methods)*
16 }
17 }
18 }
19
20 remove_sections! { []
21 $(#[$doc])*
22 pub trait $name $($methods)*
23
24 // This is where the trait definition is reproduced by the macro.
25 // It makes the source links point to this place!
26 //
27 // I'm sorry, you'll have to find the source by looking at the
28 // source of the module the trait is defined in.
29 //
30 // We use this nifty macro so that we can automatically generate
31 // delegation trait impls and implement the graph traits for more
32 // types and combinators.
33 }
34 }
35 }
36
37 macro_rules! remove_sections_inner {
38 ([$($stack:tt)*]) => {
39 $($stack)*
40 };
41 // escape the following tt
42 ([$($stack:tt)*] @escape $_x:tt $($t:tt)*) => {
43 remove_sections_inner!([$($stack)*] $($t)*);
44 };
45 ([$($stack:tt)*] @section $x:ident $($t:tt)*) => {
46 remove_sections_inner!([$($stack)*] $($t)*);
47 };
48 ([$($stack:tt)*] $t:tt $($tail:tt)*) => {
49 remove_sections_inner!([$($stack)* $t] $($tail)*);
50 };
51 }
52
53 // This is the outer layer, just find the { } of the actual trait definition
54 // recurse once into { }, but not more.
55 macro_rules! remove_sections {
56 ([$($stack:tt)*]) => {
57 $($stack)*
58 };
59 ([$($stack:tt)*] { $($tail:tt)* }) => {
60 $($stack)* {
61 remove_sections_inner!([] $($tail)*);
62 }
63 };
64 ([$($stack:tt)*] $t:tt $($tail:tt)*) => {
65 remove_sections!([$($stack)* $t] $($tail)*);
66 };
67 }
68
69 macro_rules! deref {
70 ($e:expr) => (*$e);
71 }
72 macro_rules! deref_twice {
73 ($e:expr) => (**$e);
74 }
75
76 /// Implement a trait by delegation. By default as if we are delegating
77 /// from &G to G.
78 macro_rules! delegate_impl {
79 ([] $($rest:tt)*) => {
80 delegate_impl! { [['a, G], G, &'a G, deref] $($rest)* }
81 };
82 ([[$($param:tt)*], $self_type:ident, $self_wrap:ty, $self_map:ident]
83 pub trait $name:ident $(: $sup:ident)* $(+ $more_sup:ident)* {
84
85 // "Escaped" associated types. Stripped before making the `trait`
86 // itself, but forwarded when delegating impls.
87 $(
88 @escape [type $assoc_name_ext:ident]
89 // Associated types. Forwarded.
90 )*
91 $(
92 @section type
93 $(
94 $(#[$_assoc_attr:meta])*
95 type $assoc_name:ident $(: $assoc_bound:ty)*;
96 )+
97 )*
98 // Methods. Forwarded. Using $self_map!(self) around the self argument.
99 // Methods must use receiver `self` or explicit type like `self: &Self`
100 // &self and &mut self are _not_ supported.
101 $(
102 @section self
103 $(
104 $(#[$_method_attr:meta])*
105 fn $method_name:ident(self $(: $self_selftype:ty)* $(,$marg:ident : $marg_ty:ty)*) -> $mret:ty;
106 )+
107 )*
108 // Arbitrary tail that is ignored when forwarding.
109 $(
110 @section nodelegate
111 $($tail:tt)*
112 )*
113 }) => {
114 impl<$($param)*> $name for $self_wrap where $self_type: $name {
115 $(
116 $(
117 type $assoc_name = $self_type::$assoc_name;
118 )*
119 )*
120 $(
121 type $assoc_name_ext = $self_type::$assoc_name_ext;
122 )*
123 $(
124 $(
125 fn $method_name(self $(: $self_selftype)* $(,$marg: $marg_ty)*) -> $mret {
126 $self_map!(self).$method_name($($marg),*)
127 }
128 )*
129 )*
130 }
131 }
132 }
133