• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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