PageRenderTime 92ms CodeModel.GetById 3ms app.highlight 82ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/graph/labeled_graph.hpp

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