graphene/core/
graph_wrapper.rs

1use super::*;
2
3///
4/// Implements a method for the wrapped graph:
5///
6/// Syntax:
7///
8/// ``` text
9/// unsafe? <method name>( <type of self> self
10/// (, <args>)* -> <return type>
11/// ```
12/// expands to:
13///
14/// ``` text
15/// unsafe? fn (<type of self> self <, <args>>*) -> <return type>{
16/// 	self.wrapped().<method name>( (<args>,)*)
17/// }
18/// ```
19///
20#[macro_export]
21macro_rules! wrapped_method {
22	{
23		$fn_name:ident( &self
24			$(, $arg_name:ident : $arg_type:ty)*) -> $ret:ty
25	} => {
26		fn $fn_name(&self, $($arg_name : $arg_type),*) -> $ret {
27			self.wrapped().$fn_name($($arg_name),*)
28		}
29	};
30	{
31		$fn_name:ident( & mut self
32			$(, $arg_name:ident : $arg_type:ty)*) -> $ret:ty
33	} => {
34		fn $fn_name(& mut self, $($arg_name : $arg_type),*) -> $ret {
35			self.wrapped_mut().$fn_name($($arg_name),*)
36		}
37	};
38	{
39		unsafe $fn_name:ident( &self
40			$(, $arg_name:ident : $arg_type:ty)*) -> $ret:ty
41	} => {
42		unsafe fn $fn_name(&self, $($arg_name : $arg_type),*) -> $ret {
43			self.wrapped().$fn_name($($arg_name),*)
44		}
45	};
46	{
47		unsafe $fn_name:ident( & mut self
48			$(, $arg_name:ident : $arg_type:ty)*) -> $ret:ty
49	} => {
50		unsafe fn $fn_name(& mut self, $($arg_name : $arg_type),*) -> $ret {
51			self.wrapped_mut().$fn_name($($arg_name),*)
52		}
53	};
54}
55
56///
57/// Implements the four uncon_* methods from `ConstrainedGraph` for a graph using `wrapped_method!`.
58/// Must be called inside an impl of `ConstrainedGraph`.
59///
60#[macro_export]
61macro_rules! wrapped_uncon_methods{
62	{
63	} => {
64		wrapped_method!{unsafe uncon_add_vertex(&mut self, v: Self::Vertex) -> Result<(), ()>}
65	
66		wrapped_method!{unsafe uncon_remove_vertex(&mut self, v: Self::Vertex) -> Result<(), ()>}
67	
68		wrapped_method!{unsafe uncon_add_edge(&mut self, e: $crate::core::BaseEdge<Self::Vertex, Self::Weight>) -> Result<(), ()>}
69	
70		wrapped_method!{unsafe uncon_remove_edge(&mut self, e: $crate::core::BaseEdge<Self::Vertex, Self::Weight>) -> Result<(), ()>}
71	}
72}
73
74///
75/// Implements `BaseGraph` for a `GraphWrapper` by having all methods
76/// call the corresponding wrapped graph methods.
77///
78#[macro_export]
79macro_rules! impl_BaseGraph_for_wrapper{
80	{
81		$graph_name:ident
82	} => {
83		impl<G> $crate::core::BaseGraph for $graph_name<G>
84			where
85				G: $crate::core::ConstrainedGraph,
86				<G as $crate::core::BaseGraph>::Vertex: Vertex,
87				<G as $crate::core::BaseGraph>::Weight: Weight,
88				<<G as $crate::core::BaseGraph>::VertexIter as IntoIterator>::IntoIter: ExactSizeIterator,
89				<<G as $crate::core::BaseGraph>::EdgeIter as IntoIterator>::IntoIter: ExactSizeIterator,
90		{
91			type Vertex = <G as $crate::core::BaseGraph>::Vertex;
92			type Weight = <G as $crate::core::BaseGraph>::Weight;
93			type VertexIter = <G as $crate::core::BaseGraph>::VertexIter;
94			type EdgeIter = <G as $crate::core::BaseGraph>::EdgeIter;
95			
96			fn empty_graph() -> Self{
97				$graph_name::wrap(G::empty_graph())
98			}
99		
100			wrapped_method!{all_vertices(&self) -> Self::VertexIter}
101			
102			wrapped_method!{all_edges(&self) -> Self::EdgeIter}
103			
104			wrapped_method!{add_vertex(&mut self, v: Self::Vertex) -> Result<(), ()>}
105			
106			wrapped_method!{remove_vertex(&mut self, v: Self::Vertex) -> Result<(), ()>}
107			
108			wrapped_method!{add_edge(&mut self, e: $crate::core::BaseEdge<Self::Vertex, Self::Weight>) -> Result<(), ()>}
109			
110			wrapped_method!{remove_edge(&mut self, e: $crate::core::BaseEdge<Self::Vertex, Self::Weight>) -> Result<(), ()>}
111		}
112	}
113}
114
115///
116/// Implements `ConstrainedGraph` for a `GraphWrapper` by having all methods
117/// call the corresponding wrapped graph methods.
118///
119#[macro_export]
120macro_rules! impl_ConstrainedGraph_for_wrapper{
121	{
122	$graph_name:ident
123	} => {
124		impl<G> $crate::core::ConstrainedGraph for $graph_name<G>
125			where
126				G: $crate::core::ConstrainedGraph,
127				<G as $crate::core::BaseGraph>::Vertex: Vertex,
128				<G as $crate::core::BaseGraph>::Weight: Weight,
129				<<G as $crate::core::BaseGraph>::VertexIter as IntoIterator>::IntoIter: ExactSizeIterator,
130				<<G as $crate::core::BaseGraph>::EdgeIter as IntoIterator>::IntoIter: ExactSizeIterator,
131		{
132			wrapped_method!{invariant_holds(&self) -> bool}
133		
134			wrapped_uncon_methods!{}
135		}
136	}
137}
138
139///
140/// Implements the given list of constraints for the given GraphWrapper,
141/// which must be generic over a `ContainedGraph` (`<G>`).
142///
143#[macro_export]
144macro_rules! impl_constraints_for_wrapper{
145	{
146		// Name of the resulting graph.
147		$graph_name:ident
148		
149		// Name of the constraint implementations
150		: $($con_trait:ident),+
151	} => {
152		$(
153			impl<G> $con_trait for $graph_name<G>
154				where
155					G: $crate::core::ConstrainedGraph,
156					<G as $crate::core::BaseGraph>::Vertex: Vertex,
157					<G as $crate::core::BaseGraph>::Weight: Weight,
158					<<G as $crate::core::BaseGraph>::VertexIter as IntoIterator>::IntoIter: ExactSizeIterator,
159					<<G as $crate::core::BaseGraph>::EdgeIter as IntoIterator>::IntoIter: ExactSizeIterator,
160			{}
161		)*
162	}
163}
164
165///
166/// Defines a new public struct with implements `GraphWrapper`.
167/// The struct is generic over any `ConstrainedGraph` G.
168///
169#[macro_export]
170macro_rules! graph_wrapper{
171	{
172		$(#[$attr:meta])*
173		struct $graph_name:ident
174	} =>{
175		$(#[$attr])*
176		#[derive(Debug, Clone)]
177		pub struct $graph_name<G>
178			where
179				G: $crate::core::ConstrainedGraph,
180				<G as $crate::core::BaseGraph>::Vertex: Vertex,
181				<G as $crate::core::BaseGraph>::Weight: Weight,
182				<<G as $crate::core::BaseGraph>::VertexIter as IntoIterator>::IntoIter: ExactSizeIterator,
183				<<G as $crate::core::BaseGraph>::EdgeIter as IntoIterator>::IntoIter: ExactSizeIterator,
184		{
185			wraps: G
186		}
187		
188		impl<G> $crate::core::GraphWrapper for $graph_name<G>
189			where
190				G: $crate::core::ConstrainedGraph,
191				<G as $crate::core::BaseGraph>::Vertex: Vertex,
192				<G as $crate::core::BaseGraph>::Weight: Weight,
193				<<G as $crate::core::BaseGraph>::VertexIter as IntoIterator>::IntoIter: ExactSizeIterator,
194				<<G as $crate::core::BaseGraph>::EdgeIter as IntoIterator>::IntoIter: ExactSizeIterator,
195		{
196			
197			type Wrapped = G;
198			
199			fn wrap(g: Self::Wrapped) -> Self{
200				$graph_name{wraps: g}
201			}
202			
203			fn wrapped(&self) -> &Self::Wrapped{
204				&self.wraps
205			}
206			
207			fn wrapped_mut(&mut self) -> &mut Self::Wrapped{
208				&mut self.wraps
209			}
210			
211			fn unwrap(self) -> Self::Wrapped{
212				self.wraps
213			}
214		}
215	};
216}
217
218///
219/// Defines a type that wraps a `ConstrainedGraph`.
220///
221pub trait GraphWrapper
222	where
223		<Self::Wrapped as BaseGraph>::Vertex: Vertex,
224		<Self::Wrapped as BaseGraph>::Weight: Weight,
225		<<Self::Wrapped as BaseGraph>::VertexIter as IntoIterator>::IntoIter: ExactSizeIterator,
226		<<Self::Wrapped as BaseGraph>::EdgeIter as IntoIterator>::IntoIter: ExactSizeIterator,
227{
228	type Wrapped: 	ConstrainedGraph;
229	
230	fn wrap(g: Self::Wrapped) -> Self;
231	
232	fn wrapped(&self) -> &Self::Wrapped;
233	
234	fn wrapped_mut(&mut self) -> &mut Self::Wrapped;
235	
236	fn unwrap(self) -> Self::Wrapped;
237}
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266