Ticket #1021: bug_report_example_skeleton.hpp

File bug_report_example_skeleton.hpp, 10.3 KB (added by anonymous, 15 years ago)
Line 
1#include <boost/property_map.hpp>
2#include <boost/graph/properties.hpp>
3#include <boost/graph/adjacency_iterator.hpp>
4#include <vector>
5
6/// A skeleton user defined graph not using any of the builtin Boost Graph Library graph types.
7namespace MyGraph {
8
9 class Graph;
10 class Vertex;
11 class Edge;
12
13 typedef Vertex* VertexDesc;
14 typedef Edge* EdgeDesc;
15 typedef std::vector<EdgeDesc>::iterator EdgeIterator;
16 typedef std::vector<VertexDesc>::iterator VertexIterator;
17
18 class Vertex {
19 public:
20 unsigned int index();
21 std::pair<EdgeIterator, EdgeIterator> outEdges() const;
22 std::pair<EdgeIterator, EdgeIterator> inEdges() const;
23 unsigned int outEdgeCount() const;
24 unsigned int inEdgeCount() const;
25 EdgeIterator outEdgeBegin() const;
26 EdgeIterator outEdgeEnd() const;
27 EdgeIterator inEdgeBegin() const;
28 EdgeIterator inEdgeEnd() const;
29 void clearEdges();
30 };
31
32 class Edge {
33 public:
34 unsigned int index() const;
35 VertexDesc source() const;
36 VertexDesc target() const;
37 };
38
39 class Graph {
40 public:
41 std::pair<EdgeIterator, EdgeIterator> edges() const;
42 std::pair<VertexIterator, VertexIterator> vertices() const;
43 unsigned int vertexCount() const;
44 unsigned int edgeCount() const;
45 std::pair<EdgeDesc, bool> findEdge(VertexDesc source, VertexDesc target) const;
46 VertexDesc addVertex();
47 void removeVertex(VertexDesc vertex);
48 std::pair<EdgeDesc, bool> addEdge(VertexDesc source, VertexDesc target);
49 void removeEdge(EdgeDesc edge);
50 };
51
52} // namespace MyGraph
53
54/// An adapter to allow the user defined graph MyGraph to be used as a Boost Graph.
55namespace boost {
56
57 /// The Boost Graph Library algorithms use graph_traits to obtain
58 /// information about the types to use to access the graph.
59 template <>
60 struct graph_traits<MyGraph::Graph> {
61
62 // Our user defined graph models all of the following concepts:
63 struct bidir_adj_list_traversal_tag :
64 public virtual vertex_list_graph_tag,
65 public virtual incidence_graph_tag,
66 public virtual adjacency_graph_tag,
67 public virtual edge_list_graph_tag,
68 public virtual bidirectional_graph_tag { };
69
70 // Graph requires:
71 typedef MyGraph::VertexDesc vertex_descriptor;
72 typedef MyGraph::EdgeDesc edge_descriptor;
73 typedef directed_tag directed_category;
74 typedef disallow_parallel_edge_tag edge_parallel_category;
75 typedef bidir_adj_list_traversal_tag traversal_category;
76
77 static inline vertex_descriptor null_vertex()
78 {
79 return MyGraph::VertexDesc(0);
80 }
81
82 // IncidenceGraph requires:
83 typedef MyGraph::EdgeIterator out_edge_iterator;
84 typedef unsigned int degree_size_type;
85
86 // BidirectionalGraph requires:
87 typedef MyGraph::EdgeIterator in_edge_iterator;
88
89 // Adjacency Graph requires:
90 typedef adjacency_iterator_generator
91 <MyGraph::Graph, vertex_descriptor, out_edge_iterator>::type
92 adjacency_iterator;
93
94 // VertexListGraph requires:
95 typedef MyGraph::VertexIterator vertex_iterator;
96 typedef unsigned int vertices_size_type;
97
98 // EdgeListGraph requires:
99 typedef MyGraph::EdgeIterator edge_iterator;
100 typedef unsigned int edges_size_type;
101 };
102
103} // namespace boost
104
105/// In addition we must provide the following operations.
106/// These definitions are logically part of MyGraph.
107namespace MyGraph {
108
109 /// IncidenceGraph refines Graph requires:
110 inline
111 std::pair<boost::graph_traits<MyGraph::Graph>::out_edge_iterator,
112 boost::graph_traits<MyGraph::Graph>::out_edge_iterator>
113 out_edges(boost::graph_traits<MyGraph::Graph>::vertex_descriptor v, const MyGraph::Graph& g)
114 {
115 return v->outEdges();
116 }
117
118 inline
119 boost::graph_traits<MyGraph::Graph>::vertex_descriptor
120 source(boost::graph_traits<MyGraph::Graph>::edge_descriptor e, const MyGraph::Graph& g)
121 {
122 return e->source();
123 }
124
125 inline
126 boost::graph_traits<MyGraph::Graph>::vertex_descriptor
127 target(boost::graph_traits<MyGraph::Graph>::edge_descriptor e, const MyGraph::Graph& g)
128 {
129 return e->target();
130 }
131
132 inline
133 boost::graph_traits<MyGraph::Graph>::degree_size_type
134 out_degree(boost::graph_traits<MyGraph::Graph>::vertex_descriptor v, const MyGraph::Graph& g)
135 {
136 return v->outEdgeCount();
137 }
138
139
140 /// BidirectionalGraph refines IncidenceGraph and requires:
141 inline
142 std::pair<boost::graph_traits<MyGraph::Graph>::in_edge_iterator, boost::graph_traits<MyGraph::Graph>::in_edge_iterator>
143 in_edges(boost::graph_traits<MyGraph::Graph>::vertex_descriptor v, const MyGraph::Graph& g)
144 {
145 return v->inEdges();
146 }
147
148 inline
149 boost::graph_traits<MyGraph::Graph>::degree_size_type
150 in_degree(boost::graph_traits<MyGraph::Graph>::vertex_descriptor v, const MyGraph::Graph& g)
151 {
152 return v->inEdgeCount();
153 }
154
155 inline
156 boost::graph_traits<MyGraph::Graph>::degree_size_type
157 degree(boost::graph_traits<MyGraph::Graph>::vertex_descriptor v, const MyGraph::Graph& g)
158 {
159 return in_degree(v, g) + out_degree(v, g);
160 }
161
162 /// AdjacencyGraph refines Graph and requires:
163 inline
164 std::pair<boost::graph_traits<MyGraph::Graph>::adjacency_iterator, boost::graph_traits<MyGraph::Graph>::adjacency_iterator>
165 adjacent_vertices(boost::graph_traits<MyGraph::Graph>::vertex_descriptor v, const MyGraph::Graph& g)
166 {
167 boost::graph_traits<MyGraph::Graph>::adjacency_iterator begin(v->outEdgeBegin(), &g);
168 boost::graph_traits<MyGraph::Graph>::adjacency_iterator end(v->outEdgeEnd(), &g);
169 return std::make_pair(begin, end);
170 }
171
172 /// VertexListGraph refines IncidenceGraph and AdjacencyGraph and requires:
173 inline
174 std::pair<boost::graph_traits<MyGraph::Graph>::vertex_iterator, boost::graph_traits<MyGraph::Graph>::vertex_iterator>
175 vertices(const MyGraph::Graph& g)
176 {
177 return g.vertices();
178 }
179
180 inline
181 boost::graph_traits<MyGraph::Graph>::vertices_size_type
182 num_vertices(const MyGraph::Graph& g)
183 {
184 return g.vertexCount();
185 }
186
187 /// EdgeListGraph refines Graph and requires:
188 inline
189 std::pair<boost::graph_traits<MyGraph::Graph>::edge_iterator, boost::graph_traits<MyGraph::Graph>::edge_iterator>
190 edges(const MyGraph::Graph& g)
191 {
192 return g.edges();
193 }
194
195 inline
196 boost::graph_traits<MyGraph::Graph>::edges_size_type
197 num_edges(const MyGraph::Graph& g)
198 {
199 return g.edgeCount();
200 }
201
202 /// AdjacencyMatrix refines Graph and requires:
203 inline
204 std::pair<boost::graph_traits<MyGraph::Graph>::edge_descriptor, bool>
205 edge(boost::graph_traits<MyGraph::Graph>::vertex_descriptor u,
206 boost::graph_traits<MyGraph::Graph>::vertex_descriptor v, const MyGraph::Graph& g)
207 {
208 return g.findEdge(u, v);
209 }
210
211 /// MutableGraph refines Graph and requires:
212 inline
213 boost::graph_traits<MyGraph::Graph>::vertex_descriptor
214 add_vertex(MyGraph::Graph& g)
215 {
216 return g.addVertex();
217 }
218
219 inline
220 void
221 clear_vertex(boost::graph_traits<MyGraph::Graph>::vertex_descriptor v, MyGraph::Graph& g)
222 {
223 v->clearEdges();
224 }
225
226 inline
227 void
228 remove_vertex(boost::graph_traits<MyGraph::Graph>::vertex_descriptor v, MyGraph::Graph& g)
229 {
230 g.removeVertex(v);
231 }
232
233 inline
234 std::pair<boost::graph_traits<MyGraph::Graph>::edge_descriptor, bool>
235 add_edge(boost::graph_traits<MyGraph::Graph>::vertex_descriptor u, boost::graph_traits<MyGraph::Graph>::vertex_descriptor v,
236 MyGraph::Graph& g)
237 {
238 return g.addEdge(u, v);
239 }
240
241 inline
242 void
243 remove_edge(boost::graph_traits<MyGraph::Graph>::vertex_descriptor u, boost::graph_traits<MyGraph::Graph>::vertex_descriptor v,
244 MyGraph::Graph& g)
245 {
246 std::pair<MyGraph::EdgeDesc, bool> edge_pair = g.findEdge(u, v);
247 if (edge_pair.second){
248 g.removeEdge(edge_pair.first);
249 }
250
251 }
252
253 inline
254 void
255 remove_edge(boost::graph_traits<MyGraph::Graph>::edge_descriptor e, MyGraph::Graph& g)
256 {
257 g.removeEdge(e);
258 }
259
260 inline
261 void
262 remove_edge(boost::graph_traits<MyGraph::Graph>::edge_iterator e_iter, MyGraph::Graph& g)
263 {
264 g.removeEdge(*e_iter);
265 }
266
267 /// We also need to provide the predefined property maps used by the algorithms we will use.
268
269 /// The vertex_index_t property map:
270 class VertexDescMap
271 : public boost::put_get_helper<unsigned int, VertexDescMap>
272 {
273 public:
274 typedef boost::readable_property_map_tag category;
275 typedef unsigned int value_type;
276 typedef unsigned int reference;
277 typedef MyGraph::VertexDesc key_type;
278 VertexDescMap()
279 {
280 }
281 VertexDescMap(const MyGraph::Graph& g)
282 {
283 }
284
285 unsigned int operator[](key_type v) const
286 {
287 return v->index();
288 }
289 };
290
291 inline
292 VertexDescMap
293 get(boost::vertex_index_t, const MyGraph::Graph& g)
294 {
295 return VertexDescMap(g);
296 }
297
298 /// The edge_index_t property map:
299 class EdgeDescMap
300 : public boost::put_get_helper<EdgeDesc, EdgeDescMap>
301 {
302 public:
303 typedef boost::readable_property_map_tag category;
304 typedef unsigned int value_type;
305 typedef unsigned int reference;
306 typedef MyGraph::EdgeDesc key_type;
307 EdgeDescMap()
308 {
309 }
310 EdgeDescMap(const MyGraph::Graph& g)
311 {
312 }
313
314 unsigned int operator[](key_type e) const
315 {
316 return e->index();
317 }
318 };
319
320 inline
321 EdgeDescMap
322 get(boost::edge_index_t, const MyGraph::Graph& g)
323 {
324 return EdgeDescMap(g);
325 }
326
327} // namespace MyGraph
328
329/// We must also provide specializations for property_map for our
330/// graph for the predefined property maps we support.
331///
332/// NOTE: This mechanism is not currently described in the
333/// documentation on how to provide an adapter for a user defined
334/// graph.
335namespace boost {
336
337 template<>
338 struct property_map<MyGraph::Graph, vertex_index_t>
339 {
340 typedef MyGraph::VertexDescMap type;
341
342 /// The BGL graphs all seem to define their
343 /// property_map<...>::const_type the same as their
344 /// property_map<...>::type (ie both non-const). It seems that
345 /// ::const_type ought to be the const version of ::type.
346 /// However, making it a const type results in
347 /// make_iterator_property_map not working.
348 typedef const MyGraph::VertexDescMap const_type;
349 };
350
351 /// We also provide a specialization for the edge_index_t which serves
352 /// the same purpose as vertex_index_t except for the edges.
353 template<>
354 struct property_map<MyGraph::Graph, edge_index_t>
355 {
356 typedef MyGraph::EdgeDescMap type;
357 typedef const MyGraph::EdgeDescMap const_type;
358 };
359
360} // namespace boost