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

http://hadesmem.googlecode.com/ · C++ Header · 1238 lines · 916 code · 169 blank · 153 comment · 64 complexity · 7f7c9f37b59c6817ce9758f897fcc53a MD5 · raw file

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