annotate DEPENDENCIES/generic/include/boost/graph/subgraph.hpp @ 118:770eb830ec19 emscripten

Typo fix
author Chris Cannam
date Wed, 18 May 2016 16:14:08 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 //=======================================================================
Chris@16 2 // Copyright 2001 University of Notre Dame.
Chris@16 3 // Authors: Jeremy G. Siek and Lie-Quan Lee
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 //=======================================================================
Chris@16 9
Chris@16 10 #ifndef BOOST_SUBGRAPH_HPP
Chris@16 11 #define BOOST_SUBGRAPH_HPP
Chris@16 12
Chris@16 13 // UNDER CONSTRUCTION
Chris@16 14
Chris@16 15 #include <boost/config.hpp>
Chris@16 16 #include <list>
Chris@16 17 #include <vector>
Chris@16 18 #include <map>
Chris@16 19 #include <boost/assert.hpp>
Chris@16 20 #include <boost/graph/graph_traits.hpp>
Chris@16 21 #include <boost/graph/graph_mutability_traits.hpp>
Chris@16 22 #include <boost/graph/properties.hpp>
Chris@16 23 #include <boost/iterator/indirect_iterator.hpp>
Chris@16 24
Chris@16 25 #include <boost/static_assert.hpp>
Chris@16 26 #include <boost/assert.hpp>
Chris@16 27 #include <boost/type_traits.hpp>
Chris@16 28 #include <boost/mpl/if.hpp>
Chris@16 29 #include <boost/mpl/or.hpp>
Chris@16 30
Chris@16 31 namespace boost {
Chris@16 32
Chris@16 33 struct subgraph_tag { };
Chris@16 34
Chris@16 35 /** @name Property Lookup
Chris@16 36 * The local_property and global_property functions are used to create
Chris@16 37 * structures that determine the lookup strategy for properties in subgraphs.
Chris@16 38 * Note that the nested kind member is used to help interoperate with actual
Chris@16 39 * Property types.
Chris@16 40 */
Chris@16 41 //@{
Chris@16 42 template <typename T>
Chris@16 43 struct local_property
Chris@16 44 {
Chris@16 45 typedef T kind;
Chris@16 46 local_property(T x) : value(x) { }
Chris@16 47 T value;
Chris@16 48 };
Chris@16 49
Chris@16 50 template <typename T>
Chris@16 51 inline local_property<T> local(T x)
Chris@16 52 { return local_property<T>(x); }
Chris@16 53
Chris@16 54 template <typename T>
Chris@16 55 struct global_property
Chris@16 56 {
Chris@16 57 typedef T kind;
Chris@16 58 global_property(T x) : value(x) { }
Chris@16 59 T value;
Chris@16 60 };
Chris@16 61
Chris@16 62 template <typename T>
Chris@16 63 inline global_property<T> global(T x)
Chris@16 64 { return global_property<T>(x); }
Chris@16 65 //@}
Chris@16 66
Chris@16 67 // Invariants of an induced subgraph:
Chris@16 68 // - If vertex u is in subgraph g, then u must be in g.parent().
Chris@16 69 // - If edge e is in subgraph g, then e must be in g.parent().
Chris@16 70 // - If edge e=(u,v) is in the root graph, then edge e
Chris@16 71 // is also in any subgraph that contains both vertex u and v.
Chris@16 72
Chris@16 73 // The Graph template parameter must have a vertex_index and edge_index
Chris@16 74 // internal property. It is assumed that the vertex indices are assigned
Chris@16 75 // automatically by the graph during a call to add_vertex(). It is not
Chris@16 76 // assumed that the edge vertices are assigned automatically, they are
Chris@16 77 // explicitly assigned here.
Chris@16 78
Chris@16 79 template <typename Graph>
Chris@16 80 class subgraph {
Chris@16 81 typedef graph_traits<Graph> Traits;
Chris@16 82 typedef std::list<subgraph<Graph>*> ChildrenList;
Chris@16 83 public:
Chris@16 84 // Graph requirements
Chris@16 85 typedef typename Traits::vertex_descriptor vertex_descriptor;
Chris@16 86 typedef typename Traits::edge_descriptor edge_descriptor;
Chris@16 87 typedef typename Traits::directed_category directed_category;
Chris@16 88 typedef typename Traits::edge_parallel_category edge_parallel_category;
Chris@16 89 typedef typename Traits::traversal_category traversal_category;
Chris@16 90
Chris@16 91 // IncidenceGraph requirements
Chris@16 92 typedef typename Traits::out_edge_iterator out_edge_iterator;
Chris@16 93 typedef typename Traits::degree_size_type degree_size_type;
Chris@16 94
Chris@16 95 // AdjacencyGraph requirements
Chris@16 96 typedef typename Traits::adjacency_iterator adjacency_iterator;
Chris@16 97
Chris@16 98 // VertexListGraph requirements
Chris@16 99 typedef typename Traits::vertex_iterator vertex_iterator;
Chris@16 100 typedef typename Traits::vertices_size_type vertices_size_type;
Chris@16 101
Chris@16 102 // EdgeListGraph requirements
Chris@16 103 typedef typename Traits::edge_iterator edge_iterator;
Chris@16 104 typedef typename Traits::edges_size_type edges_size_type;
Chris@16 105
Chris@16 106 typedef typename Traits::in_edge_iterator in_edge_iterator;
Chris@16 107
Chris@16 108 typedef typename edge_property_type<Graph>::type edge_property_type;
Chris@16 109 typedef typename vertex_property_type<Graph>::type vertex_property_type;
Chris@16 110 typedef subgraph_tag graph_tag;
Chris@16 111 typedef Graph graph_type;
Chris@16 112 typedef typename graph_property_type<Graph>::type graph_property_type;
Chris@16 113
Chris@16 114 // Create the main graph, the root of the subgraph tree
Chris@16 115 subgraph()
Chris@16 116 : m_parent(0), m_edge_counter(0)
Chris@16 117 { }
Chris@16 118
Chris@16 119 subgraph(const graph_property_type& p)
Chris@16 120 : m_graph(p), m_parent(0), m_edge_counter(0)
Chris@16 121 { }
Chris@16 122
Chris@16 123 subgraph(vertices_size_type n, const graph_property_type& p = graph_property_type())
Chris@16 124 : m_graph(n, p), m_parent(0), m_edge_counter(0), m_global_vertex(n)
Chris@16 125 {
Chris@16 126 typename Graph::vertex_iterator v, v_end;
Chris@16 127 vertices_size_type i = 0;
Chris@16 128 for(boost::tie(v, v_end) = vertices(m_graph); v != v_end; ++v)
Chris@16 129 m_global_vertex[i++] = *v;
Chris@16 130 }
Chris@16 131
Chris@16 132 // copy constructor
Chris@16 133 subgraph(const subgraph& x)
Chris@16 134 : m_parent(x.m_parent), m_edge_counter(x.m_edge_counter)
Chris@16 135 , m_global_vertex(x.m_global_vertex), m_global_edge(x.m_global_edge)
Chris@16 136 {
Chris@16 137 if(x.is_root())
Chris@16 138 {
Chris@16 139 m_graph = x.m_graph;
Chris@16 140 }
Chris@16 141 // Do a deep copy (recursive).
Chris@16 142 // Only the root graph is copied, the subgraphs contain
Chris@16 143 // only references to the global vertices they own.
Chris@16 144 typename subgraph<Graph>::children_iterator i,i_end;
Chris@16 145 boost::tie(i,i_end) = x.children();
Chris@16 146 for(; i != i_end; ++i)
Chris@16 147 {
Chris@16 148 subgraph<Graph> child = this->create_subgraph();
Chris@16 149 child = *i;
Chris@16 150 vertex_iterator vi,vi_end;
Chris@16 151 boost::tie(vi,vi_end) = vertices(*i);
Chris@16 152 for (;vi!=vi_end;++vi)
Chris@16 153 {
Chris@16 154 add_vertex(*vi,child);
Chris@16 155 }
Chris@16 156 }
Chris@16 157 }
Chris@16 158
Chris@16 159
Chris@16 160 ~subgraph() {
Chris@16 161 for(typename ChildrenList::iterator i = m_children.begin();
Chris@16 162 i != m_children.end(); ++i)
Chris@16 163 {
Chris@16 164 delete *i;
Chris@16 165 }
Chris@16 166 }
Chris@16 167
Chris@16 168 // Return a null vertex descriptor for the graph.
Chris@16 169 static vertex_descriptor null_vertex()
Chris@16 170 { return Traits::null_vertex(); }
Chris@16 171
Chris@16 172
Chris@16 173 // Create a subgraph
Chris@16 174 subgraph<Graph>& create_subgraph() {
Chris@16 175 m_children.push_back(new subgraph<Graph>());
Chris@16 176 m_children.back()->m_parent = this;
Chris@16 177 return *m_children.back();
Chris@16 178 }
Chris@16 179
Chris@16 180 // Create a subgraph with the specified vertex set.
Chris@16 181 template <typename VertexIterator>
Chris@16 182 subgraph<Graph>& create_subgraph(VertexIterator first, VertexIterator last) {
Chris@16 183 m_children.push_back(new subgraph<Graph>());
Chris@16 184 m_children.back()->m_parent = this;
Chris@16 185 for(; first != last; ++first) {
Chris@16 186 add_vertex(*first, *m_children.back());
Chris@16 187 }
Chris@16 188 return *m_children.back();
Chris@16 189 }
Chris@16 190
Chris@16 191 // local <-> global descriptor conversion functions
Chris@16 192 vertex_descriptor local_to_global(vertex_descriptor u_local) const
Chris@16 193 { return is_root() ? u_local : m_global_vertex[u_local]; }
Chris@16 194
Chris@16 195 vertex_descriptor global_to_local(vertex_descriptor u_global) const {
Chris@16 196 vertex_descriptor u_local; bool in_subgraph;
Chris@16 197 if (is_root()) return u_global;
Chris@16 198 boost::tie(u_local, in_subgraph) = this->find_vertex(u_global);
Chris@16 199 BOOST_ASSERT(in_subgraph == true);
Chris@16 200 return u_local;
Chris@16 201 }
Chris@16 202
Chris@16 203 edge_descriptor local_to_global(edge_descriptor e_local) const
Chris@16 204 { return is_root() ? e_local : m_global_edge[get(get(edge_index, m_graph), e_local)]; }
Chris@16 205
Chris@16 206 edge_descriptor global_to_local(edge_descriptor e_global) const
Chris@16 207 { return is_root() ? e_global : (*m_local_edge.find(get(get(edge_index, root().m_graph), e_global))).second; }
Chris@16 208
Chris@16 209 // Is vertex u (of the root graph) contained in this subgraph?
Chris@16 210 // If so, return the matching local vertex.
Chris@16 211 std::pair<vertex_descriptor, bool>
Chris@16 212 find_vertex(vertex_descriptor u_global) const {
Chris@16 213 if (is_root()) return std::make_pair(u_global, true);
Chris@16 214 typename LocalVertexMap::const_iterator i = m_local_vertex.find(u_global);
Chris@16 215 bool valid = i != m_local_vertex.end();
Chris@16 216 return std::make_pair((valid ? (*i).second : null_vertex()), valid);
Chris@16 217 }
Chris@16 218
Chris@16 219 // Is edge e (of the root graph) contained in this subgraph?
Chris@16 220 // If so, return the matching local edge.
Chris@16 221 std::pair<edge_descriptor, bool>
Chris@16 222 find_edge(edge_descriptor e_global) const {
Chris@16 223 if (is_root()) return std::make_pair(e_global, true);
Chris@16 224 typename LocalEdgeMap::const_iterator i =
Chris@16 225 m_local_edge.find(get(get(edge_index, root().m_graph), e_global));
Chris@16 226 bool valid = i != m_local_edge.end();
Chris@16 227 return std::make_pair((valid ? (*i).second : edge_descriptor()), valid);
Chris@16 228 }
Chris@16 229
Chris@16 230 // Return the parent graph.
Chris@16 231 subgraph& parent() { return *m_parent; }
Chris@16 232 const subgraph& parent() const { return *m_parent; }
Chris@16 233
Chris@16 234 // Return true if this is the root subgraph
Chris@16 235 bool is_root() const { return m_parent == 0; }
Chris@16 236
Chris@16 237 // Return the root graph of the subgraph tree.
Chris@16 238 subgraph& root()
Chris@16 239 { return is_root() ? *this : m_parent->root(); }
Chris@16 240
Chris@16 241 const subgraph& root() const
Chris@16 242 { return is_root() ? *this : m_parent->root(); }
Chris@16 243
Chris@16 244 // Return the children subgraphs of this graph/subgraph.
Chris@16 245 // Use a list of pointers because the VC++ std::list doesn't like
Chris@16 246 // storing incomplete type.
Chris@16 247 typedef indirect_iterator<
Chris@16 248 typename ChildrenList::const_iterator
Chris@16 249 , subgraph<Graph>
Chris@16 250 , std::bidirectional_iterator_tag
Chris@16 251 >
Chris@16 252 children_iterator;
Chris@16 253
Chris@16 254 typedef indirect_iterator<
Chris@16 255 typename ChildrenList::const_iterator
Chris@16 256 , subgraph<Graph> const
Chris@16 257 , std::bidirectional_iterator_tag
Chris@16 258 >
Chris@16 259 const_children_iterator;
Chris@16 260
Chris@16 261 std::pair<const_children_iterator, const_children_iterator> children() const {
Chris@16 262 return std::make_pair(const_children_iterator(m_children.begin()),
Chris@16 263 const_children_iterator(m_children.end()));
Chris@16 264 }
Chris@16 265
Chris@16 266 std::pair<children_iterator, children_iterator> children() {
Chris@16 267 return std::make_pair(children_iterator(m_children.begin()),
Chris@16 268 children_iterator(m_children.end()));
Chris@16 269 }
Chris@16 270
Chris@16 271 std::size_t num_children() const { return m_children.size(); }
Chris@16 272
Chris@16 273 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
Chris@16 274 // Defualt property access delegates the lookup to global properties.
Chris@16 275 template <typename Descriptor>
Chris@16 276 typename graph::detail::bundled_result<Graph, Descriptor>::type&
Chris@16 277 operator[](Descriptor x)
Chris@16 278 { return is_root() ? m_graph[x] : root().m_graph[local_to_global(x)]; }
Chris@16 279
Chris@16 280 template <typename Descriptor>
Chris@16 281 typename graph::detail::bundled_result<Graph, Descriptor>::type const&
Chris@16 282 operator[](Descriptor x) const
Chris@16 283 { return is_root() ? m_graph[x] : root().m_graph[local_to_global(x)]; }
Chris@16 284
Chris@16 285 // Local property access returns the local property of the given descripor.
Chris@16 286 template <typename Descriptor>
Chris@16 287 typename graph::detail::bundled_result<Graph, Descriptor>::type&
Chris@16 288 operator[](local_property<Descriptor> x)
Chris@16 289 { return m_graph[x.value]; }
Chris@16 290
Chris@16 291 template <typename Descriptor>
Chris@16 292 typename graph::detail::bundled_result<Graph, Descriptor>::type const&
Chris@16 293 operator[](local_property<Descriptor> x) const
Chris@16 294 { return m_graph[x.value]; }
Chris@16 295
Chris@16 296 // Global property access returns the global property associated with the
Chris@16 297 // given descriptor. This is an alias for the default bundled property
Chris@16 298 // access operations.
Chris@16 299 template <typename Descriptor>
Chris@16 300 typename graph::detail::bundled_result<Graph, Descriptor>::type&
Chris@16 301 operator[](global_property<Descriptor> x)
Chris@16 302 { return (*this)[x.value]; }
Chris@16 303
Chris@16 304 template <typename Descriptor>
Chris@16 305 typename graph::detail::bundled_result<Graph, Descriptor>::type const&
Chris@16 306 operator[](global_property<Descriptor> x) const
Chris@16 307 { return (*this)[x.value]; }
Chris@16 308
Chris@16 309 #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
Chris@16 310
Chris@16 311 // private:
Chris@16 312 typedef typename property_map<Graph, edge_index_t>::type EdgeIndexMap;
Chris@16 313 typedef typename property_traits<EdgeIndexMap>::value_type edge_index_type;
Chris@16 314 BOOST_STATIC_ASSERT((!is_same<edge_index_type,
Chris@16 315 boost::detail::error_property_not_found>::value));
Chris@16 316
Chris@16 317 private:
Chris@16 318 typedef std::vector<vertex_descriptor> GlobalVertexList;
Chris@16 319 typedef std::vector<edge_descriptor> GlobalEdgeList;
Chris@16 320 typedef std::map<vertex_descriptor, vertex_descriptor> LocalVertexMap;
Chris@16 321 typedef std::map<edge_index_type, edge_descriptor> LocalEdgeMap;
Chris@16 322 // TODO: Should the LocalVertexMap be: map<index_type, descriptor>?
Chris@16 323 // TODO: Can we relax the indexing requirement if both descriptors are
Chris@16 324 // LessThanComparable?
Chris@16 325 // TODO: Should we really be using unorderd_map for improved lookup times?
Chris@16 326
Chris@16 327 public: // Probably shouldn't be public....
Chris@16 328 Graph m_graph;
Chris@16 329 subgraph<Graph>* m_parent;
Chris@16 330 edge_index_type m_edge_counter; // for generating unique edge indices
Chris@16 331 ChildrenList m_children;
Chris@16 332 GlobalVertexList m_global_vertex; // local -> global
Chris@16 333 LocalVertexMap m_local_vertex; // global -> local
Chris@16 334 GlobalEdgeList m_global_edge; // local -> global
Chris@16 335 LocalEdgeMap m_local_edge; // global -> local
Chris@16 336
Chris@16 337 edge_descriptor local_add_edge(vertex_descriptor u_local,
Chris@16 338 vertex_descriptor v_local,
Chris@16 339 edge_descriptor e_global)
Chris@16 340 {
Chris@16 341 edge_descriptor e_local;
Chris@16 342 bool inserted;
Chris@16 343 boost::tie(e_local, inserted) = add_edge(u_local, v_local, m_graph);
Chris@16 344 put(edge_index, m_graph, e_local, m_edge_counter++);
Chris@16 345 m_global_edge.push_back(e_global);
Chris@16 346 m_local_edge[get(get(edge_index, this->root()), e_global)] = e_local;
Chris@16 347 return e_local;
Chris@16 348 }
Chris@16 349 };
Chris@16 350
Chris@16 351 template <typename Graph>
Chris@16 352 struct vertex_bundle_type<subgraph<Graph> >
Chris@16 353 : vertex_bundle_type<Graph>
Chris@16 354 { };
Chris@16 355
Chris@16 356 template<typename Graph>
Chris@16 357 struct edge_bundle_type<subgraph<Graph> >
Chris@16 358 : edge_bundle_type<Graph>
Chris@16 359 { };
Chris@16 360
Chris@16 361 template<typename Graph>
Chris@16 362 struct graph_bundle_type<subgraph<Graph> >
Chris@16 363 : graph_bundle_type<Graph>
Chris@16 364 { };
Chris@16 365
Chris@16 366 //===========================================================================
Chris@16 367 // Functions special to the Subgraph Class
Chris@16 368
Chris@16 369 template <typename G>
Chris@16 370 typename subgraph<G>::vertex_descriptor
Chris@16 371 add_vertex(typename subgraph<G>::vertex_descriptor u_global,
Chris@16 372 subgraph<G>& g)
Chris@16 373 {
Chris@16 374 BOOST_ASSERT(!g.is_root());
Chris@16 375 typename subgraph<G>::vertex_descriptor u_local, v_global;
Chris@16 376 typename subgraph<G>::edge_descriptor e_global;
Chris@16 377
Chris@16 378 u_local = add_vertex(g.m_graph);
Chris@16 379 g.m_global_vertex.push_back(u_global);
Chris@16 380 g.m_local_vertex[u_global] = u_local;
Chris@16 381
Chris@16 382 subgraph<G>& r = g.root();
Chris@16 383
Chris@16 384 // remember edge global and local maps
Chris@16 385 {
Chris@16 386 typename subgraph<G>::out_edge_iterator ei, ei_end;
Chris@16 387 for (boost::tie(ei, ei_end) = out_edges(u_global, r);
Chris@16 388 ei != ei_end; ++ei) {
Chris@16 389 e_global = *ei;
Chris@16 390 v_global = target(e_global, r);
Chris@16 391 if (g.find_vertex(v_global).second == true)
Chris@16 392 g.local_add_edge(u_local, g.global_to_local(v_global), e_global);
Chris@16 393 }
Chris@16 394 }
Chris@16 395 if (is_directed(g)) { // not necessary for undirected graph
Chris@16 396 typename subgraph<G>::vertex_iterator vi, vi_end;
Chris@16 397 typename subgraph<G>::out_edge_iterator ei, ei_end;
Chris@16 398 for(boost::tie(vi, vi_end) = vertices(r); vi != vi_end; ++vi) {
Chris@16 399 v_global = *vi;
Chris@16 400 if (v_global == u_global)
Chris@16 401 continue; // don't insert self loops twice!
Chris@16 402 if (!g.find_vertex(v_global).second)
Chris@16 403 continue; // not a subgraph vertex => try next one
Chris@16 404 for(boost::tie(ei, ei_end) = out_edges(*vi, r); ei != ei_end; ++ei) {
Chris@16 405 e_global = *ei;
Chris@16 406 if(target(e_global, r) == u_global) {
Chris@16 407 g.local_add_edge(g.global_to_local(v_global), u_local, e_global);
Chris@16 408 }
Chris@16 409 }
Chris@16 410 }
Chris@16 411 }
Chris@16 412
Chris@16 413 return u_local;
Chris@16 414 }
Chris@16 415
Chris@16 416 // NOTE: Descriptors are local unless otherwise noted.
Chris@16 417
Chris@16 418 //===========================================================================
Chris@16 419 // Functions required by the IncidenceGraph concept
Chris@16 420
Chris@16 421 template <typename G>
Chris@16 422 std::pair<typename graph_traits<G>::out_edge_iterator,
Chris@16 423 typename graph_traits<G>::out_edge_iterator>
Chris@16 424 out_edges(typename graph_traits<G>::vertex_descriptor v, const subgraph<G>& g)
Chris@16 425 { return out_edges(v, g.m_graph); }
Chris@16 426
Chris@16 427 template <typename G>
Chris@16 428 typename graph_traits<G>::degree_size_type
Chris@16 429 out_degree(typename graph_traits<G>::vertex_descriptor v, const subgraph<G>& g)
Chris@16 430 { return out_degree(v, g.m_graph); }
Chris@16 431
Chris@16 432 template <typename G>
Chris@16 433 typename graph_traits<G>::vertex_descriptor
Chris@16 434 source(typename graph_traits<G>::edge_descriptor e, const subgraph<G>& g)
Chris@16 435 { return source(e, g.m_graph); }
Chris@16 436
Chris@16 437 template <typename G>
Chris@16 438 typename graph_traits<G>::vertex_descriptor
Chris@16 439 target(typename graph_traits<G>::edge_descriptor e, const subgraph<G>& g)
Chris@16 440 { return target(e, g.m_graph); }
Chris@16 441
Chris@16 442 //===========================================================================
Chris@16 443 // Functions required by the BidirectionalGraph concept
Chris@16 444
Chris@16 445 template <typename G>
Chris@16 446 std::pair<typename graph_traits<G>::in_edge_iterator,
Chris@16 447 typename graph_traits<G>::in_edge_iterator>
Chris@16 448 in_edges(typename graph_traits<G>::vertex_descriptor v, const subgraph<G>& g)
Chris@16 449 { return in_edges(v, g.m_graph); }
Chris@16 450
Chris@16 451 template <typename G>
Chris@16 452 typename graph_traits<G>::degree_size_type
Chris@16 453 in_degree(typename graph_traits<G>::vertex_descriptor v, const subgraph<G>& g)
Chris@16 454 { return in_degree(v, g.m_graph); }
Chris@16 455
Chris@16 456 template <typename G>
Chris@16 457 typename graph_traits<G>::degree_size_type
Chris@16 458 degree(typename graph_traits<G>::vertex_descriptor v, const subgraph<G>& g)
Chris@16 459 { return degree(v, g.m_graph); }
Chris@16 460
Chris@16 461 //===========================================================================
Chris@16 462 // Functions required by the AdjacencyGraph concept
Chris@16 463
Chris@16 464 template <typename G>
Chris@16 465 std::pair<typename subgraph<G>::adjacency_iterator,
Chris@16 466 typename subgraph<G>::adjacency_iterator>
Chris@16 467 adjacent_vertices(typename subgraph<G>::vertex_descriptor v, const subgraph<G>& g)
Chris@16 468 { return adjacent_vertices(v, g.m_graph); }
Chris@16 469
Chris@16 470 //===========================================================================
Chris@16 471 // Functions required by the VertexListGraph concept
Chris@16 472
Chris@16 473 template <typename G>
Chris@16 474 std::pair<typename subgraph<G>::vertex_iterator,
Chris@16 475 typename subgraph<G>::vertex_iterator>
Chris@16 476 vertices(const subgraph<G>& g)
Chris@16 477 { return vertices(g.m_graph); }
Chris@16 478
Chris@16 479 template <typename G>
Chris@16 480 typename subgraph<G>::vertices_size_type
Chris@16 481 num_vertices(const subgraph<G>& g)
Chris@16 482 { return num_vertices(g.m_graph); }
Chris@16 483
Chris@16 484 //===========================================================================
Chris@16 485 // Functions required by the EdgeListGraph concept
Chris@16 486
Chris@16 487 template <typename G>
Chris@16 488 std::pair<typename subgraph<G>::edge_iterator,
Chris@16 489 typename subgraph<G>::edge_iterator>
Chris@16 490 edges(const subgraph<G>& g)
Chris@16 491 { return edges(g.m_graph); }
Chris@16 492
Chris@16 493 template <typename G>
Chris@16 494 typename subgraph<G>::edges_size_type
Chris@16 495 num_edges(const subgraph<G>& g)
Chris@16 496 { return num_edges(g.m_graph); }
Chris@16 497
Chris@16 498 //===========================================================================
Chris@16 499 // Functions required by the AdjacencyMatrix concept
Chris@16 500
Chris@16 501 template <typename G>
Chris@16 502 std::pair<typename subgraph<G>::edge_descriptor, bool>
Chris@16 503 edge(typename subgraph<G>::vertex_descriptor u,
Chris@16 504 typename subgraph<G>::vertex_descriptor v,
Chris@16 505 const subgraph<G>& g)
Chris@16 506 { return edge(u, v, g.m_graph); }
Chris@16 507
Chris@16 508 //===========================================================================
Chris@16 509 // Functions required by the MutableGraph concept
Chris@16 510
Chris@16 511 namespace detail {
Chris@16 512
Chris@16 513 template <typename Vertex, typename Edge, typename Graph>
Chris@16 514 void add_edge_recur_down(Vertex u_global, Vertex v_global, Edge e_global,
Chris@16 515 subgraph<Graph>& g);
Chris@16 516
Chris@16 517 template <typename Vertex, typename Edge, typename Children, typename G>
Chris@16 518 void children_add_edge(Vertex u_global, Vertex v_global, Edge e_global,
Chris@16 519 Children& c, subgraph<G>* orig)
Chris@16 520 {
Chris@16 521 for(typename Children::iterator i = c.begin(); i != c.end(); ++i) {
Chris@16 522 if ((*i)->find_vertex(u_global).second &&
Chris@16 523 (*i)->find_vertex(v_global).second)
Chris@16 524 {
Chris@16 525 add_edge_recur_down(u_global, v_global, e_global, **i, orig);
Chris@16 526 }
Chris@16 527 }
Chris@16 528 }
Chris@16 529
Chris@16 530 template <typename Vertex, typename Edge, typename Graph>
Chris@16 531 void add_edge_recur_down(Vertex u_global, Vertex v_global, Edge e_global,
Chris@16 532 subgraph<Graph>& g, subgraph<Graph>* orig)
Chris@16 533 {
Chris@16 534 if(&g != orig ) {
Chris@16 535 // add local edge only if u_global and v_global are in subgraph g
Chris@16 536 Vertex u_local, v_local;
Chris@16 537 bool u_in_subgraph, v_in_subgraph;
Chris@16 538 boost::tie(u_local, u_in_subgraph) = g.find_vertex(u_global);
Chris@16 539 boost::tie(v_local, v_in_subgraph) = g.find_vertex(v_global);
Chris@16 540 if(u_in_subgraph && v_in_subgraph) {
Chris@16 541 g.local_add_edge(u_local, v_local, e_global);
Chris@16 542 }
Chris@16 543 }
Chris@16 544 children_add_edge(u_global, v_global, e_global, g.m_children, orig);
Chris@16 545 }
Chris@16 546
Chris@16 547 template <typename Vertex, typename Graph>
Chris@16 548 std::pair<typename subgraph<Graph>::edge_descriptor, bool>
Chris@16 549 add_edge_recur_up(Vertex u_global, Vertex v_global,
Chris@16 550 const typename Graph::edge_property_type& ep,
Chris@16 551 subgraph<Graph>& g, subgraph<Graph>* orig)
Chris@16 552 {
Chris@16 553 if(g.is_root()) {
Chris@16 554 typename subgraph<Graph>::edge_descriptor e_global;
Chris@16 555 bool inserted;
Chris@16 556 boost::tie(e_global, inserted) = add_edge(u_global, v_global, ep, g.m_graph);
Chris@16 557 put(edge_index, g.m_graph, e_global, g.m_edge_counter++);
Chris@16 558 g.m_global_edge.push_back(e_global);
Chris@16 559 children_add_edge(u_global, v_global, e_global, g.m_children, orig);
Chris@16 560 return std::make_pair(e_global, inserted);
Chris@16 561 } else {
Chris@16 562 return add_edge_recur_up(u_global, v_global, ep, *g.m_parent, orig);
Chris@16 563 }
Chris@16 564 }
Chris@16 565
Chris@16 566 } // namespace detail
Chris@16 567
Chris@16 568 // Add an edge to the subgraph g, specified by the local vertex descriptors u
Chris@16 569 // and v. In addition, the edge will be added to any (all) other subgraphs that
Chris@16 570 // contain vertex descriptors u and v.
Chris@16 571
Chris@16 572 template <typename G>
Chris@16 573 std::pair<typename subgraph<G>::edge_descriptor, bool>
Chris@16 574 add_edge(typename subgraph<G>::vertex_descriptor u,
Chris@16 575 typename subgraph<G>::vertex_descriptor v,
Chris@16 576 const typename G::edge_property_type& ep,
Chris@16 577 subgraph<G>& g)
Chris@16 578 {
Chris@16 579 if (g.is_root()) {
Chris@16 580 // u and v are really global
Chris@16 581 return detail::add_edge_recur_up(u, v, ep, g, &g);
Chris@16 582 } else {
Chris@16 583 typename subgraph<G>::edge_descriptor e_local, e_global;
Chris@16 584 bool inserted;
Chris@16 585 boost::tie(e_global, inserted) =
Chris@16 586 detail::add_edge_recur_up(g.local_to_global(u),
Chris@16 587 g.local_to_global(v),
Chris@16 588 ep, g, &g);
Chris@16 589 e_local = g.local_add_edge(u, v, e_global);
Chris@16 590 return std::make_pair(e_local, inserted);
Chris@16 591 }
Chris@16 592 }
Chris@16 593
Chris@16 594 template <typename G>
Chris@16 595 std::pair<typename subgraph<G>::edge_descriptor, bool>
Chris@16 596 add_edge(typename subgraph<G>::vertex_descriptor u,
Chris@16 597 typename subgraph<G>::vertex_descriptor v,
Chris@16 598 subgraph<G>& g)
Chris@16 599 { return add_edge(u, v, typename G::edge_property_type(), g); }
Chris@16 600
Chris@16 601 namespace detail {
Chris@16 602 //-------------------------------------------------------------------------
Chris@16 603 // implementation of remove_edge(u,v,g)
Chris@16 604 template <typename Vertex, typename Graph>
Chris@16 605 void remove_edge_recur_down(Vertex u_global, Vertex v_global,
Chris@16 606 subgraph<Graph>& g);
Chris@16 607
Chris@16 608 template <typename Vertex, typename Children>
Chris@16 609 void children_remove_edge(Vertex u_global, Vertex v_global,
Chris@16 610 Children& c)
Chris@16 611 {
Chris@16 612 for(typename Children::iterator i = c.begin(); i != c.end(); ++i) {
Chris@16 613 if((*i)->find_vertex(u_global).second &&
Chris@16 614 (*i)->find_vertex(v_global).second)
Chris@16 615 {
Chris@16 616 remove_edge_recur_down(u_global, v_global, **i);
Chris@16 617 }
Chris@16 618 }
Chris@16 619 }
Chris@16 620
Chris@16 621 template <typename Vertex, typename Graph>
Chris@16 622 void remove_edge_recur_down(Vertex u_global, Vertex v_global,
Chris@16 623 subgraph<Graph>& g)
Chris@16 624 {
Chris@16 625 Vertex u_local, v_local;
Chris@16 626 u_local = g.m_local_vertex[u_global];
Chris@16 627 v_local = g.m_local_vertex[v_global];
Chris@16 628 remove_edge(u_local, v_local, g.m_graph);
Chris@16 629 children_remove_edge(u_global, v_global, g.m_children);
Chris@16 630 }
Chris@16 631
Chris@16 632 template <typename Vertex, typename Graph>
Chris@16 633 void remove_edge_recur_up(Vertex u_global, Vertex v_global,
Chris@16 634 subgraph<Graph>& g)
Chris@16 635 {
Chris@16 636 if(g.is_root()) {
Chris@16 637 remove_edge(u_global, v_global, g.m_graph);
Chris@16 638 children_remove_edge(u_global, v_global, g.m_children);
Chris@16 639 } else {
Chris@16 640 remove_edge_recur_up(u_global, v_global, *g.m_parent);
Chris@16 641 }
Chris@16 642 }
Chris@16 643
Chris@16 644 //-------------------------------------------------------------------------
Chris@16 645 // implementation of remove_edge(e,g)
Chris@16 646
Chris@16 647 template <typename G, typename Edge, typename Children>
Chris@16 648 void children_remove_edge(Edge e_global, Children& c)
Chris@16 649 {
Chris@16 650 for(typename Children::iterator i = c.begin(); i != c.end(); ++i) {
Chris@16 651 std::pair<typename subgraph<G>::edge_descriptor, bool> found =
Chris@16 652 (*i)->find_edge(e_global);
Chris@16 653 if (!found.second) {
Chris@16 654 continue;
Chris@16 655 }
Chris@16 656 children_remove_edge<G>(e_global, (*i)->m_children);
Chris@16 657 remove_edge(found.first, (*i)->m_graph);
Chris@16 658 }
Chris@16 659 }
Chris@16 660
Chris@16 661 } // namespace detail
Chris@16 662
Chris@16 663 template <typename G>
Chris@16 664 void
Chris@16 665 remove_edge(typename subgraph<G>::vertex_descriptor u,
Chris@16 666 typename subgraph<G>::vertex_descriptor v,
Chris@16 667 subgraph<G>& g)
Chris@16 668 {
Chris@16 669 if(g.is_root()) {
Chris@16 670 detail::remove_edge_recur_up(u, v, g);
Chris@16 671 } else {
Chris@16 672 detail::remove_edge_recur_up(g.local_to_global(u),
Chris@16 673 g.local_to_global(v), g);
Chris@16 674 }
Chris@16 675 }
Chris@16 676
Chris@16 677 template <typename G>
Chris@16 678 void
Chris@16 679 remove_edge(typename subgraph<G>::edge_descriptor e, subgraph<G>& g)
Chris@16 680 {
Chris@16 681 typename subgraph<G>::edge_descriptor e_global = g.local_to_global(e);
Chris@16 682 #ifndef NDEBUG
Chris@16 683 std::pair<typename subgraph<G>::edge_descriptor, bool> fe = g.find_edge(e_global);
Chris@16 684 BOOST_ASSERT(fe.second && fe.first == e);
Chris@16 685 #endif //NDEBUG
Chris@16 686 subgraph<G> &root = g.root(); // chase to root
Chris@16 687 detail::children_remove_edge<G>(e_global, root.m_children);
Chris@16 688 remove_edge(e_global, root.m_graph); // kick edge from root
Chris@16 689 }
Chris@16 690
Chris@16 691 // This is slow, but there may not be a good way to do it safely otherwise
Chris@16 692 template <typename Predicate, typename G>
Chris@16 693 void
Chris@16 694 remove_edge_if(Predicate p, subgraph<G>& g) {
Chris@16 695 while (true) {
Chris@16 696 bool any_removed = false;
Chris@16 697 typedef typename subgraph<G>::edge_iterator ei_type;
Chris@16 698 for (std::pair<ei_type, ei_type> ep = edges(g);
Chris@16 699 ep.first != ep.second; ++ep.first) {
Chris@16 700 if (p(*ep.first)) {
Chris@16 701 any_removed = true;
Chris@16 702 remove_edge(*ep.first, g);
Chris@16 703 break; /* Since iterators may be invalidated */
Chris@16 704 }
Chris@16 705 }
Chris@16 706 if (!any_removed) break;
Chris@16 707 }
Chris@16 708 }
Chris@16 709
Chris@16 710 template <typename G>
Chris@16 711 void
Chris@16 712 clear_vertex(typename subgraph<G>::vertex_descriptor v, subgraph<G>& g) {
Chris@16 713 while (true) {
Chris@16 714 typedef typename subgraph<G>::out_edge_iterator oei_type;
Chris@16 715 std::pair<oei_type, oei_type> p = out_edges(v, g);
Chris@16 716 if (p.first == p.second) break;
Chris@16 717 remove_edge(*p.first, g);
Chris@16 718 }
Chris@16 719 }
Chris@16 720
Chris@16 721 namespace detail {
Chris@16 722 template <typename G>
Chris@16 723 typename subgraph<G>::vertex_descriptor
Chris@16 724 add_vertex_recur_up(subgraph<G>& g)
Chris@16 725 {
Chris@16 726 typename subgraph<G>::vertex_descriptor u_local, u_global;
Chris@16 727 if (g.is_root()) {
Chris@16 728 u_global = add_vertex(g.m_graph);
Chris@16 729 g.m_global_vertex.push_back(u_global);
Chris@16 730 } else {
Chris@16 731 u_global = add_vertex_recur_up(*g.m_parent);
Chris@16 732 u_local = add_vertex(g.m_graph);
Chris@16 733 g.m_global_vertex.push_back(u_global);
Chris@16 734 g.m_local_vertex[u_global] = u_local;
Chris@16 735 }
Chris@16 736 return u_global;
Chris@16 737 }
Chris@16 738 } // namespace detail
Chris@16 739
Chris@16 740 template <typename G>
Chris@16 741 typename subgraph<G>::vertex_descriptor
Chris@16 742 add_vertex(subgraph<G>& g)
Chris@16 743 {
Chris@16 744 typename subgraph<G>::vertex_descriptor u_local, u_global;
Chris@16 745 if(g.is_root()) {
Chris@16 746 u_global = add_vertex(g.m_graph);
Chris@16 747 g.m_global_vertex.push_back(u_global);
Chris@16 748 u_local = u_global;
Chris@16 749 } else {
Chris@16 750 u_global = detail::add_vertex_recur_up(g.parent());
Chris@16 751 u_local = add_vertex(g.m_graph);
Chris@16 752 g.m_global_vertex.push_back(u_global);
Chris@16 753 g.m_local_vertex[u_global] = u_local;
Chris@16 754 }
Chris@16 755 return u_local;
Chris@16 756 }
Chris@16 757
Chris@16 758
Chris@16 759 #if 0
Chris@16 760 // TODO: Under Construction
Chris@16 761 template <typename G>
Chris@16 762 void remove_vertex(typename subgraph<G>::vertex_descriptor u, subgraph<G>& g)
Chris@16 763 { BOOST_ASSERT(false); }
Chris@16 764 #endif
Chris@16 765
Chris@16 766 //===========================================================================
Chris@16 767 // Functions required by the PropertyGraph concept
Chris@16 768
Chris@16 769 /**
Chris@16 770 * The global property map returns the global properties associated with local
Chris@16 771 * descriptors.
Chris@16 772 */
Chris@16 773 template <typename GraphPtr, typename PropertyMap, typename Tag>
Chris@16 774 class subgraph_global_property_map
Chris@16 775 : public put_get_helper<
Chris@16 776 typename property_traits<PropertyMap>::reference,
Chris@16 777 subgraph_global_property_map<GraphPtr, PropertyMap, Tag>
Chris@16 778 >
Chris@16 779 {
Chris@16 780 typedef property_traits<PropertyMap> Traits;
Chris@16 781 public:
Chris@16 782 typedef typename mpl::if_<is_const<typename remove_pointer<GraphPtr>::type>,
Chris@16 783 readable_property_map_tag,
Chris@16 784 typename Traits::category>::type
Chris@16 785 category;
Chris@16 786 typedef typename Traits::value_type value_type;
Chris@16 787 typedef typename Traits::key_type key_type;
Chris@16 788 typedef typename Traits::reference reference;
Chris@16 789
Chris@16 790 subgraph_global_property_map()
Chris@16 791 { }
Chris@16 792
Chris@16 793 subgraph_global_property_map(GraphPtr g, Tag tag)
Chris@16 794 : m_g(g), m_tag(tag)
Chris@16 795 { }
Chris@16 796
Chris@16 797 reference operator[](key_type e) const {
Chris@16 798 PropertyMap pmap = get(m_tag, m_g->root().m_graph);
Chris@16 799 return m_g->is_root()
Chris@16 800 ? pmap[e]
Chris@16 801 : pmap[m_g->local_to_global(e)];
Chris@16 802 }
Chris@16 803
Chris@16 804 GraphPtr m_g;
Chris@16 805 Tag m_tag;
Chris@16 806 };
Chris@16 807
Chris@16 808 /**
Chris@16 809 * The local property map returns the local property associated with the local
Chris@16 810 * descriptors.
Chris@16 811 */
Chris@16 812 template <typename GraphPtr, typename PropertyMap, typename Tag>
Chris@16 813 class subgraph_local_property_map
Chris@16 814 : public put_get_helper<
Chris@16 815 typename property_traits<PropertyMap>::reference,
Chris@16 816 subgraph_local_property_map<GraphPtr, PropertyMap, Tag>
Chris@16 817 >
Chris@16 818 {
Chris@16 819 typedef property_traits<PropertyMap> Traits;
Chris@16 820 public:
Chris@16 821 typedef typename mpl::if_<is_const<typename remove_pointer<GraphPtr>::type>,
Chris@16 822 readable_property_map_tag,
Chris@16 823 typename Traits::category>::type
Chris@16 824 category;
Chris@16 825 typedef typename Traits::value_type value_type;
Chris@16 826 typedef typename Traits::key_type key_type;
Chris@16 827 typedef typename Traits::reference reference;
Chris@16 828
Chris@16 829 typedef Tag tag;
Chris@16 830 typedef PropertyMap pmap;
Chris@16 831
Chris@16 832 subgraph_local_property_map()
Chris@16 833 { }
Chris@16 834
Chris@16 835 subgraph_local_property_map(GraphPtr g, Tag tag)
Chris@16 836 : m_g(g), m_tag(tag)
Chris@16 837 { }
Chris@16 838
Chris@16 839 reference operator[](key_type e) const {
Chris@16 840 // Get property map on the underlying graph.
Chris@16 841 PropertyMap pmap = get(m_tag, m_g->m_graph);
Chris@16 842 return pmap[e];
Chris@16 843 }
Chris@16 844
Chris@16 845 GraphPtr m_g;
Chris@16 846 Tag m_tag;
Chris@16 847 };
Chris@16 848
Chris@16 849 namespace detail {
Chris@16 850 // Extract the actual tags from local or global property maps so we don't
Chris@16 851 // try to find non-properties.
Chris@16 852 template <typename P> struct extract_lg_tag { typedef P type; };
Chris@16 853 template <typename P> struct extract_lg_tag< local_property<P> > {
Chris@16 854 typedef P type;
Chris@16 855 };
Chris@16 856 template <typename P> struct extract_lg_tag< global_property<P> > {
Chris@16 857 typedef P type;
Chris@16 858 };
Chris@16 859
Chris@16 860 // NOTE: Mysterious Property template parameter unused in both metafunction
Chris@16 861 // classes.
Chris@16 862 struct subgraph_global_pmap {
Chris@16 863 template <class Tag, class SubGraph, class Property>
Chris@16 864 struct bind_ {
Chris@16 865 typedef typename SubGraph::graph_type Graph;
Chris@16 866 typedef SubGraph* SubGraphPtr;
Chris@16 867 typedef const SubGraph* const_SubGraphPtr;
Chris@16 868 typedef typename extract_lg_tag<Tag>::type TagType;
Chris@16 869 typedef typename property_map<Graph, TagType>::type PMap;
Chris@16 870 typedef typename property_map<Graph, TagType>::const_type const_PMap;
Chris@16 871 public:
Chris@16 872 typedef subgraph_global_property_map<SubGraphPtr, PMap, TagType> type;
Chris@16 873 typedef subgraph_global_property_map<const_SubGraphPtr, const_PMap, TagType>
Chris@16 874 const_type;
Chris@16 875 };
Chris@16 876 };
Chris@16 877
Chris@16 878 struct subgraph_local_pmap {
Chris@16 879 template <class Tag, class SubGraph, class Property>
Chris@16 880 struct bind_ {
Chris@16 881 typedef typename SubGraph::graph_type Graph;
Chris@16 882 typedef SubGraph* SubGraphPtr;
Chris@16 883 typedef const SubGraph* const_SubGraphPtr;
Chris@16 884 typedef typename extract_lg_tag<Tag>::type TagType;
Chris@16 885 typedef typename property_map<Graph, TagType>::type PMap;
Chris@16 886 typedef typename property_map<Graph, TagType>::const_type const_PMap;
Chris@16 887 public:
Chris@16 888 typedef subgraph_local_property_map<SubGraphPtr, PMap, TagType> type;
Chris@16 889 typedef subgraph_local_property_map<const_SubGraphPtr, const_PMap, TagType>
Chris@16 890 const_type;
Chris@16 891 };
Chris@16 892 };
Chris@16 893
Chris@16 894 // These metafunctions select the corresponding metafunctions above, and
Chris@16 895 // are used by the choose_pmap metafunction below to specialize the choice
Chris@16 896 // of local/global property map. By default, we defer to the global
Chris@16 897 // property.
Chris@16 898 template <class Tag>
Chris@16 899 struct subgraph_choose_pmap_helper {
Chris@16 900 typedef subgraph_global_pmap type;
Chris@16 901 };
Chris@16 902 template <class Tag>
Chris@16 903 struct subgraph_choose_pmap_helper< local_property<Tag> > {
Chris@16 904 typedef subgraph_local_pmap type;
Chris@16 905 };
Chris@16 906 template <class Tag>
Chris@16 907 struct subgraph_choose_pmap_helper< global_property<Tag> > {
Chris@16 908 typedef subgraph_global_pmap type;
Chris@16 909 };
Chris@16 910
Chris@16 911 // As above, unless we're requesting vertex_index_t. Then it's always a
Chris@16 912 // local property map. This enables the correct translation of descriptors
Chris@16 913 // between local and global layers.
Chris@16 914 template <>
Chris@16 915 struct subgraph_choose_pmap_helper<vertex_index_t> {
Chris@16 916 typedef subgraph_local_pmap type;
Chris@16 917 };
Chris@16 918 template <>
Chris@16 919 struct subgraph_choose_pmap_helper< local_property<vertex_index_t> > {
Chris@16 920 typedef subgraph_local_pmap type;
Chris@16 921 };
Chris@16 922 template <>
Chris@16 923 struct subgraph_choose_pmap_helper< global_property<vertex_index_t> > {
Chris@16 924 typedef subgraph_local_pmap type;
Chris@16 925 };
Chris@16 926
Chris@16 927 // Determine the kind of property. If SameType<Tag, vertex_index_t>, then
Chris@16 928 // the property lookup is always local. Otherwise, the lookup is global.
Chris@16 929 // NOTE: Property parameter is basically unused.
Chris@16 930 template <class Tag, class Graph, class Property>
Chris@16 931 struct subgraph_choose_pmap {
Chris@16 932 typedef typename subgraph_choose_pmap_helper<Tag>::type Helper;
Chris@16 933 typedef typename Helper::template bind_<Tag, Graph, Property> Bind;
Chris@16 934 typedef typename Bind::type type;
Chris@16 935 typedef typename Bind::const_type const_type;
Chris@16 936 };
Chris@16 937
Chris@16 938 // Used by the vertex/edge property selectors to determine the kind(s) of
Chris@16 939 // property maps used by the property_map type generator.
Chris@16 940 struct subgraph_property_generator {
Chris@16 941 template <class SubGraph, class Property, class Tag>
Chris@16 942 struct bind_ {
Chris@16 943 typedef subgraph_choose_pmap<Tag, SubGraph, Property> Choice;
Chris@16 944 typedef typename Choice::type type;
Chris@16 945 typedef typename Choice::const_type const_type;
Chris@16 946 };
Chris@16 947 };
Chris@16 948
Chris@16 949 } // namespace detail
Chris@16 950
Chris@16 951 template <>
Chris@16 952 struct vertex_property_selector<subgraph_tag> {
Chris@16 953 typedef detail::subgraph_property_generator type;
Chris@16 954 };
Chris@16 955
Chris@16 956 template <>
Chris@16 957 struct edge_property_selector<subgraph_tag> {
Chris@16 958 typedef detail::subgraph_property_generator type;
Chris@16 959 };
Chris@16 960
Chris@16 961 // ==================================================
Chris@16 962 // get(p, g), get(p, g, k), and put(p, g, k, v)
Chris@16 963 // ==================================================
Chris@16 964 template <typename G, typename Property>
Chris@16 965 typename property_map<subgraph<G>, Property>::type
Chris@16 966 get(Property p, subgraph<G>& g) {
Chris@16 967 typedef typename property_map< subgraph<G>, Property>::type PMap;
Chris@16 968 return PMap(&g, p);
Chris@16 969 }
Chris@16 970
Chris@16 971 template <typename G, typename Property>
Chris@16 972 typename property_map<subgraph<G>, Property>::const_type
Chris@16 973 get(Property p, const subgraph<G>& g) {
Chris@16 974 typedef typename property_map< subgraph<G>, Property>::const_type PMap;
Chris@16 975 return PMap(&g, p);
Chris@16 976 }
Chris@16 977
Chris@16 978 template <typename G, typename Property, typename Key>
Chris@16 979 typename property_traits<
Chris@16 980 typename property_map<subgraph<G>, Property>::const_type
Chris@16 981 >::value_type
Chris@16 982 get(Property p, const subgraph<G>& g, const Key& k) {
Chris@16 983 typedef typename property_map< subgraph<G>, Property>::const_type PMap;
Chris@16 984 PMap pmap(&g, p);
Chris@16 985 return pmap[k];
Chris@16 986 }
Chris@16 987
Chris@16 988 template <typename G, typename Property, typename Key, typename Value>
Chris@16 989 void put(Property p, subgraph<G>& g, const Key& k, const Value& val) {
Chris@16 990 typedef typename property_map< subgraph<G>, Property>::type PMap;
Chris@16 991 PMap pmap(&g, p);
Chris@16 992 pmap[k] = val;
Chris@16 993 }
Chris@16 994
Chris@16 995 // ==================================================
Chris@16 996 // get(global(p), g)
Chris@16 997 // NOTE: get(global(p), g, k) and put(global(p), g, k, v) not supported
Chris@16 998 // ==================================================
Chris@16 999 template <typename G, typename Property>
Chris@16 1000 typename property_map<subgraph<G>, global_property<Property> >::type
Chris@16 1001 get(global_property<Property> p, subgraph<G>& g) {
Chris@16 1002 typedef typename property_map<
Chris@16 1003 subgraph<G>, global_property<Property>
Chris@16 1004 >::type Map;
Chris@16 1005 return Map(&g, p.value);
Chris@16 1006 }
Chris@16 1007
Chris@16 1008 template <typename G, typename Property>
Chris@16 1009 typename property_map<subgraph<G>, global_property<Property> >::const_type
Chris@16 1010 get(global_property<Property> p, const subgraph<G>& g) {
Chris@16 1011 typedef typename property_map<
Chris@16 1012 subgraph<G>, global_property<Property>
Chris@16 1013 >::const_type Map;
Chris@16 1014 return Map(&g, p.value);
Chris@16 1015 }
Chris@16 1016
Chris@16 1017 // ==================================================
Chris@16 1018 // get(local(p), g)
Chris@16 1019 // NOTE: get(local(p), g, k) and put(local(p), g, k, v) not supported
Chris@16 1020 // ==================================================
Chris@16 1021 template <typename G, typename Property>
Chris@16 1022 typename property_map<subgraph<G>, local_property<Property> >::type
Chris@16 1023 get(local_property<Property> p, subgraph<G>& g) {
Chris@16 1024 typedef typename property_map<
Chris@16 1025 subgraph<G>, local_property<Property>
Chris@16 1026 >::type Map;
Chris@16 1027 return Map(&g, p.value);
Chris@16 1028 }
Chris@16 1029
Chris@16 1030 template <typename G, typename Property>
Chris@16 1031 typename property_map<subgraph<G>, local_property<Property> >::const_type
Chris@16 1032 get(local_property<Property> p, const subgraph<G>& g) {
Chris@16 1033 typedef typename property_map<
Chris@16 1034 subgraph<G>, local_property<Property>
Chris@16 1035 >::const_type Map;
Chris@16 1036 return Map(&g, p.value);
Chris@16 1037 }
Chris@16 1038
Chris@16 1039 template <typename G, typename Tag>
Chris@16 1040 inline typename graph_property<G, Tag>::type&
Chris@16 1041 get_property(subgraph<G>& g, Tag tag) {
Chris@16 1042 return get_property(g.m_graph, tag);
Chris@16 1043 }
Chris@16 1044
Chris@16 1045 template <typename G, typename Tag>
Chris@16 1046 inline const typename graph_property<G, Tag>::type&
Chris@16 1047 get_property(const subgraph<G>& g, Tag tag) {
Chris@16 1048 return get_property(g.m_graph, tag);
Chris@16 1049 }
Chris@16 1050
Chris@16 1051 //===========================================================================
Chris@16 1052 // Miscellaneous Functions
Chris@16 1053
Chris@16 1054 template <typename G>
Chris@16 1055 typename subgraph<G>::vertex_descriptor
Chris@16 1056 vertex(typename subgraph<G>::vertices_size_type n, const subgraph<G>& g)
Chris@16 1057 { return vertex(n, g.m_graph); }
Chris@16 1058
Chris@16 1059 //===========================================================================
Chris@16 1060 // Mutability Traits
Chris@16 1061 // Just pull the mutability traits form the underlying graph. Note that this
Chris@16 1062 // will probably fail (badly) for labeled graphs.
Chris@16 1063 template <typename G>
Chris@16 1064 struct graph_mutability_traits< subgraph<G> > {
Chris@16 1065 typedef typename graph_mutability_traits<G>::category category;
Chris@16 1066 };
Chris@16 1067
Chris@16 1068 } // namespace boost
Chris@16 1069
Chris@16 1070 #endif // BOOST_SUBGRAPH_HPP