Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:37:31

0001 // Copyright (C) 2009 Andrew Sutton
0002 
0003 // Use, modification and distribution is subject to the Boost Software
0004 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_GRAPH_LABELED_GRAPH_HPP
0008 #define BOOST_GRAPH_LABELED_GRAPH_HPP
0009 
0010 #include <boost/config.hpp>
0011 #include <vector>
0012 #include <map>
0013 
0014 #include <boost/static_assert.hpp>
0015 #include <boost/mpl/if.hpp>
0016 #include <boost/mpl/bool.hpp>
0017 #include <boost/unordered_map.hpp>
0018 #include <boost/type_traits/is_same.hpp>
0019 #include <boost/type_traits/is_unsigned.hpp>
0020 #include <boost/pending/container_traits.hpp>
0021 #include <boost/graph/graph_traits.hpp>
0022 
0023 // This file implements a utility for creating mappings from arbitrary
0024 // identifiers to the vertices of a graph.
0025 
0026 namespace boost
0027 {
0028 
0029 // A type selector that denotes the use of some default value.
0030 struct defaultS
0031 {
0032 };
0033 
0034 /** @internal */
0035 namespace graph_detail
0036 {
0037     /** Returns true if the selector is the default selector. */
0038     template < typename Selector >
0039     struct is_default : mpl::bool_< is_same< Selector, defaultS >::value >
0040     {
0041     };
0042 
0043     /**
0044      * Choose the default map instance. If Label is an unsigned integral type
0045      * the we can use a vector to store the information.
0046      */
0047     template < typename Label, typename Vertex > struct choose_default_map
0048     {
0049         typedef typename mpl::if_< is_unsigned< Label >, std::vector< Vertex >,
0050             std::map< Label, Vertex > // TODO: Should use unordered_map?
0051             >::type type;
0052     };
0053 
0054     /**
0055      * @name Generate Label Map
0056      * These type generators are responsible for instantiating an associative
0057      * container for the the labeled graph. Note that the Selector must be
0058      * select a pair associative container or a vecS, which is only valid if
0059      * Label is an integral type.
0060      */
0061     //@{
0062     template < typename Selector, typename Label, typename Vertex >
0063     struct generate_label_map
0064     {
0065     };
0066 
0067     template < typename Label, typename Vertex >
0068     struct generate_label_map< vecS, Label, Vertex >
0069     {
0070         typedef std::vector< Vertex > type;
0071     };
0072 
0073     template < typename Label, typename Vertex >
0074     struct generate_label_map< mapS, Label, Vertex >
0075     {
0076         typedef std::map< Label, Vertex > type;
0077     };
0078 
0079     template < typename Label, typename Vertex >
0080     struct generate_label_map< multimapS, Label, Vertex >
0081     {
0082         typedef std::multimap< Label, Vertex > type;
0083     };
0084 
0085     template < typename Label, typename Vertex >
0086     struct generate_label_map< hash_mapS, Label, Vertex >
0087     {
0088         typedef boost::unordered_map< Label, Vertex > type;
0089     };
0090 
0091     template < typename Label, typename Vertex >
0092     struct generate_label_map< hash_multimapS, Label, Vertex >
0093     {
0094         typedef boost::unordered_multimap< Label, Vertex > type;
0095     };
0096 
0097     template < typename Selector, typename Label, typename Vertex >
0098     struct choose_custom_map
0099     {
0100         typedef
0101             typename generate_label_map< Selector, Label, Vertex >::type type;
0102     };
0103     //@}
0104 
0105     /**
0106      * Choose and instantiate an "associative" container. Note that this can
0107      * also choose vector.
0108      */
0109     template < typename Selector, typename Label, typename Vertex >
0110     struct choose_map
0111     {
0112         typedef typename mpl::eval_if< is_default< Selector >,
0113             choose_default_map< Label, Vertex >,
0114             choose_custom_map< Selector, Label, Vertex > >::type type;
0115     };
0116 
0117     /** @name Insert Labeled Vertex */
0118     //@{
0119     // Tag dispatch on random access containers (i.e., vectors). This function
0120     // basically requires a) that Container is vector<Label> and that Label
0121     // is an unsigned integral value. Note that this will resize the vector
0122     // to accommodate indices.
0123     template < typename Container, typename Graph, typename Label,
0124         typename Prop >
0125     std::pair< typename graph_traits< Graph >::vertex_descriptor, bool >
0126     insert_labeled_vertex(Container& c, Graph& g, Label const& l, Prop const& p,
0127         random_access_container_tag)
0128     {
0129         typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
0130 
0131         // If the label is out of bounds, resize the vector to accommodate.
0132         // Resize by 2x the index so we don't cause quadratic insertions over
0133         // time.
0134         if (l >= c.size())
0135         {
0136             c.resize((l + 1) * 2);
0137         }
0138         Vertex v = add_vertex(p, g);
0139         c[l] = v;
0140         return std::make_pair(c[l], true);
0141     }
0142 
0143     // Tag dispatch on multi associative containers (i.e. multimaps).
0144     template < typename Container, typename Graph, typename Label,
0145         typename Prop >
0146     std::pair< typename graph_traits< Graph >::vertex_descriptor, bool >
0147     insert_labeled_vertex(Container& c, Graph& g, Label const& l, Prop const& p,
0148         multiple_associative_container_tag const&)
0149     {
0150         // Note that insertion always succeeds so we can add the vertex first
0151         // and then the mapping to the label.
0152         typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
0153         Vertex v = add_vertex(p, g);
0154         c.insert(std::make_pair(l, v));
0155         return std::make_pair(v, true);
0156     }
0157 
0158     // Tag dispatch on unique associative containers (i.e. maps).
0159     template < typename Container, typename Graph, typename Label,
0160         typename Prop >
0161     std::pair< typename graph_traits< Graph >::vertex_descriptor, bool >
0162     insert_labeled_vertex(Container& c, Graph& g, Label const& l, Prop const& p,
0163         unique_associative_container_tag)
0164     {
0165         // Here, we actually have to try the insertion first, and only add
0166         // the vertex if we get a new element.
0167         typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
0168         typedef typename Container::iterator Iterator;
0169         std::pair< Iterator, bool > x = c.insert(std::make_pair(l, Vertex()));
0170         if (x.second)
0171         {
0172             x.first->second = add_vertex(g);
0173             put(boost::vertex_all, g, x.first->second, p);
0174         }
0175         return std::make_pair(x.first->second, x.second);
0176     }
0177 
0178     // Dispatcher
0179     template < typename Container, typename Graph, typename Label,
0180         typename Prop >
0181     std::pair< typename graph_traits< Graph >::vertex_descriptor, bool >
0182     insert_labeled_vertex(Container& c, Graph& g, Label const& l, Prop const& p)
0183     {
0184         return insert_labeled_vertex(c, g, l, p, container_category(c));
0185     }
0186     //@}
0187 
0188     /** @name Find Labeled Vertex */
0189     //@{
0190     // Tag dispatch for sequential maps (i.e., vectors).
0191     template < typename Container, typename Graph, typename Label >
0192     typename graph_traits< Graph >::vertex_descriptor find_labeled_vertex(
0193         Container const& c, Graph const&, Label const& l,
0194         random_access_container_tag)
0195     {
0196         return l < c.size() ? c[l] : graph_traits< Graph >::null_vertex();
0197     }
0198 
0199     // Tag dispatch for pair associative maps (more or less).
0200     template < typename Container, typename Graph, typename Label >
0201     typename graph_traits< Graph >::vertex_descriptor find_labeled_vertex(
0202         Container const& c, Graph const&, Label const& l,
0203         associative_container_tag)
0204     {
0205         typename Container::const_iterator i = c.find(l);
0206         return i != c.end() ? i->second : graph_traits< Graph >::null_vertex();
0207     }
0208 
0209     // Dispatcher
0210     template < typename Container, typename Graph, typename Label >
0211     typename graph_traits< Graph >::vertex_descriptor find_labeled_vertex(
0212         Container const& c, Graph const& g, Label const& l)
0213     {
0214         return find_labeled_vertex(c, g, l, container_category(c));
0215     }
0216     //@}
0217 
0218     /** @name Put Vertex Label */
0219     //@{
0220     // Tag dispatch on vectors.
0221     template < typename Container, typename Label, typename Graph,
0222         typename Vertex >
0223     bool put_vertex_label(Container& c, Graph const&, Label const& l, Vertex v,
0224         random_access_container_tag)
0225     {
0226         // If the element is already occupied, then we probably don't want to
0227         // overwrite it.
0228         if (c[l] == graph_traits< Graph >::null_vertex())
0229             return false;
0230         c[l] = v;
0231         return true;
0232     }
0233 
0234     // Attempt the insertion and return its result.
0235     template < typename Container, typename Label, typename Graph,
0236         typename Vertex >
0237     bool put_vertex_label(Container& c, Graph const&, Label const& l, Vertex v,
0238         unique_associative_container_tag)
0239     {
0240         return c.insert(std::make_pair(l, v)).second;
0241     }
0242 
0243     // Insert the pair and return true.
0244     template < typename Container, typename Label, typename Graph,
0245         typename Vertex >
0246     bool put_vertex_label(Container& c, Graph const&, Label const& l, Vertex v,
0247         multiple_associative_container_tag)
0248     {
0249         c.insert(std::make_pair(l, v));
0250         return true;
0251     }
0252 
0253     // Dispatcher
0254     template < typename Container, typename Label, typename Graph,
0255         typename Vertex >
0256     bool put_vertex_label(
0257         Container& c, Graph const& g, Label const& l, Vertex v)
0258     {
0259         return put_vertex_label(c, g, l, v, container_category(c));
0260     }
0261     //@}
0262 
0263 } // namespace detail
0264 
0265 struct labeled_graph_class_tag
0266 {
0267 };
0268 
0269 /** @internal
0270  * This class is responsible for the deduction and declaration of type names
0271  * for the labeled_graph class template.
0272  */
0273 template < typename Graph, typename Label, typename Selector >
0274 struct labeled_graph_types
0275 {
0276     typedef Graph graph_type;
0277 
0278     // Label and maps
0279     typedef Label label_type;
0280     typedef typename graph_detail::choose_map< Selector, Label,
0281         typename graph_traits< Graph >::vertex_descriptor >::type map_type;
0282 };
0283 
0284 /**
0285  * The labeled_graph class is a graph adaptor that maintains a mapping between
0286  * vertex labels and vertex descriptors.
0287  *
0288  * @todo This class is somewhat redundant for adjacency_list<*, vecS>  if
0289  * the intended label is an unsigned int (and perhaps some other cases), but
0290  * it does avoid some weird ambiguities (i.e. adding a vertex with a label that
0291  * does not match its target index).
0292  *
0293  * @todo This needs to be reconciled with the named_graph, but since there is
0294  * no documentation or examples, its not going to happen.
0295  */
0296 template < typename Graph, typename Label, typename Selector = defaultS >
0297 class labeled_graph : protected labeled_graph_types< Graph, Label, Selector >
0298 {
0299     typedef labeled_graph_types< Graph, Label, Selector > Base;
0300 
0301 public:
0302     typedef labeled_graph_class_tag graph_tag;
0303 
0304     typedef typename Base::graph_type graph_type;
0305     typedef typename graph_traits< graph_type >::vertex_descriptor
0306         vertex_descriptor;
0307     typedef
0308         typename graph_traits< graph_type >::edge_descriptor edge_descriptor;
0309     typedef typename graph_traits< graph_type >::directed_category
0310         directed_category;
0311     typedef typename graph_traits< graph_type >::edge_parallel_category
0312         edge_parallel_category;
0313     typedef typename graph_traits< graph_type >::traversal_category
0314         traversal_category;
0315 
0316     typedef typename graph_traits< graph_type >::out_edge_iterator
0317         out_edge_iterator;
0318     typedef
0319         typename graph_traits< graph_type >::in_edge_iterator in_edge_iterator;
0320     typedef typename graph_traits< graph_type >::adjacency_iterator
0321         adjacency_iterator;
0322     typedef
0323         typename graph_traits< graph_type >::degree_size_type degree_size_type;
0324 
0325     typedef
0326         typename graph_traits< graph_type >::vertex_iterator vertex_iterator;
0327     typedef typename graph_traits< graph_type >::vertices_size_type
0328         vertices_size_type;
0329     typedef typename graph_traits< graph_type >::edge_iterator edge_iterator;
0330     typedef
0331         typename graph_traits< graph_type >::edges_size_type edges_size_type;
0332 
0333     typedef typename graph_type::graph_property_type graph_property_type;
0334     typedef typename graph_type::graph_bundled graph_bundled;
0335 
0336     typedef typename graph_type::vertex_property_type vertex_property_type;
0337     typedef typename graph_type::vertex_bundled vertex_bundled;
0338 
0339     typedef typename graph_type::edge_property_type edge_property_type;
0340     typedef typename graph_type::edge_bundled edge_bundled;
0341 
0342     typedef typename Base::label_type label_type;
0343     typedef typename Base::map_type map_type;
0344 
0345 public:
0346     labeled_graph(graph_property_type const& gp = graph_property_type())
0347     : _graph(gp), _map()
0348     {
0349     }
0350 
0351     labeled_graph(labeled_graph const& x) : _graph(x._graph), _map(x._map) {}
0352 
0353     // This constructor can only be used if map_type supports positional
0354     // range insertion (i.e. its a vector). This is the only case where we can
0355     // try to guess the intended labels for graph.
0356     labeled_graph(vertices_size_type n,
0357         graph_property_type const& gp = graph_property_type())
0358     : _graph(n, gp), _map()
0359     {
0360         std::pair< vertex_iterator, vertex_iterator > rng = vertices(_graph);
0361         _map.insert(_map.end(), rng.first, rng.second);
0362     }
0363 
0364     // Construct a graph over n vertices, each of which receives a label from
0365     // the range [l, l + n). Note that the graph is not directly constructed
0366     // over the n vertices, but added sequentially. This constructor is
0367     // necessarily slower than the underlying counterpart.
0368     template < typename LabelIter >
0369     labeled_graph(vertices_size_type n, LabelIter l,
0370         graph_property_type const& gp = graph_property_type())
0371     : _graph(gp)
0372     {
0373         while (n-- > 0)
0374             add_vertex(*l++);
0375     }
0376 
0377     // Construct the graph over n vertices each of which has a label in the
0378     // range [l, l + n) and a property in the range [p, p + n).
0379     template < typename LabelIter, typename PropIter >
0380     labeled_graph(vertices_size_type n, LabelIter l, PropIter p,
0381         graph_property_type const& gp = graph_property_type())
0382     : _graph(gp)
0383     {
0384         while (n-- > 0)
0385             add_vertex(*l++, *p++);
0386     }
0387 
0388     labeled_graph& operator=(labeled_graph const& x)
0389     {
0390         _graph = x._graph;
0391         _map = x._map;
0392         return *this;
0393     }
0394 
0395     /** @name Graph Accessors */
0396     //@{
0397     graph_type& graph() { return _graph; }
0398     graph_type const& graph() const { return _graph; }
0399     //@}
0400 
0401     /**
0402      * Create a new label for the given vertex, returning false, if the label
0403      * cannot be created.
0404      */
0405     bool label_vertex(vertex_descriptor v, Label const& l)
0406     {
0407         return graph_detail::put_vertex_label(_map, _graph, l, v);
0408     }
0409 
0410     /** @name Add Vertex
0411      * Add a vertex to the graph, returning the descriptor. If the vertices
0412      * are uniquely labeled and the label already exists within the graph,
0413      * then no vertex is added, and the returned descriptor refers to the
0414      * existing vertex. A vertex property can be given as a parameter, if
0415      * needed.
0416      */
0417     //@{
0418     vertex_descriptor add_vertex(Label const& l)
0419     {
0420         return graph_detail::insert_labeled_vertex(
0421             _map, _graph, l, vertex_property_type())
0422             .first;
0423     }
0424 
0425     vertex_descriptor add_vertex(Label const& l, vertex_property_type const& p)
0426     {
0427         return graph_detail::insert_labeled_vertex(_map, _graph, l, p).first;
0428     }
0429     //@}
0430 
0431     /** @name Insert Vertex
0432      * Insert a vertex into the graph, returning a pair containing the
0433      * descriptor of a vertex and a boolean value that describes whether or not
0434      * a new vertex was inserted. If vertices are not uniquely labeled, then
0435      * insertion will always succeed.
0436      */
0437     //@{
0438     std::pair< vertex_descriptor, bool > insert_vertex(Label const& l)
0439     {
0440         return graph_detail::insert_labeled_vertex(
0441             _map, _graph, l, vertex_property_type());
0442     }
0443 
0444     std::pair< vertex_descriptor, bool > insert_vertex(
0445         Label const& l, vertex_property_type const& p)
0446     {
0447         return graph_detail::insert_labeled_vertex(_map, _graph, l, p);
0448     }
0449     //@}
0450 
0451     /** Remove the vertex with the given label. */
0452     void remove_vertex(Label const& l)
0453     {
0454         return boost::remove_vertex(vertex(l), _graph);
0455     }
0456 
0457     /** Return a descriptor for the given label. */
0458     vertex_descriptor vertex(Label const& l) const
0459     {
0460         return graph_detail::find_labeled_vertex(_map, _graph, l);
0461     }
0462 
0463 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
0464     /** @name Bundled Properties */
0465     //@{
0466     // Lookup the requested vertex and return the bundle.
0467     vertex_bundled& operator[](Label const& l) { return _graph[vertex(l)]; }
0468 
0469     vertex_bundled const& operator[](Label const& l) const
0470     {
0471         return _graph[vertex(l)];
0472     }
0473 
0474     // Delegate edge lookup to the underlying graph.
0475     edge_bundled& operator[](edge_descriptor e) { return _graph[e]; }
0476 
0477     edge_bundled const& operator[](edge_descriptor e) const
0478     {
0479         return _graph[e];
0480     }
0481     //@}
0482 #endif
0483 
0484     /** Return a null descriptor */
0485     static vertex_descriptor null_vertex()
0486     {
0487         return graph_traits< graph_type >::null_vertex();
0488     }
0489 
0490 private:
0491     graph_type _graph;
0492     map_type _map;
0493 };
0494 
0495 /**
0496  * The partial specialization over graph pointers allows the construction
0497  * of temporary labeled graph objects. In this case, the labels are destructed
0498  * when the wrapper goes out of scope.
0499  */
0500 template < typename Graph, typename Label, typename Selector >
0501 class labeled_graph< Graph*, Label, Selector >
0502 : protected labeled_graph_types< Graph, Label, Selector >
0503 {
0504     typedef labeled_graph_types< Graph, Label, Selector > Base;
0505 
0506 public:
0507     typedef labeled_graph_class_tag graph_tag;
0508 
0509     typedef typename Base::graph_type graph_type;
0510     typedef typename graph_traits< graph_type >::vertex_descriptor
0511         vertex_descriptor;
0512     typedef
0513         typename graph_traits< graph_type >::edge_descriptor edge_descriptor;
0514     typedef typename graph_traits< graph_type >::directed_category
0515         directed_category;
0516     typedef typename graph_traits< graph_type >::edge_parallel_category
0517         edge_parallel_category;
0518     typedef typename graph_traits< graph_type >::traversal_category
0519         traversal_category;
0520 
0521     typedef typename graph_traits< graph_type >::out_edge_iterator
0522         out_edge_iterator;
0523     typedef
0524         typename graph_traits< graph_type >::in_edge_iterator in_edge_iterator;
0525     typedef typename graph_traits< graph_type >::adjacency_iterator
0526         adjacency_iterator;
0527     typedef
0528         typename graph_traits< graph_type >::degree_size_type degree_size_type;
0529 
0530     typedef
0531         typename graph_traits< graph_type >::vertex_iterator vertex_iterator;
0532     typedef typename graph_traits< graph_type >::vertices_size_type
0533         vertices_size_type;
0534     typedef typename graph_traits< graph_type >::edge_iterator edge_iterator;
0535     typedef
0536         typename graph_traits< graph_type >::edges_size_type edges_size_type;
0537 
0538     typedef typename graph_type::vertex_property_type vertex_property_type;
0539     typedef typename graph_type::edge_property_type edge_property_type;
0540     typedef typename graph_type::graph_property_type graph_property_type;
0541     typedef typename graph_type::vertex_bundled vertex_bundled;
0542     typedef typename graph_type::edge_bundled edge_bundled;
0543 
0544     typedef typename Base::label_type label_type;
0545     typedef typename Base::map_type map_type;
0546 
0547     labeled_graph(graph_type* g) : _graph(g) {}
0548 
0549     /** @name Graph Access */
0550     //@{
0551     graph_type& graph() { return *_graph; }
0552     graph_type const& graph() const { return *_graph; }
0553     //@}
0554 
0555     /**
0556      * Create a new label for the given vertex, returning false, if the label
0557      * cannot be created.
0558      */
0559     bool label_vertex(vertex_descriptor v, Label const& l)
0560     {
0561         return graph_detail::put_vertex_label(_map, *_graph, l, v);
0562     }
0563 
0564     /** @name Add Vertex */
0565     //@{
0566     vertex_descriptor add_vertex(Label const& l)
0567     {
0568         return graph_detail::insert_labeled_vertex(
0569             _map, *_graph, l, vertex_property_type())
0570             .first;
0571     }
0572 
0573     vertex_descriptor add_vertex(Label const& l, vertex_property_type const& p)
0574     {
0575         return graph_detail::insert_labeled_vertex(_map, *_graph, l, p).first;
0576     }
0577 
0578     std::pair< vertex_descriptor, bool > insert_vertex(Label const& l)
0579     {
0580         return graph_detail::insert_labeled_vertex(
0581             _map, *_graph, l, vertex_property_type());
0582     }
0583     //@}
0584 
0585     /** Try to insert a vertex with the given label. */
0586     std::pair< vertex_descriptor, bool > insert_vertex(
0587         Label const& l, vertex_property_type const& p)
0588     {
0589         return graph_detail::insert_labeled_vertex(_map, *_graph, l, p);
0590     }
0591 
0592     /** Remove the vertex with the given label. */
0593     void remove_vertex(Label const& l)
0594     {
0595         return boost::remove_vertex(vertex(l), *_graph);
0596     }
0597 
0598     /** Return a descriptor for the given label. */
0599     vertex_descriptor vertex(Label const& l) const
0600     {
0601         return graph_detail::find_labeled_vertex(_map, *_graph, l);
0602     }
0603 
0604 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
0605     /** @name Bundled Properties */
0606     //@{
0607     // Lookup the requested vertex and return the bundle.
0608     vertex_bundled& operator[](Label const& l) { return (*_graph)[vertex(l)]; }
0609 
0610     vertex_bundled const& operator[](Label const& l) const
0611     {
0612         return (*_graph)[vertex(l)];
0613     }
0614 
0615     // Delegate edge lookup to the underlying graph.
0616     edge_bundled& operator[](edge_descriptor e) { return (*_graph)[e]; }
0617 
0618     edge_bundled const& operator[](edge_descriptor e) const
0619     {
0620         return (*_graph)[e];
0621     }
0622     //@}
0623 #endif
0624 
0625     static vertex_descriptor null_vertex()
0626     {
0627         return graph_traits< graph_type >::null_vertex();
0628     }
0629 
0630 private:
0631     graph_type* _graph;
0632     map_type _map;
0633 };
0634 
0635 #define LABELED_GRAPH_PARAMS typename G, typename L, typename S
0636 #define LABELED_GRAPH labeled_graph< G, L, S >
0637 
0638 /** @name Labeled Graph */
0639 //@{
0640 template < LABELED_GRAPH_PARAMS >
0641 inline bool label_vertex(typename LABELED_GRAPH::vertex_descriptor v,
0642     typename LABELED_GRAPH::label_type const l, LABELED_GRAPH& g)
0643 {
0644     return g.label_vertex(v, l);
0645 }
0646 
0647 template < LABELED_GRAPH_PARAMS >
0648 inline typename LABELED_GRAPH::vertex_descriptor vertex_by_label(
0649     typename LABELED_GRAPH::label_type const l, LABELED_GRAPH& g)
0650 {
0651     return g.vertex(l);
0652 }
0653 //@}
0654 
0655 /** @name Graph */
0656 //@{
0657 template < LABELED_GRAPH_PARAMS >
0658 inline std::pair< typename LABELED_GRAPH::edge_descriptor, bool > edge(
0659     typename LABELED_GRAPH::vertex_descriptor const& u,
0660     typename LABELED_GRAPH::vertex_descriptor const& v, LABELED_GRAPH const& g)
0661 {
0662     return edge(u, v, g.graph());
0663 }
0664 
0665 // Labeled Extensions
0666 template < LABELED_GRAPH_PARAMS >
0667 inline std::pair< typename LABELED_GRAPH::edge_descriptor, bool > edge_by_label(
0668     typename LABELED_GRAPH::label_type const& u,
0669     typename LABELED_GRAPH::label_type const& v, LABELED_GRAPH const& g)
0670 {
0671     return edge(g.vertex(u), g.vertex(v), g);
0672 }
0673 //@}
0674 
0675 /** @name Incidence Graph */
0676 //@{
0677 template < LABELED_GRAPH_PARAMS >
0678 inline std::pair< typename LABELED_GRAPH::out_edge_iterator,
0679     typename LABELED_GRAPH::out_edge_iterator >
0680 out_edges(typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
0681 {
0682     return out_edges(v, g.graph());
0683 }
0684 
0685 template < LABELED_GRAPH_PARAMS >
0686 inline typename LABELED_GRAPH::degree_size_type out_degree(
0687     typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
0688 {
0689     return out_degree(v, g.graph());
0690 }
0691 
0692 template < LABELED_GRAPH_PARAMS >
0693 inline typename LABELED_GRAPH::vertex_descriptor source(
0694     typename LABELED_GRAPH::edge_descriptor e, LABELED_GRAPH const& g)
0695 {
0696     return source(e, g.graph());
0697 }
0698 
0699 template < LABELED_GRAPH_PARAMS >
0700 inline typename LABELED_GRAPH::vertex_descriptor target(
0701     typename LABELED_GRAPH::edge_descriptor e, LABELED_GRAPH const& g)
0702 {
0703     return target(e, g.graph());
0704 }
0705 //@}
0706 
0707 /** @name Bidirectional Graph */
0708 //@{
0709 template < LABELED_GRAPH_PARAMS >
0710 inline std::pair< typename LABELED_GRAPH::in_edge_iterator,
0711     typename LABELED_GRAPH::in_edge_iterator >
0712 in_edges(typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
0713 {
0714     return in_edges(v, g.graph());
0715 }
0716 
0717 template < LABELED_GRAPH_PARAMS >
0718 inline typename LABELED_GRAPH::degree_size_type in_degree(
0719     typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
0720 {
0721     return in_degree(v, g.graph());
0722 }
0723 
0724 template < LABELED_GRAPH_PARAMS >
0725 inline typename LABELED_GRAPH::degree_size_type degree(
0726     typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
0727 {
0728     return degree(v, g.graph());
0729 }
0730 //@}
0731 
0732 /** @name Adjacency Graph */
0733 //@{
0734 template < LABELED_GRAPH_PARAMS >
0735 inline std::pair< typename LABELED_GRAPH::adjacency_iterator,
0736     typename LABELED_GRAPH::adjacency_iterator >
0737 adjacenct_vertices(
0738     typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
0739 {
0740     return adjacent_vertices(v, g.graph());
0741 }
0742 //@}
0743 
0744 /** @name VertexListGraph */
0745 //@{
0746 template < LABELED_GRAPH_PARAMS >
0747 inline std::pair< typename LABELED_GRAPH::vertex_iterator,
0748     typename LABELED_GRAPH::vertex_iterator >
0749 vertices(LABELED_GRAPH const& g)
0750 {
0751     return vertices(g.graph());
0752 }
0753 
0754 template < LABELED_GRAPH_PARAMS >
0755 inline typename LABELED_GRAPH::vertices_size_type num_vertices(
0756     LABELED_GRAPH const& g)
0757 {
0758     return num_vertices(g.graph());
0759 }
0760 //@}
0761 
0762 /** @name EdgeListGraph */
0763 //@{
0764 template < LABELED_GRAPH_PARAMS >
0765 inline std::pair< typename LABELED_GRAPH::edge_iterator,
0766     typename LABELED_GRAPH::edge_iterator >
0767 edges(LABELED_GRAPH const& g)
0768 {
0769     return edges(g.graph());
0770 }
0771 
0772 template < LABELED_GRAPH_PARAMS >
0773 inline typename LABELED_GRAPH::edges_size_type num_edges(LABELED_GRAPH const& g)
0774 {
0775     return num_edges(g.graph());
0776 }
0777 //@}
0778 
0779 /** @internal @name Property Lookup */
0780 //@{
0781 namespace graph_detail
0782 {
0783     struct labeled_graph_vertex_property_selector
0784     {
0785         template < class LabeledGraph, class Property, class Tag > struct bind_
0786         {
0787             typedef typename LabeledGraph::graph_type Graph;
0788             typedef property_map< Graph, Tag > PropertyMap;
0789             typedef typename PropertyMap::type type;
0790             typedef typename PropertyMap::const_type const_type;
0791         };
0792     };
0793 
0794     struct labeled_graph_edge_property_selector
0795     {
0796         template < class LabeledGraph, class Property, class Tag > struct bind_
0797         {
0798             typedef typename LabeledGraph::graph_type Graph;
0799             typedef property_map< Graph, Tag > PropertyMap;
0800             typedef typename PropertyMap::type type;
0801             typedef typename PropertyMap::const_type const_type;
0802         };
0803     };
0804 }
0805 
0806 template <> struct vertex_property_selector< labeled_graph_class_tag >
0807 {
0808     typedef graph_detail::labeled_graph_vertex_property_selector type;
0809 };
0810 
0811 template <> struct edge_property_selector< labeled_graph_class_tag >
0812 {
0813     typedef graph_detail::labeled_graph_edge_property_selector type;
0814 };
0815 //@}
0816 
0817 /** @name Property Graph */
0818 //@{
0819 template < LABELED_GRAPH_PARAMS, typename Prop >
0820 inline typename property_map< LABELED_GRAPH, Prop >::type get(
0821     Prop p, LABELED_GRAPH& g)
0822 {
0823     return get(p, g.graph());
0824 }
0825 
0826 template < LABELED_GRAPH_PARAMS, typename Prop >
0827 inline typename property_map< LABELED_GRAPH, Prop >::const_type get(
0828     Prop p, LABELED_GRAPH const& g)
0829 {
0830     return get(p, g.graph());
0831 }
0832 
0833 template < LABELED_GRAPH_PARAMS, typename Prop, typename Key >
0834 inline typename property_traits< typename property_map<
0835     typename LABELED_GRAPH::graph_type, Prop >::const_type >::value_type
0836 get(Prop p, LABELED_GRAPH const& g, const Key& k)
0837 {
0838     return get(p, g.graph(), k);
0839 }
0840 
0841 template < LABELED_GRAPH_PARAMS, typename Prop, typename Key, typename Value >
0842 inline void put(Prop p, LABELED_GRAPH& g, Key const& k, Value const& v)
0843 {
0844     put(p, g.graph(), k, v);
0845 }
0846 //@}
0847 
0848 /** @name Mutable Graph */
0849 //@{
0850 template < LABELED_GRAPH_PARAMS >
0851 inline std::pair< typename LABELED_GRAPH::edge_descriptor, bool > add_edge(
0852     typename LABELED_GRAPH::vertex_descriptor const& u,
0853     typename LABELED_GRAPH::vertex_descriptor const& v, LABELED_GRAPH& g)
0854 {
0855     return add_edge(u, v, g.graph());
0856 }
0857 
0858 template < LABELED_GRAPH_PARAMS >
0859 inline std::pair< typename LABELED_GRAPH::edge_descriptor, bool > add_edge(
0860     typename LABELED_GRAPH::vertex_descriptor const& u,
0861     typename LABELED_GRAPH::vertex_descriptor const& v,
0862     typename LABELED_GRAPH::edge_property_type const& p, LABELED_GRAPH& g)
0863 {
0864     return add_edge(u, v, p, g.graph());
0865 }
0866 
0867 template < LABELED_GRAPH_PARAMS >
0868 inline void clear_vertex(
0869     typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH& g)
0870 {
0871     return clear_vertex(v, g.graph());
0872 }
0873 
0874 template < LABELED_GRAPH_PARAMS >
0875 inline void remove_edge(
0876     typename LABELED_GRAPH::edge_descriptor e, LABELED_GRAPH& g)
0877 {
0878     return remove_edge(e, g.graph());
0879 }
0880 
0881 template < LABELED_GRAPH_PARAMS >
0882 inline void remove_edge(typename LABELED_GRAPH::vertex_descriptor u,
0883     typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH& g)
0884 {
0885     return remove_edge(u, v, g.graph());
0886 }
0887 
0888 // Labeled extensions
0889 template < LABELED_GRAPH_PARAMS >
0890 inline std::pair< typename LABELED_GRAPH::edge_descriptor, bool >
0891 add_edge_by_label(typename LABELED_GRAPH::label_type const& u,
0892     typename LABELED_GRAPH::label_type const& v, LABELED_GRAPH& g)
0893 {
0894     return add_edge(g.vertex(u), g.vertex(v), g);
0895 }
0896 
0897 template < LABELED_GRAPH_PARAMS >
0898 inline std::pair< typename LABELED_GRAPH::edge_descriptor, bool >
0899 add_edge_by_label(typename LABELED_GRAPH::label_type const& u,
0900     typename LABELED_GRAPH::label_type const& v,
0901     typename LABELED_GRAPH::edge_property_type const& p, LABELED_GRAPH& g)
0902 {
0903     return add_edge(g.vertex(u), g.vertex(v), p, g);
0904 }
0905 
0906 template < LABELED_GRAPH_PARAMS >
0907 inline void clear_vertex_by_label(
0908     typename LABELED_GRAPH::label_type const& l, LABELED_GRAPH& g)
0909 {
0910     clear_vertex(g.vertex(l), g.graph());
0911 }
0912 
0913 template < LABELED_GRAPH_PARAMS >
0914 inline void remove_edge_by_label(typename LABELED_GRAPH::label_type const& u,
0915     typename LABELED_GRAPH::label_type const& v, LABELED_GRAPH& g)
0916 {
0917     remove_edge(g.vertex(u), g.vertex(v), g.graph());
0918 }
0919 //@}
0920 
0921 /** @name Labeled Mutable Graph
0922  * The labeled mutable graph hides the add_ and remove_ vertex functions from
0923  * the mutable graph concept. Note that the remove_vertex is hidden because
0924  * removing the vertex without its key could leave a dangling reference in
0925  * the map.
0926  */
0927 //@{
0928 template < LABELED_GRAPH_PARAMS >
0929 inline typename LABELED_GRAPH::vertex_descriptor add_vertex(
0930     typename LABELED_GRAPH::label_type const& l, LABELED_GRAPH& g)
0931 {
0932     return g.add_vertex(l);
0933 }
0934 
0935 // MutableLabeledPropertyGraph::add_vertex(l, vp, g)
0936 template < LABELED_GRAPH_PARAMS >
0937 inline typename LABELED_GRAPH::vertex_descriptor add_vertex(
0938     typename LABELED_GRAPH::label_type const& l,
0939     typename LABELED_GRAPH::vertex_property_type const& p, LABELED_GRAPH& g)
0940 {
0941     return g.add_vertex(l, p);
0942 }
0943 
0944 template < LABELED_GRAPH_PARAMS >
0945 inline void remove_vertex(
0946     typename LABELED_GRAPH::label_type const& l, LABELED_GRAPH& g)
0947 {
0948     g.remove_vertex(l);
0949 }
0950 //@}
0951 
0952 #undef LABELED_GRAPH_PARAMS
0953 #undef LABELED_GRAPH
0954 
0955 } // namespace boost
0956 
0957 // Pull the labeled graph traits
0958 #include <boost/graph/detail/labeled_graph_traits.hpp>
0959 
0960 #endif // BOOST_GRAPH_LABELED_GRAPH_HPP