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