Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-15 08:35:56

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