Chris@16
|
1 // Copyright (C) 2009 Andrew Sutton
|
Chris@16
|
2
|
Chris@16
|
3 // Use, modification and distribution is subject to the Boost Software
|
Chris@16
|
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
5 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6
|
Chris@16
|
7 #ifndef BOOST_GRAPH_LABELED_GRAPH_HPP
|
Chris@16
|
8 #define BOOST_GRAPH_LABELED_GRAPH_HPP
|
Chris@16
|
9
|
Chris@16
|
10 #include <boost/config.hpp>
|
Chris@16
|
11 #include <vector>
|
Chris@16
|
12 #include <map>
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/static_assert.hpp>
|
Chris@16
|
15 #include <boost/mpl/if.hpp>
|
Chris@16
|
16 #include <boost/mpl/bool.hpp>
|
Chris@16
|
17 #include <boost/unordered_map.hpp>
|
Chris@16
|
18 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
19 #include <boost/type_traits/is_unsigned.hpp>
|
Chris@16
|
20 #include <boost/pending/container_traits.hpp>
|
Chris@16
|
21 #include <boost/graph/graph_traits.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 // This file implements a utility for creating mappings from arbitrary
|
Chris@16
|
24 // identifiers to the vertices of a graph.
|
Chris@16
|
25
|
Chris@16
|
26 namespace boost {
|
Chris@16
|
27
|
Chris@16
|
28 // A type selector that denotes the use of some default value.
|
Chris@16
|
29 struct defaultS { };
|
Chris@16
|
30
|
Chris@16
|
31 /** @internal */
|
Chris@16
|
32 namespace graph_detail {
|
Chris@16
|
33 /** Returns true if the selector is the default selector. */
|
Chris@16
|
34 template <typename Selector>
|
Chris@16
|
35 struct is_default
|
Chris@16
|
36 : mpl::bool_<is_same<Selector, defaultS>::value>
|
Chris@16
|
37 { };
|
Chris@16
|
38
|
Chris@16
|
39 /**
|
Chris@16
|
40 * Choose the default map instance. If Label is an unsigned integral type
|
Chris@16
|
41 * the we can use a vector to store the information.
|
Chris@16
|
42 */
|
Chris@16
|
43 template <typename Label, typename Vertex>
|
Chris@16
|
44 struct choose_default_map {
|
Chris@16
|
45 typedef typename mpl::if_<
|
Chris@16
|
46 is_unsigned<Label>,
|
Chris@16
|
47 std::vector<Vertex>,
|
Chris@16
|
48 std::map<Label, Vertex> // TODO: Should use unordered_map?
|
Chris@16
|
49 >::type type;
|
Chris@16
|
50 };
|
Chris@16
|
51
|
Chris@16
|
52 /**
|
Chris@16
|
53 * @name Generate Label Map
|
Chris@16
|
54 * These type generators are responsible for instantiating an associative
|
Chris@16
|
55 * container for the the labeled graph. Note that the Selector must be
|
Chris@16
|
56 * select a pair associative container or a vecS, which is only valid if
|
Chris@16
|
57 * Label is an integral type.
|
Chris@16
|
58 */
|
Chris@16
|
59 //@{
|
Chris@16
|
60 template <typename Selector, typename Label, typename Vertex>
|
Chris@16
|
61 struct generate_label_map { };
|
Chris@16
|
62
|
Chris@16
|
63 template <typename Label, typename Vertex>
|
Chris@16
|
64 struct generate_label_map<vecS, Label, Vertex>
|
Chris@16
|
65 { typedef std::vector<Vertex> type; };
|
Chris@16
|
66
|
Chris@16
|
67 template <typename Label, typename Vertex>
|
Chris@16
|
68 struct generate_label_map<mapS, Label, Vertex>
|
Chris@16
|
69 { typedef std::map<Label, Vertex> type; };
|
Chris@16
|
70
|
Chris@16
|
71 template <typename Label, typename Vertex>
|
Chris@16
|
72 struct generate_label_map<multimapS, Label, Vertex>
|
Chris@16
|
73 { typedef std::multimap<Label, Vertex> type; };
|
Chris@16
|
74
|
Chris@16
|
75 template <typename Label, typename Vertex>
|
Chris@16
|
76 struct generate_label_map<hash_mapS, Label, Vertex>
|
Chris@16
|
77 { typedef boost::unordered_map<Label, Vertex> type; };
|
Chris@16
|
78
|
Chris@16
|
79 template <typename Label, typename Vertex>
|
Chris@16
|
80 struct generate_label_map<hash_multimapS, Label, Vertex>
|
Chris@16
|
81 { typedef boost::unordered_multimap<Label, Vertex> type; };
|
Chris@16
|
82
|
Chris@16
|
83 template <typename Selector, typename Label, typename Vertex>
|
Chris@16
|
84 struct choose_custom_map {
|
Chris@16
|
85 typedef typename generate_label_map<Selector, Label, Vertex>::type type;
|
Chris@16
|
86 };
|
Chris@16
|
87 //@}
|
Chris@16
|
88
|
Chris@16
|
89 /**
|
Chris@16
|
90 * Choose and instantiate an "associative" container. Note that this can
|
Chris@16
|
91 * also choose vector.
|
Chris@16
|
92 */
|
Chris@16
|
93 template <typename Selector, typename Label, typename Vertex>
|
Chris@16
|
94 struct choose_map {
|
Chris@16
|
95 typedef typename mpl::eval_if<
|
Chris@16
|
96 is_default<Selector>,
|
Chris@16
|
97 choose_default_map<Label, Vertex>,
|
Chris@16
|
98 choose_custom_map<Selector, Label, Vertex>
|
Chris@16
|
99 >::type type;
|
Chris@16
|
100 };
|
Chris@16
|
101
|
Chris@16
|
102 /** @name Insert Labeled Vertex */
|
Chris@16
|
103 //@{
|
Chris@16
|
104 // Tag dispatch on random access containers (i.e., vectors). This function
|
Chris@16
|
105 // basically requires a) that Container is vector<Label> and that Label
|
Chris@16
|
106 // is an unsigned integral value. Note that this will resize the vector
|
Chris@16
|
107 // to accommodate indices.
|
Chris@16
|
108 template <typename Container, typename Graph, typename Label, typename Prop>
|
Chris@16
|
109 std::pair<typename graph_traits<Graph>::vertex_descriptor, bool>
|
Chris@16
|
110 insert_labeled_vertex(Container& c, Graph& g, Label const& l, Prop const& p,
|
Chris@16
|
111 random_access_container_tag)
|
Chris@16
|
112 {
|
Chris@16
|
113 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
Chris@16
|
114
|
Chris@16
|
115 // If the label is out of bounds, resize the vector to accommodate.
|
Chris@16
|
116 // Resize by 2x the index so we don't cause quadratic insertions over
|
Chris@16
|
117 // time.
|
Chris@16
|
118 if(l >= c.size()) {
|
Chris@16
|
119 c.resize((l + 1) * 2);
|
Chris@16
|
120 }
|
Chris@16
|
121 Vertex v = add_vertex(p, g);
|
Chris@16
|
122 c[l] = v;
|
Chris@16
|
123 return std::make_pair(c[l], true);
|
Chris@16
|
124 }
|
Chris@16
|
125
|
Chris@16
|
126 // Tag dispatch on multi associative containers (i.e. multimaps).
|
Chris@16
|
127 template <typename Container, typename Graph, typename Label, typename Prop>
|
Chris@16
|
128 std::pair<typename graph_traits<Graph>::vertex_descriptor, bool>
|
Chris@16
|
129 insert_labeled_vertex(Container& c, Graph& g, Label const& l, Prop const& p,
|
Chris@16
|
130 multiple_associative_container_tag const&)
|
Chris@16
|
131 {
|
Chris@16
|
132 // Note that insertion always succeeds so we can add the vertex first
|
Chris@16
|
133 // and then the mapping to the label.
|
Chris@16
|
134 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
Chris@16
|
135 Vertex v = add_vertex(g);
|
Chris@16
|
136 c.insert(std::make_pair(l, v));
|
Chris@16
|
137 return std::make_pair(v, true);
|
Chris@16
|
138 }
|
Chris@16
|
139
|
Chris@16
|
140 // Tag dispatch on unique associative containers (i.e. maps).
|
Chris@16
|
141 template <typename Container, typename Graph, typename Label, typename Prop>
|
Chris@16
|
142 std::pair<typename graph_traits<Graph>::vertex_descriptor, bool>
|
Chris@16
|
143 insert_labeled_vertex(Container& c, Graph& g, Label const& l, Prop const& p,
|
Chris@16
|
144 unique_associative_container_tag)
|
Chris@16
|
145 {
|
Chris@16
|
146 // Here, we actually have to try the insertion first, and only add
|
Chris@16
|
147 // the vertex if we get a new element.
|
Chris@16
|
148 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
Chris@16
|
149 typedef typename Container::iterator Iterator;
|
Chris@16
|
150 std::pair<Iterator, bool> x = c.insert(std::make_pair(l, Vertex()));
|
Chris@16
|
151 if(x.second) {
|
Chris@16
|
152 x.first->second = add_vertex(g);
|
Chris@16
|
153 put(boost::vertex_all, g, x.first->second, p);
|
Chris@16
|
154 }
|
Chris@16
|
155 return std::make_pair(x.first->second, x.second);
|
Chris@16
|
156 }
|
Chris@16
|
157
|
Chris@16
|
158 // Dispatcher
|
Chris@16
|
159 template <typename Container, typename Graph, typename Label, typename Prop>
|
Chris@16
|
160 std::pair<typename graph_traits<Graph>::vertex_descriptor, bool>
|
Chris@16
|
161 insert_labeled_vertex(Container& c, Graph& g, Label const& l, Prop const& p)
|
Chris@16
|
162 { return insert_labeled_vertex(c, g, l, p, container_category(c)); }
|
Chris@16
|
163 //@}
|
Chris@16
|
164
|
Chris@16
|
165 /** @name Find Labeled Vertex */
|
Chris@16
|
166 //@{
|
Chris@16
|
167 // Tag dispatch for sequential maps (i.e., vectors).
|
Chris@16
|
168 template <typename Container, typename Graph, typename Label>
|
Chris@16
|
169 typename graph_traits<Graph>::vertex_descriptor
|
Chris@16
|
170 find_labeled_vertex(Container const& c, Graph const&, Label const& l,
|
Chris@16
|
171 random_access_container_tag)
|
Chris@16
|
172 { return l < c.size() ? c[l] : graph_traits<Graph>::null_vertex(); }
|
Chris@16
|
173
|
Chris@16
|
174 // Tag dispatch for pair associative maps (more or less).
|
Chris@16
|
175 template <typename Container, typename Graph, typename Label>
|
Chris@16
|
176 typename graph_traits<Graph>::vertex_descriptor
|
Chris@16
|
177 find_labeled_vertex(Container const& c, Graph const&, Label const& l,
|
Chris@16
|
178 associative_container_tag)
|
Chris@16
|
179 {
|
Chris@16
|
180 typename Container::const_iterator i = c.find(l);
|
Chris@16
|
181 return i != c.end() ? i->second : graph_traits<Graph>::null_vertex();
|
Chris@16
|
182 }
|
Chris@16
|
183
|
Chris@16
|
184 // Dispatcher
|
Chris@16
|
185 template <typename Container, typename Graph, typename Label>
|
Chris@16
|
186 typename graph_traits<Graph>::vertex_descriptor
|
Chris@16
|
187 find_labeled_vertex(Container const& c, Graph const& g, Label const& l)
|
Chris@16
|
188 { return find_labeled_vertex(c, g, l, container_category(c)); }
|
Chris@16
|
189 //@}
|
Chris@16
|
190
|
Chris@16
|
191 /** @name Put Vertex Label */
|
Chris@16
|
192 //@{
|
Chris@16
|
193 // Tag dispatch on vectors.
|
Chris@16
|
194 template <typename Container, typename Label, typename Graph, typename Vertex>
|
Chris@16
|
195 bool put_vertex_label(Container& c, Graph const&, Label const& l, Vertex v,
|
Chris@16
|
196 random_access_container_tag)
|
Chris@16
|
197 {
|
Chris@16
|
198 // If the element is already occupied, then we probably don't want to
|
Chris@16
|
199 // overwrite it.
|
Chris@16
|
200 if(c[l] == graph_traits<Graph>::null_vertex()) return false;
|
Chris@16
|
201 c[l] = v;
|
Chris@16
|
202 return true;
|
Chris@16
|
203 }
|
Chris@16
|
204
|
Chris@16
|
205 // Attempt the insertion and return its result.
|
Chris@16
|
206 template <typename Container, typename Label, typename Graph, typename Vertex>
|
Chris@16
|
207 bool put_vertex_label(Container& c, Graph const&, Label const& l, Vertex v,
|
Chris@16
|
208 unique_associative_container_tag)
|
Chris@16
|
209 { return c.insert(std::make_pair(l, v)).second; }
|
Chris@16
|
210
|
Chris@16
|
211 // Insert the pair and return true.
|
Chris@16
|
212 template <typename Container, typename Label, typename Graph, typename Vertex>
|
Chris@16
|
213 bool put_vertex_label(Container& c, Graph const&, Label const& l, Vertex v,
|
Chris@16
|
214 multiple_associative_container_tag)
|
Chris@16
|
215 {
|
Chris@16
|
216 c.insert(std::make_pair(l, v));
|
Chris@16
|
217 return true;
|
Chris@16
|
218 }
|
Chris@16
|
219
|
Chris@16
|
220 // Dispatcher
|
Chris@16
|
221 template <typename Container, typename Label, typename Graph, typename Vertex>
|
Chris@16
|
222 bool put_vertex_label(Container& c, Graph const& g, Label const& l, Vertex v)
|
Chris@16
|
223 { return put_vertex_label(c, g, l, v, container_category(c)); }
|
Chris@16
|
224 //@}
|
Chris@16
|
225
|
Chris@16
|
226 } // namespace detail
|
Chris@16
|
227
|
Chris@16
|
228 struct labeled_graph_class_tag { };
|
Chris@16
|
229
|
Chris@16
|
230 /** @internal
|
Chris@16
|
231 * This class is responsible for the deduction and declaration of type names
|
Chris@16
|
232 * for the labeled_graph class template.
|
Chris@16
|
233 */
|
Chris@16
|
234 template <typename Graph, typename Label, typename Selector>
|
Chris@16
|
235 struct labeled_graph_types {
|
Chris@16
|
236 typedef Graph graph_type;
|
Chris@16
|
237
|
Chris@16
|
238 // Label and maps
|
Chris@16
|
239 typedef Label label_type;
|
Chris@16
|
240 typedef typename graph_detail::choose_map<
|
Chris@16
|
241 Selector, Label, typename graph_traits<Graph>::vertex_descriptor
|
Chris@16
|
242 >::type map_type;
|
Chris@16
|
243 };
|
Chris@16
|
244
|
Chris@16
|
245 /**
|
Chris@16
|
246 * The labeled_graph class is a graph adaptor that maintains a mapping between
|
Chris@16
|
247 * vertex labels and vertex descriptors.
|
Chris@16
|
248 *
|
Chris@16
|
249 * @todo This class is somewhat redundant for adjacency_list<*, vecS> if
|
Chris@16
|
250 * the intended label is an unsigned int (and perhaps some other cases), but
|
Chris@16
|
251 * it does avoid some weird ambiguities (i.e. adding a vertex with a label that
|
Chris@16
|
252 * does not match its target index).
|
Chris@16
|
253 *
|
Chris@16
|
254 * @todo This needs to be reconciled with the named_graph, but since there is
|
Chris@16
|
255 * no documentation or examples, its not going to happen.
|
Chris@16
|
256 */
|
Chris@16
|
257 template <typename Graph, typename Label, typename Selector = defaultS>
|
Chris@16
|
258 class labeled_graph
|
Chris@16
|
259 : protected labeled_graph_types<Graph, Label, Selector>
|
Chris@16
|
260 {
|
Chris@16
|
261 typedef labeled_graph_types<Graph, Label, Selector> Base;
|
Chris@16
|
262 public:
|
Chris@16
|
263 typedef labeled_graph_class_tag graph_tag;
|
Chris@16
|
264
|
Chris@16
|
265 typedef typename Base::graph_type graph_type;
|
Chris@16
|
266 typedef typename graph_traits<graph_type>::vertex_descriptor vertex_descriptor;
|
Chris@16
|
267 typedef typename graph_traits<graph_type>::edge_descriptor edge_descriptor;
|
Chris@16
|
268 typedef typename graph_traits<graph_type>::directed_category directed_category;
|
Chris@16
|
269 typedef typename graph_traits<graph_type>::edge_parallel_category edge_parallel_category;
|
Chris@16
|
270 typedef typename graph_traits<graph_type>::traversal_category traversal_category;
|
Chris@16
|
271
|
Chris@16
|
272 typedef typename graph_traits<graph_type>::out_edge_iterator out_edge_iterator;
|
Chris@16
|
273 typedef typename graph_traits<graph_type>::in_edge_iterator in_edge_iterator;
|
Chris@16
|
274 typedef typename graph_traits<graph_type>::adjacency_iterator adjacency_iterator;
|
Chris@16
|
275 typedef typename graph_traits<graph_type>::degree_size_type degree_size_type;
|
Chris@16
|
276
|
Chris@16
|
277 typedef typename graph_traits<graph_type>::vertex_iterator vertex_iterator;
|
Chris@16
|
278 typedef typename graph_traits<graph_type>::vertices_size_type vertices_size_type;
|
Chris@16
|
279 typedef typename graph_traits<graph_type>::edge_iterator edge_iterator;
|
Chris@16
|
280 typedef typename graph_traits<graph_type>::edges_size_type edges_size_type;
|
Chris@16
|
281
|
Chris@16
|
282 typedef typename graph_type::graph_property_type graph_property_type;
|
Chris@16
|
283 typedef typename graph_type::graph_bundled graph_bundled;
|
Chris@16
|
284
|
Chris@16
|
285 typedef typename graph_type::vertex_property_type vertex_property_type;
|
Chris@16
|
286 typedef typename graph_type::vertex_bundled vertex_bundled;
|
Chris@16
|
287
|
Chris@16
|
288 typedef typename graph_type::edge_property_type edge_property_type;
|
Chris@16
|
289 typedef typename graph_type::edge_bundled edge_bundled;
|
Chris@16
|
290
|
Chris@16
|
291 typedef typename Base::label_type label_type;
|
Chris@16
|
292 typedef typename Base::map_type map_type;
|
Chris@16
|
293
|
Chris@16
|
294 public:
|
Chris@16
|
295 labeled_graph(graph_property_type const& gp = graph_property_type())
|
Chris@16
|
296 : _graph(gp), _map()
|
Chris@16
|
297 { }
|
Chris@16
|
298
|
Chris@16
|
299 labeled_graph(labeled_graph const& x)
|
Chris@16
|
300 : _graph(x._graph), _map(x._map)
|
Chris@16
|
301 { }
|
Chris@16
|
302
|
Chris@16
|
303 // This constructor can only be used if map_type supports positional
|
Chris@16
|
304 // range insertion (i.e. its a vector). This is the only case where we can
|
Chris@16
|
305 // try to guess the intended labels for graph.
|
Chris@16
|
306 labeled_graph(vertices_size_type n,
|
Chris@16
|
307 graph_property_type const& gp = graph_property_type())
|
Chris@16
|
308 : _graph(n, gp), _map()
|
Chris@16
|
309 {
|
Chris@16
|
310 std::pair<vertex_iterator, vertex_iterator> rng = vertices(_graph);
|
Chris@16
|
311 _map.insert(_map.end(), rng.first, rng.second);
|
Chris@16
|
312 }
|
Chris@16
|
313
|
Chris@16
|
314 // Construct a graph over n vertices, each of which receives a label from
|
Chris@16
|
315 // the range [l, l + n). Note that the graph is not directly constructed
|
Chris@16
|
316 // over the n vertices, but added sequentially. This constructor is
|
Chris@16
|
317 // necessarily slower than the underlying counterpart.
|
Chris@16
|
318 template <typename LabelIter>
|
Chris@16
|
319 labeled_graph(vertices_size_type n, LabelIter l,
|
Chris@16
|
320 graph_property_type const& gp = graph_property_type())
|
Chris@16
|
321 : _graph(gp)
|
Chris@16
|
322 { while(n-- >= 0) add_vertex(*l++); }
|
Chris@16
|
323
|
Chris@16
|
324 // Construct the graph over n vertices each of which has a label in the
|
Chris@16
|
325 // range [l, l + n) and a property in the range [p, p + n).
|
Chris@16
|
326 template <typename LabelIter, typename PropIter>
|
Chris@16
|
327 labeled_graph(vertices_size_type n, LabelIter l, PropIter p,
|
Chris@16
|
328 graph_property_type const& gp = graph_property_type())
|
Chris@16
|
329 { while(n-- >= 0) add_vertex(*l++, *p++); }
|
Chris@16
|
330
|
Chris@16
|
331 labeled_graph& operator=(labeled_graph const& x) {
|
Chris@16
|
332 _graph = x._graph;
|
Chris@16
|
333 _map = x._map;
|
Chris@16
|
334 return *this;
|
Chris@16
|
335 }
|
Chris@16
|
336
|
Chris@16
|
337 /** @name Graph Accessors */
|
Chris@16
|
338 //@{
|
Chris@16
|
339 graph_type& graph() { return _graph; }
|
Chris@16
|
340 graph_type const& graph() const { return _graph; }
|
Chris@16
|
341 //@}
|
Chris@16
|
342
|
Chris@16
|
343 /**
|
Chris@16
|
344 * Create a new label for the given vertex, returning false, if the label
|
Chris@16
|
345 * cannot be created.
|
Chris@16
|
346 */
|
Chris@16
|
347 bool label_vertex(vertex_descriptor v, Label const& l)
|
Chris@16
|
348 { return graph_detail::put_vertex_label(_map, _graph, l, v); }
|
Chris@16
|
349
|
Chris@16
|
350 /** @name Add Vertex
|
Chris@16
|
351 * Add a vertex to the graph, returning the descriptor. If the vertices
|
Chris@16
|
352 * are uniquely labeled and the label already exists within the graph,
|
Chris@16
|
353 * then no vertex is added, and the returned descriptor refers to the
|
Chris@16
|
354 * existing vertex. A vertex property can be given as a parameter, if
|
Chris@16
|
355 * needed.
|
Chris@16
|
356 */
|
Chris@16
|
357 //@{
|
Chris@16
|
358 vertex_descriptor add_vertex(Label const& l) {
|
Chris@16
|
359 return graph_detail::insert_labeled_vertex(
|
Chris@16
|
360 _map, _graph, l, vertex_property_type()
|
Chris@16
|
361 ).first;
|
Chris@16
|
362 }
|
Chris@16
|
363
|
Chris@16
|
364 vertex_descriptor add_vertex(Label const& l, vertex_property_type const& p)
|
Chris@16
|
365 { return graph_detail::insert_labeled_vertex(_map, _graph, l, p).first; }
|
Chris@16
|
366 //@}
|
Chris@16
|
367
|
Chris@16
|
368 /** @name Insert Vertex
|
Chris@16
|
369 * Insert a vertex into the graph, returning a pair containing the
|
Chris@16
|
370 * descriptor of a vertex and a boolean value that describes whether or not
|
Chris@16
|
371 * a new vertex was inserted. If vertices are not uniquely labeled, then
|
Chris@16
|
372 * insertion will always succeed.
|
Chris@16
|
373 */
|
Chris@16
|
374 //@{
|
Chris@16
|
375 std::pair<vertex_descriptor, bool> insert_vertex(Label const& l) {
|
Chris@16
|
376 return graph_detail::insert_labeled_vertex(
|
Chris@16
|
377 _map, _graph, l, vertex_property_type()
|
Chris@16
|
378 );
|
Chris@16
|
379 }
|
Chris@16
|
380
|
Chris@16
|
381 std::pair<vertex_descriptor, bool>
|
Chris@16
|
382 insert_vertex(Label const& l, vertex_property_type const& p)
|
Chris@16
|
383 { return graph_detail::insert_labeled_vertex(_map, _graph, l, p); }
|
Chris@16
|
384 //@}
|
Chris@16
|
385
|
Chris@16
|
386 /** Remove the vertex with the given label. */
|
Chris@16
|
387 void remove_vertex(Label const& l)
|
Chris@16
|
388 { return boost::remove_vertex(vertex(l), _graph); }
|
Chris@16
|
389
|
Chris@16
|
390 /** Return a descriptor for the given label. */
|
Chris@16
|
391 vertex_descriptor vertex(Label const& l) const
|
Chris@16
|
392 { return graph_detail::find_labeled_vertex(_map, _graph, l); }
|
Chris@16
|
393
|
Chris@16
|
394 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
|
Chris@16
|
395 /** @name Bundled Properties */
|
Chris@16
|
396 //@{
|
Chris@16
|
397 // Lookup the requested vertex and return the bundle.
|
Chris@16
|
398 vertex_bundled& operator[](Label const& l)
|
Chris@16
|
399 { return _graph[vertex(l)]; }
|
Chris@16
|
400
|
Chris@16
|
401 vertex_bundled const& operator[](Label const& l) const
|
Chris@16
|
402 { return _graph[vertex(l)]; }
|
Chris@16
|
403
|
Chris@16
|
404 // Delegate edge lookup to the underlying graph.
|
Chris@16
|
405 edge_bundled& operator[](edge_descriptor e)
|
Chris@16
|
406 { return _graph[e]; }
|
Chris@16
|
407
|
Chris@16
|
408 edge_bundled const& operator[](edge_descriptor e) const
|
Chris@16
|
409 { return _graph[e]; }
|
Chris@16
|
410 //@}
|
Chris@16
|
411 #endif
|
Chris@16
|
412
|
Chris@16
|
413 /** Return a null descriptor */
|
Chris@16
|
414 static vertex_descriptor null_vertex()
|
Chris@16
|
415 { return graph_traits<graph_type>::null_vertex(); }
|
Chris@16
|
416
|
Chris@16
|
417 private:
|
Chris@16
|
418 graph_type _graph;
|
Chris@16
|
419 map_type _map;
|
Chris@16
|
420 };
|
Chris@16
|
421
|
Chris@16
|
422 /**
|
Chris@16
|
423 * The partial specialization over graph pointers allows the construction
|
Chris@16
|
424 * of temporary labeled graph objects. In this case, the labels are destructed
|
Chris@16
|
425 * when the wrapper goes out of scope.
|
Chris@16
|
426 */
|
Chris@16
|
427 template <typename Graph, typename Label, typename Selector>
|
Chris@16
|
428 class labeled_graph<Graph*, Label, Selector>
|
Chris@16
|
429 : protected labeled_graph_types<Graph, Label, Selector>
|
Chris@16
|
430 {
|
Chris@16
|
431 typedef labeled_graph_types<Graph, Label, Selector> Base;
|
Chris@16
|
432 public:
|
Chris@16
|
433 typedef labeled_graph_class_tag graph_tag;
|
Chris@16
|
434
|
Chris@16
|
435 typedef typename Base::graph_type graph_type;
|
Chris@16
|
436 typedef typename graph_traits<graph_type>::vertex_descriptor vertex_descriptor;
|
Chris@16
|
437 typedef typename graph_traits<graph_type>::edge_descriptor edge_descriptor;
|
Chris@16
|
438 typedef typename graph_traits<graph_type>::directed_category directed_category;
|
Chris@16
|
439 typedef typename graph_traits<graph_type>::edge_parallel_category edge_parallel_category;
|
Chris@16
|
440 typedef typename graph_traits<graph_type>::traversal_category traversal_category;
|
Chris@16
|
441
|
Chris@16
|
442 typedef typename graph_traits<graph_type>::out_edge_iterator out_edge_iterator;
|
Chris@16
|
443 typedef typename graph_traits<graph_type>::in_edge_iterator in_edge_iterator;
|
Chris@16
|
444 typedef typename graph_traits<graph_type>::adjacency_iterator adjacency_iterator;
|
Chris@16
|
445 typedef typename graph_traits<graph_type>::degree_size_type degree_size_type;
|
Chris@16
|
446
|
Chris@16
|
447 typedef typename graph_traits<graph_type>::vertex_iterator vertex_iterator;
|
Chris@16
|
448 typedef typename graph_traits<graph_type>::vertices_size_type vertices_size_type;
|
Chris@16
|
449 typedef typename graph_traits<graph_type>::edge_iterator edge_iterator;
|
Chris@16
|
450 typedef typename graph_traits<graph_type>::edges_size_type edges_size_type;
|
Chris@16
|
451
|
Chris@16
|
452 typedef typename graph_type::vertex_property_type vertex_property_type;
|
Chris@16
|
453 typedef typename graph_type::edge_property_type edge_property_type;
|
Chris@16
|
454 typedef typename graph_type::graph_property_type graph_property_type;
|
Chris@16
|
455 typedef typename graph_type::vertex_bundled vertex_bundled;
|
Chris@16
|
456 typedef typename graph_type::edge_bundled edge_bundled;
|
Chris@16
|
457
|
Chris@16
|
458 typedef typename Base::label_type label_type;
|
Chris@16
|
459 typedef typename Base::map_type map_type;
|
Chris@16
|
460
|
Chris@16
|
461 labeled_graph(graph_type* g)
|
Chris@16
|
462 : _graph(g)
|
Chris@16
|
463 { }
|
Chris@16
|
464
|
Chris@16
|
465 /** @name Graph Access */
|
Chris@16
|
466 //@{
|
Chris@16
|
467 graph_type& graph() { return *_graph; }
|
Chris@16
|
468 graph_type const& graph() const { return *_graph; }
|
Chris@16
|
469 //@}
|
Chris@16
|
470
|
Chris@16
|
471 /**
|
Chris@16
|
472 * Create a new label for the given vertex, returning false, if the label
|
Chris@16
|
473 * cannot be created.
|
Chris@16
|
474 */
|
Chris@16
|
475 bool label_vertex(vertex_descriptor v, Label const& l)
|
Chris@16
|
476 { return graph_detail::put_vertex_label(_map, *_graph, l, v); }
|
Chris@16
|
477
|
Chris@16
|
478 /** @name Add Vertex */
|
Chris@16
|
479 //@{
|
Chris@16
|
480 vertex_descriptor add_vertex(Label const& l) {
|
Chris@16
|
481 return graph_detail::insert_labeled_vertex(
|
Chris@16
|
482 _map, *_graph, l, vertex_property_type()
|
Chris@16
|
483 ).first;
|
Chris@16
|
484 }
|
Chris@16
|
485
|
Chris@16
|
486 vertex_descriptor add_vertex(Label const& l, vertex_property_type const& p)
|
Chris@16
|
487 { return graph_detail::insert_labeled_vertex(_map, *_graph, l, p).first; }
|
Chris@16
|
488
|
Chris@16
|
489 std::pair<vertex_descriptor, bool> insert_vertex(Label const& l) {
|
Chris@16
|
490 return graph_detail::insert_labeled_vertex(
|
Chris@16
|
491 _map, *_graph, l, vertex_property_type()
|
Chris@16
|
492 );
|
Chris@16
|
493 }
|
Chris@16
|
494 //@}
|
Chris@16
|
495
|
Chris@16
|
496 /** Try to insert a vertex with the given label. */
|
Chris@16
|
497 std::pair<vertex_descriptor, bool>
|
Chris@16
|
498 insert_vertex(Label const& l, vertex_property_type const& p)
|
Chris@16
|
499 { return graph_detail::insert_labeled_vertex(_map, *_graph, l, p); }
|
Chris@16
|
500
|
Chris@16
|
501 /** Remove the vertex with the given label. */
|
Chris@16
|
502 void remove_vertex(Label const& l)
|
Chris@16
|
503 { return boost::remove_vertex(vertex(l), *_graph); }
|
Chris@16
|
504
|
Chris@16
|
505 /** Return a descriptor for the given label. */
|
Chris@16
|
506 vertex_descriptor vertex(Label const& l) const
|
Chris@16
|
507 { return graph_detail::find_labeled_vertex(_map, *_graph, l); }
|
Chris@16
|
508
|
Chris@16
|
509 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
|
Chris@16
|
510 /** @name Bundled Properties */
|
Chris@16
|
511 //@{
|
Chris@16
|
512 // Lookup the requested vertex and return the bundle.
|
Chris@16
|
513 vertex_bundled& operator[](Label const& l)
|
Chris@16
|
514 { return (*_graph)[vertex(l)]; }
|
Chris@16
|
515
|
Chris@16
|
516 vertex_bundled const& operator[](Label const& l) const
|
Chris@16
|
517 { return (*_graph)[vertex(l)]; }
|
Chris@16
|
518
|
Chris@16
|
519 // Delegate edge lookup to the underlying graph.
|
Chris@16
|
520 edge_bundled& operator[](edge_descriptor e)
|
Chris@16
|
521 { return (*_graph)[e]; }
|
Chris@16
|
522
|
Chris@16
|
523 edge_bundled const& operator[](edge_descriptor e) const
|
Chris@16
|
524 { return (*_graph)[e]; }
|
Chris@16
|
525 //@}
|
Chris@16
|
526 #endif
|
Chris@16
|
527
|
Chris@16
|
528 static vertex_descriptor null_vertex()
|
Chris@16
|
529 { return graph_traits<graph_type>::null_vertex(); }
|
Chris@16
|
530
|
Chris@16
|
531 private:
|
Chris@16
|
532 graph_type* _graph;
|
Chris@16
|
533 map_type _map;
|
Chris@16
|
534 };
|
Chris@16
|
535
|
Chris@16
|
536 #define LABELED_GRAPH_PARAMS typename G, typename L, typename S
|
Chris@16
|
537 #define LABELED_GRAPH labeled_graph<G,L,S>
|
Chris@16
|
538
|
Chris@16
|
539 /** @name Labeled Graph */
|
Chris@16
|
540 //@{
|
Chris@16
|
541 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
542 inline bool label_vertex(typename LABELED_GRAPH::vertex_descriptor v,
|
Chris@16
|
543 typename LABELED_GRAPH::label_type const l,
|
Chris@16
|
544 LABELED_GRAPH& g)
|
Chris@16
|
545 { return g.label_vertex(v, l); }
|
Chris@16
|
546
|
Chris@16
|
547 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
548 inline typename LABELED_GRAPH::vertex_descriptor
|
Chris@16
|
549 vertex_by_label(typename LABELED_GRAPH::label_type const l,
|
Chris@16
|
550 LABELED_GRAPH& g)
|
Chris@16
|
551 { return g.vertex(l); }
|
Chris@16
|
552 //@}
|
Chris@16
|
553
|
Chris@16
|
554 /** @name Graph */
|
Chris@16
|
555 //@{
|
Chris@16
|
556 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
557 inline std::pair<typename LABELED_GRAPH::edge_descriptor, bool>
|
Chris@16
|
558 edge(typename LABELED_GRAPH::vertex_descriptor const& u,
|
Chris@16
|
559 typename LABELED_GRAPH::vertex_descriptor const& v,
|
Chris@16
|
560 LABELED_GRAPH const& g)
|
Chris@16
|
561 { return edge(u, v, g.graph()); }
|
Chris@16
|
562
|
Chris@16
|
563 // Labeled Extensions
|
Chris@16
|
564 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
565 inline std::pair<typename LABELED_GRAPH::edge_descriptor, bool>
|
Chris@16
|
566 edge_by_label(typename LABELED_GRAPH::label_type const& u,
|
Chris@16
|
567 typename LABELED_GRAPH::label_type const& v,
|
Chris@16
|
568 LABELED_GRAPH const& g)
|
Chris@16
|
569 { return edge(g.vertex(u), g.vertex(v), g); }
|
Chris@16
|
570 //@}
|
Chris@16
|
571
|
Chris@16
|
572 /** @name Incidence Graph */
|
Chris@16
|
573 //@{
|
Chris@16
|
574 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
575 inline std::pair<
|
Chris@16
|
576 typename LABELED_GRAPH::out_edge_iterator,
|
Chris@16
|
577 typename LABELED_GRAPH::out_edge_iterator>
|
Chris@16
|
578 out_edges(typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
|
Chris@16
|
579 { return out_edges(v, g.graph()); }
|
Chris@16
|
580
|
Chris@16
|
581 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
582 inline typename LABELED_GRAPH::degree_size_type
|
Chris@16
|
583 out_degree(typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
|
Chris@16
|
584 { return out_degree(v, g.graph()); }
|
Chris@16
|
585
|
Chris@16
|
586 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
587 inline typename LABELED_GRAPH::vertex_descriptor
|
Chris@16
|
588 source(typename LABELED_GRAPH::edge_descriptor e, LABELED_GRAPH const& g)
|
Chris@16
|
589 { return source(e, g.graph()); }
|
Chris@16
|
590
|
Chris@16
|
591 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
592 inline typename LABELED_GRAPH::vertex_descriptor
|
Chris@16
|
593 target(typename LABELED_GRAPH::edge_descriptor e, LABELED_GRAPH const& g)
|
Chris@16
|
594 { return target(e, g.graph()); }
|
Chris@16
|
595 //@}
|
Chris@16
|
596
|
Chris@16
|
597 /** @name Bidirectional Graph */
|
Chris@16
|
598 //@{
|
Chris@16
|
599 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
600 inline std::pair<
|
Chris@16
|
601 typename LABELED_GRAPH::in_edge_iterator,
|
Chris@16
|
602 typename LABELED_GRAPH::in_edge_iterator>
|
Chris@16
|
603 in_edges(typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
|
Chris@16
|
604 { return in_edges(v, g.graph()); }
|
Chris@16
|
605
|
Chris@16
|
606 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
607 inline typename LABELED_GRAPH::degree_size_type
|
Chris@16
|
608 in_degree(typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
|
Chris@16
|
609 { return in_degree(v, g.graph()); }
|
Chris@16
|
610
|
Chris@16
|
611 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
612 inline typename LABELED_GRAPH::degree_size_type
|
Chris@16
|
613 degree(typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
|
Chris@16
|
614 { return degree(v, g.graph()); }
|
Chris@16
|
615 //@}
|
Chris@16
|
616
|
Chris@16
|
617 /** @name Adjacency Graph */
|
Chris@16
|
618 //@{
|
Chris@16
|
619 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
620 inline std::pair<
|
Chris@16
|
621 typename LABELED_GRAPH::adjacency_iterator,
|
Chris@16
|
622 typename LABELED_GRAPH::adjacency_iterator>
|
Chris@16
|
623 adjacenct_vertices(typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
|
Chris@16
|
624 { return adjacent_vertices(v, g.graph()); }
|
Chris@16
|
625 //@}
|
Chris@16
|
626
|
Chris@16
|
627 /** @name VertexListGraph */
|
Chris@16
|
628 //@{
|
Chris@16
|
629 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
630 inline std::pair<
|
Chris@16
|
631 typename LABELED_GRAPH::vertex_iterator,
|
Chris@16
|
632 typename LABELED_GRAPH::vertex_iterator>
|
Chris@16
|
633 vertices(LABELED_GRAPH const& g)
|
Chris@16
|
634 { return vertices(g.graph()); }
|
Chris@16
|
635
|
Chris@16
|
636 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
637 inline typename LABELED_GRAPH::vertices_size_type
|
Chris@16
|
638 num_vertices(LABELED_GRAPH const& g)
|
Chris@16
|
639 { return num_vertices(g.graph()); }
|
Chris@16
|
640 //@}
|
Chris@16
|
641
|
Chris@16
|
642 /** @name EdgeListGraph */
|
Chris@16
|
643 //@{
|
Chris@16
|
644 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
645 inline std::pair<
|
Chris@16
|
646 typename LABELED_GRAPH::edge_iterator,
|
Chris@16
|
647 typename LABELED_GRAPH::edge_iterator>
|
Chris@16
|
648 edges(LABELED_GRAPH const& g)
|
Chris@16
|
649 { return edges(g.graph()); }
|
Chris@16
|
650
|
Chris@16
|
651 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
652 inline typename LABELED_GRAPH::edges_size_type
|
Chris@16
|
653 num_edges(LABELED_GRAPH const& g)
|
Chris@16
|
654 { return num_edges(g.graph()); }
|
Chris@16
|
655 //@}
|
Chris@16
|
656
|
Chris@16
|
657 /** @internal @name Property Lookup */
|
Chris@16
|
658 //@{
|
Chris@16
|
659 namespace graph_detail {
|
Chris@16
|
660 struct labeled_graph_vertex_property_selector {
|
Chris@16
|
661 template <class LabeledGraph, class Property, class Tag>
|
Chris@16
|
662 struct bind_ {
|
Chris@16
|
663 typedef typename LabeledGraph::graph_type Graph;
|
Chris@16
|
664 typedef property_map<Graph, Tag> PropertyMap;
|
Chris@16
|
665 typedef typename PropertyMap::type type;
|
Chris@16
|
666 typedef typename PropertyMap::const_type const_type;
|
Chris@16
|
667 };
|
Chris@16
|
668 };
|
Chris@16
|
669
|
Chris@16
|
670 struct labeled_graph_edge_property_selector {
|
Chris@16
|
671 template <class LabeledGraph, class Property, class Tag>
|
Chris@16
|
672 struct bind_ {
|
Chris@16
|
673 typedef typename LabeledGraph::graph_type Graph;
|
Chris@16
|
674 typedef property_map<Graph, Tag> PropertyMap;
|
Chris@16
|
675 typedef typename PropertyMap::type type;
|
Chris@16
|
676 typedef typename PropertyMap::const_type const_type;
|
Chris@16
|
677 };
|
Chris@16
|
678 };
|
Chris@16
|
679 }
|
Chris@16
|
680
|
Chris@16
|
681 template <>
|
Chris@16
|
682 struct vertex_property_selector<labeled_graph_class_tag> {
|
Chris@16
|
683 typedef graph_detail::labeled_graph_vertex_property_selector type;
|
Chris@16
|
684 };
|
Chris@16
|
685
|
Chris@16
|
686 template <>
|
Chris@16
|
687 struct edge_property_selector<labeled_graph_class_tag> {
|
Chris@16
|
688 typedef graph_detail::labeled_graph_edge_property_selector type;
|
Chris@16
|
689 };
|
Chris@16
|
690 //@}
|
Chris@16
|
691
|
Chris@16
|
692 /** @name Property Graph */
|
Chris@16
|
693 //@{
|
Chris@16
|
694 template <LABELED_GRAPH_PARAMS, typename Prop>
|
Chris@16
|
695 inline typename property_map<LABELED_GRAPH, Prop>::type
|
Chris@16
|
696 get(Prop p, LABELED_GRAPH& g)
|
Chris@16
|
697 { return get(p, g.graph()); }
|
Chris@16
|
698
|
Chris@16
|
699 template <LABELED_GRAPH_PARAMS, typename Prop>
|
Chris@16
|
700 inline typename property_map<LABELED_GRAPH, Prop>::const_type
|
Chris@16
|
701 get(Prop p, LABELED_GRAPH const& g)
|
Chris@16
|
702 { return get(p, g.graph()); }
|
Chris@16
|
703
|
Chris@16
|
704 template <LABELED_GRAPH_PARAMS, typename Prop, typename Key>
|
Chris@16
|
705 inline typename property_traits<
|
Chris@16
|
706 typename property_map<typename LABELED_GRAPH::graph_type, Prop>::const_type
|
Chris@16
|
707 >::value_type
|
Chris@16
|
708 get(Prop p, LABELED_GRAPH const& g, const Key& k)
|
Chris@16
|
709 { return get(p, g.graph(), k); }
|
Chris@16
|
710
|
Chris@16
|
711 template <LABELED_GRAPH_PARAMS, typename Prop, typename Key, typename Value>
|
Chris@16
|
712 inline void
|
Chris@16
|
713 put(Prop p, LABELED_GRAPH& g, Key const& k, Value const& v)
|
Chris@16
|
714 { put(p, g.graph(), k, v); }
|
Chris@16
|
715 //@}
|
Chris@16
|
716
|
Chris@16
|
717 /** @name Mutable Graph */
|
Chris@16
|
718 //@{
|
Chris@16
|
719 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
720 inline std::pair<typename LABELED_GRAPH::edge_descriptor, bool>
|
Chris@16
|
721 add_edge(typename LABELED_GRAPH::vertex_descriptor const& u,
|
Chris@16
|
722 typename LABELED_GRAPH::vertex_descriptor const& v,
|
Chris@16
|
723 LABELED_GRAPH& g)
|
Chris@16
|
724 { return add_edge(u, v, g.graph()); }
|
Chris@16
|
725
|
Chris@16
|
726 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
727 inline std::pair<typename LABELED_GRAPH::edge_descriptor, bool>
|
Chris@16
|
728 add_edge(typename LABELED_GRAPH::vertex_descriptor const& u,
|
Chris@16
|
729 typename LABELED_GRAPH::vertex_descriptor const& v,
|
Chris@16
|
730 typename LABELED_GRAPH::edge_property_type const& p,
|
Chris@16
|
731 LABELED_GRAPH& g)
|
Chris@16
|
732 { return add_edge(u, v, p, g.graph()); }
|
Chris@16
|
733
|
Chris@16
|
734 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
735 inline void
|
Chris@16
|
736 clear_vertex(typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH& g)
|
Chris@16
|
737 { return clear_vertex(v, g.graph()); }
|
Chris@16
|
738
|
Chris@16
|
739 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
740 inline void
|
Chris@16
|
741 remove_edge(typename LABELED_GRAPH::edge_descriptor e, LABELED_GRAPH& g)
|
Chris@16
|
742 { return remove_edge(e, g.graph()); }
|
Chris@16
|
743
|
Chris@16
|
744 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
745 inline void
|
Chris@16
|
746 remove_edge(typename LABELED_GRAPH::vertex_descriptor u,
|
Chris@16
|
747 typename LABELED_GRAPH::vertex_descriptor v,
|
Chris@16
|
748 LABELED_GRAPH& g)
|
Chris@16
|
749 { return remove_edge(u, v, g.graph()); }
|
Chris@16
|
750
|
Chris@16
|
751 // Labeled extensions
|
Chris@16
|
752 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
753 inline std::pair<typename LABELED_GRAPH::edge_descriptor, bool>
|
Chris@16
|
754 add_edge_by_label(typename LABELED_GRAPH::label_type const& u,
|
Chris@16
|
755 typename LABELED_GRAPH::label_type const& v,
|
Chris@16
|
756 LABELED_GRAPH& g)
|
Chris@16
|
757 { return add_edge(g.vertex(u), g.vertex(v), g); }
|
Chris@16
|
758
|
Chris@16
|
759 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
760 inline std::pair<typename LABELED_GRAPH::edge_descriptor, bool>
|
Chris@16
|
761 add_edge_by_label(typename LABELED_GRAPH::label_type const& u,
|
Chris@16
|
762 typename LABELED_GRAPH::label_type const& v,
|
Chris@16
|
763 typename LABELED_GRAPH::edge_property_type const& p,
|
Chris@16
|
764 LABELED_GRAPH& g)
|
Chris@16
|
765 { return add_edge(g.vertex(u), g.vertex(v), p, g); }
|
Chris@16
|
766
|
Chris@16
|
767 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
768 inline void
|
Chris@16
|
769 clear_vertex_by_label(typename LABELED_GRAPH::label_type const& l, LABELED_GRAPH& g)
|
Chris@16
|
770 { clear_vertex(g.vertex(l), g.graph()); }
|
Chris@16
|
771
|
Chris@16
|
772 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
773 inline void
|
Chris@16
|
774 remove_edge_by_label(typename LABELED_GRAPH::label_type const& u,
|
Chris@16
|
775 typename LABELED_GRAPH::label_type const& v,
|
Chris@16
|
776 LABELED_GRAPH& g)
|
Chris@16
|
777 { remove_edge(g.vertex(u), g.vertex(v), g.graph()); }
|
Chris@16
|
778 //@}
|
Chris@16
|
779
|
Chris@16
|
780 /** @name Labeled Mutable Graph
|
Chris@16
|
781 * The labeled mutable graph hides the add_ and remove_ vertex functions from
|
Chris@16
|
782 * the mutable graph concept. Note that the remove_vertex is hidden because
|
Chris@16
|
783 * removing the vertex without its key could leave a dangling reference in
|
Chris@16
|
784 * the map.
|
Chris@16
|
785 */
|
Chris@16
|
786 //@{
|
Chris@16
|
787 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
788 inline typename LABELED_GRAPH::vertex_descriptor
|
Chris@16
|
789 add_vertex(typename LABELED_GRAPH::label_type const& l,
|
Chris@16
|
790 LABELED_GRAPH& g)
|
Chris@16
|
791 { return g.add_vertex(l); }
|
Chris@16
|
792
|
Chris@16
|
793 // MutableLabeledPropertyGraph::add_vertex(l, vp, g)
|
Chris@16
|
794 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
795 inline typename LABELED_GRAPH::vertex_descriptor
|
Chris@16
|
796 add_vertex(typename LABELED_GRAPH::label_type const& l,
|
Chris@16
|
797 typename LABELED_GRAPH::vertex_property_type const& p,
|
Chris@16
|
798 LABELED_GRAPH& g)
|
Chris@16
|
799 { return g.add_vertex(l, p); }
|
Chris@16
|
800
|
Chris@16
|
801 template <LABELED_GRAPH_PARAMS>
|
Chris@16
|
802 inline void
|
Chris@16
|
803 remove_vertex(typename LABELED_GRAPH::label_type const& l, LABELED_GRAPH& g)
|
Chris@16
|
804 { g.remove_vertex(l); }
|
Chris@16
|
805 //@}
|
Chris@16
|
806
|
Chris@16
|
807 #undef LABELED_GRAPH_PARAMS
|
Chris@16
|
808 #undef LABELED_GRAPH
|
Chris@16
|
809
|
Chris@16
|
810 } // namespace boost
|
Chris@16
|
811
|
Chris@16
|
812 // Pull the labeled graph traits
|
Chris@16
|
813 #include <boost/graph/detail/labeled_graph_traits.hpp>
|
Chris@16
|
814
|
Chris@16
|
815 #endif // BOOST_GRAPH_LABELED_GRAPH_HPP
|