annotate DEPENDENCIES/generic/include/boost/graph/labeled_graph.hpp @ 133:4acb5d8d80b6 tip

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