Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
1 //=======================================================================
2 // Copyright 2001 University of Notre Dame.
3 // Authors: Jeremy G. Siek and Lie-Quan Lee
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 //=======================================================================
10 #ifndef BOOST_SUBGRAPH_HPP
11 #define BOOST_SUBGRAPH_HPP
15 #include <boost/config.hpp>
20 #include <boost/graph/graph_traits.hpp>
21 #include <boost/graph/properties.hpp>
22 #include <boost/iterator/indirect_iterator.hpp>
24 #include <boost/static_assert.hpp>
25 #include <boost/type_traits/is_same.hpp>
29 struct subgraph_tag { };
31 // Invariants of an induced subgraph:
32 // - If vertex u is in subgraph g, then u must be in g.parent().
33 // - If edge e is in subgraph g, then e must be in g.parent().
34 // - If edge e=(u,v) is in the root graph, then edge e
35 // is also in any subgraph that contains both vertex u and v.
37 // The Graph template parameter must have a vertex_index
38 // and edge_index internal property. It is assumed that
39 // the vertex indices are assigned automatically by the
40 // graph during a call to add_vertex(). It is not
41 // assumed that the edge vertices are assigned automatically,
42 // they are explicitly assigned here.
44 template <typename Graph>
46 typedef graph_traits<Graph> Traits;
47 typedef std::list<subgraph<Graph>*> ChildrenList;
50 typedef typename Traits::vertex_descriptor vertex_descriptor;
51 typedef typename Traits::edge_descriptor edge_descriptor;
52 typedef typename Traits::directed_category directed_category;
53 typedef typename Traits::edge_parallel_category edge_parallel_category;
54 typedef typename Traits::traversal_category traversal_category;
56 static vertex_descriptor null_vertex()
58 return Traits::null_vertex();
62 // IncidenceGraph requirements
63 typedef typename Traits::out_edge_iterator out_edge_iterator;
64 typedef typename Traits::degree_size_type degree_size_type;
66 // AdjacencyGraph requirements
67 typedef typename Traits::adjacency_iterator adjacency_iterator;
69 // VertexListGraph requirements
70 typedef typename Traits::vertex_iterator vertex_iterator;
71 typedef typename Traits::vertices_size_type vertices_size_type;
73 // EdgeListGraph requirements
74 typedef typename Traits::edge_iterator edge_iterator;
75 typedef typename Traits::edges_size_type edges_size_type;
77 typedef typename Traits::in_edge_iterator in_edge_iterator;
79 typedef typename Graph::edge_property_type edge_property_type;
80 typedef typename Graph::vertex_property_type vertex_property_type;
81 typedef subgraph_tag graph_tag;
82 typedef Graph graph_type;
83 typedef typename Graph::graph_property_type graph_property_type;
87 // Create the main graph, the root of the subgraph tree
89 : m_parent(0), m_edge_counter(0)
91 subgraph(const graph_property_type& p)
92 : m_graph(p), m_parent(0), m_edge_counter(0)
94 subgraph(vertices_size_type n,
95 const graph_property_type& p = graph_property_type())
96 : m_graph(n, p), m_parent(0), m_edge_counter(0), m_global_vertex(n)
98 typename Graph::vertex_iterator v, v_end;
99 vertices_size_type i = 0;
100 for (tie(v, v_end) = vertices(m_graph); v != v_end; ++v)
101 m_global_vertex[i++] = *v;
105 subgraph(const subgraph& x)
106 : m_graph(x.m_graph), m_parent(x.m_parent),
107 m_edge_counter(x.m_edge_counter),
108 m_global_vertex(x.m_global_vertex),
109 m_global_edge(x.m_global_edge)
112 for (typename ChildrenList::const_iterator i = x.m_children.begin();
113 i != x.m_children.end(); ++i)
114 m_children.push_back(new subgraph<Graph>( **i ));
119 for (typename ChildrenList::iterator i = m_children.begin();
120 i != m_children.end(); ++i)
126 subgraph<Graph>& create_subgraph() {
127 m_children.push_back(new subgraph<Graph>());
128 m_children.back()->m_parent = this;
129 return *m_children.back();
132 // Create a subgraph with the specified vertex set.
133 template <typename VertexIterator>
134 subgraph<Graph>& create_subgraph(VertexIterator first,
137 m_children.push_back(new subgraph<Graph>());
138 m_children.back()->m_parent = this;
139 for (; first != last; ++first)
140 add_vertex(*first, *m_children.back());
141 return *m_children.back();
144 // local <-> global descriptor conversion functions
145 vertex_descriptor local_to_global(vertex_descriptor u_local) const
147 return m_global_vertex[u_local];
149 vertex_descriptor global_to_local(vertex_descriptor u_global) const
151 vertex_descriptor u_local; bool in_subgraph;
152 tie(u_local, in_subgraph) = this->find_vertex(u_global);
153 assert(in_subgraph == true);
156 edge_descriptor local_to_global(edge_descriptor e_local) const
158 return m_global_edge[get(get(edge_index, m_graph), e_local)];
160 edge_descriptor global_to_local(edge_descriptor e_global) const
163 (*m_local_edge.find(get(get(edge_index, root().m_graph), e_global))).second;
166 // Is vertex u (of the root graph) contained in this subgraph?
167 // If so, return the matching local vertex.
168 std::pair<vertex_descriptor, bool>
169 find_vertex(vertex_descriptor u_global) const
171 typename std::map<vertex_descriptor, vertex_descriptor>::const_iterator
172 i = m_local_vertex.find(u_global);
173 bool valid = i != m_local_vertex.end();
174 return std::make_pair((valid ? (*i).second : null_vertex()), valid);
177 // Return the parent graph.
178 subgraph& parent() { return *m_parent; }
179 const subgraph& parent() const { return *m_parent; }
181 bool is_root() const { return m_parent == 0; }
183 // Return the root graph of the subgraph tree.
188 return m_parent->root();
190 const subgraph& root() const {
194 return m_parent->root();
197 // Return the children subgraphs of this graph/subgraph.
198 // Use a list of pointers because the VC++ std::list doesn't like
199 // storing incomplete type.
200 typedef indirect_iterator<
201 typename ChildrenList::const_iterator
203 , std::bidirectional_iterator_tag
207 typedef indirect_iterator<
208 typename ChildrenList::const_iterator
209 , subgraph<Graph> const
210 , std::bidirectional_iterator_tag
212 const_children_iterator;
214 std::pair<const_children_iterator, const_children_iterator>
217 return std::make_pair(const_children_iterator(m_children.begin()),
218 const_children_iterator(m_children.end()));
221 std::pair<children_iterator, children_iterator>
224 return std::make_pair(children_iterator(m_children.begin()),
225 children_iterator(m_children.end()));
228 std::size_t num_children() const { return m_children.size(); }
230 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
231 // Bundled properties support
232 template<typename Descriptor>
233 typename graph::detail::bundled_result<Graph, Descriptor>::type&
234 operator[](Descriptor x)
236 if (m_parent == 0) return m_graph[x];
237 else return root().m_graph[local_to_global(x)];
240 template<typename Descriptor>
241 typename graph::detail::bundled_result<Graph, Descriptor>::type const&
242 operator[](Descriptor x) const
244 if (m_parent == 0) return m_graph[x];
245 else return root().m_graph[local_to_global(x)];
247 #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
250 typedef typename property_map<Graph, edge_index_t>::type EdgeIndexMap;
251 typedef typename property_traits<EdgeIndexMap>::value_type edge_index_type;
252 BOOST_STATIC_ASSERT((!is_same<edge_index_type,
253 boost::detail::error_property_not_found>::value));
256 subgraph<Graph>* m_parent;
257 edge_index_type m_edge_counter; // for generating unique edge indices
258 ChildrenList m_children;
259 std::vector<vertex_descriptor> m_global_vertex; // local -> global
260 std::map<vertex_descriptor, vertex_descriptor> m_local_vertex; // global -> local
261 std::vector<edge_descriptor> m_global_edge; // local -> global
262 std::map<edge_index_type, edge_descriptor> m_local_edge; // global -> local
265 local_add_edge(vertex_descriptor u_local, vertex_descriptor v_local,
266 edge_descriptor e_global)
268 edge_descriptor e_local;
270 tie(e_local, inserted) = add_edge(u_local, v_local, m_graph);
271 put(edge_index, m_graph, e_local, m_edge_counter++);
272 m_global_edge.push_back(e_global);
273 m_local_edge[get(get(edge_index, this->root()), e_global)] = e_local;
279 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
280 template<typename Graph>
281 struct vertex_bundle_type<subgraph<Graph> > : vertex_bundle_type<Graph> { };
283 template<typename Graph>
284 struct edge_bundle_type<subgraph<Graph> > : edge_bundle_type<Graph> { };
285 #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
287 //===========================================================================
288 // Functions special to the Subgraph Class
290 template <typename G>
291 typename subgraph<G>::vertex_descriptor
292 add_vertex(typename subgraph<G>::vertex_descriptor u_global,
295 assert(!g.is_root());
296 typename subgraph<G>::vertex_descriptor u_local, v_global, uu_global;
297 typename subgraph<G>::edge_descriptor e_global;
299 u_local = add_vertex(g.m_graph);
300 g.m_global_vertex.push_back(u_global);
301 g.m_local_vertex[u_global] = u_local;
303 subgraph<G>& r = g.root();
305 // remember edge global and local maps
307 typename subgraph<G>::out_edge_iterator ei, ei_end;
308 for (tie(ei, ei_end) = out_edges(u_global, r);
309 ei != ei_end; ++ei) {
311 v_global = target(e_global, r);
312 if (g.find_vertex(v_global).second == true)
313 g.local_add_edge(u_local, g.global_to_local(v_global), e_global);
316 if (is_directed(g)) { // not necessary for undirected graph
317 typename subgraph<G>::vertex_iterator vi, vi_end;
318 typename subgraph<G>::out_edge_iterator ei, ei_end;
319 for (tie(vi, vi_end) = vertices(r); vi != vi_end; ++vi) {
321 if (g.find_vertex(v_global).second)
322 for (tie(ei, ei_end) = out_edges(*vi, r); ei != ei_end; ++ei) {
324 uu_global = target(e_global, r);
325 if (uu_global == u_global && g.find_vertex(v_global).second)
326 g.local_add_edge(g.global_to_local(v_global), u_local, e_global);
334 //===========================================================================
335 // Functions required by the IncidenceGraph concept
337 template <typename G>
338 std::pair<typename graph_traits<G>::out_edge_iterator,
339 typename graph_traits<G>::out_edge_iterator>
340 out_edges(typename graph_traits<G>::vertex_descriptor u_local,
341 const subgraph<G>& g)
342 { return out_edges(u_local, g.m_graph); }
344 template <typename G>
345 typename graph_traits<G>::degree_size_type
346 out_degree(typename graph_traits<G>::vertex_descriptor u_local,
347 const subgraph<G>& g)
348 { return out_degree(u_local, g.m_graph); }
350 template <typename G>
351 typename graph_traits<G>::vertex_descriptor
352 source(typename graph_traits<G>::edge_descriptor e_local,
353 const subgraph<G>& g)
354 { return source(e_local, g.m_graph); }
356 template <typename G>
357 typename graph_traits<G>::vertex_descriptor
358 target(typename graph_traits<G>::edge_descriptor e_local,
359 const subgraph<G>& g)
360 { return target(e_local, g.m_graph); }
362 //===========================================================================
363 // Functions required by the BidirectionalGraph concept
365 template <typename G>
366 std::pair<typename graph_traits<G>::in_edge_iterator,
367 typename graph_traits<G>::in_edge_iterator>
368 in_edges(typename graph_traits<G>::vertex_descriptor u_local,
369 const subgraph<G>& g)
370 { return in_edges(u_local, g.m_graph); }
372 template <typename G>
373 typename graph_traits<G>::degree_size_type
374 in_degree(typename graph_traits<G>::vertex_descriptor u_local,
375 const subgraph<G>& g)
376 { return in_degree(u_local, g.m_graph); }
378 template <typename G>
379 typename graph_traits<G>::degree_size_type
380 degree(typename graph_traits<G>::vertex_descriptor u_local,
381 const subgraph<G>& g)
382 { return degree(u_local, g.m_graph); }
384 //===========================================================================
385 // Functions required by the AdjacencyGraph concept
387 template <typename G>
388 std::pair<typename subgraph<G>::adjacency_iterator,
389 typename subgraph<G>::adjacency_iterator>
390 adjacent_vertices(typename subgraph<G>::vertex_descriptor u_local,
391 const subgraph<G>& g)
392 { return adjacent_vertices(u_local, g.m_graph); }
394 //===========================================================================
395 // Functions required by the VertexListGraph concept
397 template <typename G>
398 std::pair<typename subgraph<G>::vertex_iterator,
399 typename subgraph<G>::vertex_iterator>
400 vertices(const subgraph<G>& g)
401 { return vertices(g.m_graph); }
403 template <typename G>
404 typename subgraph<G>::vertices_size_type
405 num_vertices(const subgraph<G>& g)
406 { return num_vertices(g.m_graph); }
408 //===========================================================================
409 // Functions required by the EdgeListGraph concept
411 template <typename G>
412 std::pair<typename subgraph<G>::edge_iterator,
413 typename subgraph<G>::edge_iterator>
414 edges(const subgraph<G>& g)
415 { return edges(g.m_graph); }
417 template <typename G>
418 typename subgraph<G>::edges_size_type
419 num_edges(const subgraph<G>& g)
420 { return num_edges(g.m_graph); }
422 //===========================================================================
423 // Functions required by the AdjacencyMatrix concept
425 template <typename G>
426 std::pair<typename subgraph<G>::edge_descriptor, bool>
427 edge(typename subgraph<G>::vertex_descriptor u_local,
428 typename subgraph<G>::vertex_descriptor v_local,
429 const subgraph<G>& g)
431 return edge(u_local, v_local, g.m_graph);
434 //===========================================================================
435 // Functions required by the MutableGraph concept
439 template <typename Vertex, typename Edge, typename Graph>
440 void add_edge_recur_down
441 (Vertex u_global, Vertex v_global, Edge e_global, subgraph<Graph>& g);
443 template <typename Vertex, typename Edge, typename Children, typename G>
444 void children_add_edge(Vertex u_global, Vertex v_global, Edge e_global,
445 Children& c, subgraph<G>* orig)
447 for (typename Children::iterator i = c.begin(); i != c.end(); ++i)
448 if ((*i)->find_vertex(u_global).second
449 && (*i)->find_vertex(v_global).second)
450 add_edge_recur_down(u_global, v_global, e_global, **i, orig);
453 template <typename Vertex, typename Edge, typename Graph>
454 void add_edge_recur_down
455 (Vertex u_global, Vertex v_global, Edge e_global, subgraph<Graph>& g,
456 subgraph<Graph>* orig)
459 // add local edge only if u_global and v_global are in subgraph g
460 Vertex u_local, v_local;
461 bool u_in_subgraph, v_in_subgraph;
462 tie(u_local, u_in_subgraph) = g.find_vertex(u_global);
463 tie(v_local, v_in_subgraph) = g.find_vertex(v_global);
464 if (u_in_subgraph && v_in_subgraph)
465 g.local_add_edge(u_local, v_local, e_global);
467 children_add_edge(u_global, v_global, e_global, g.m_children, orig);
470 template <typename Vertex, typename Graph>
471 std::pair<typename subgraph<Graph>::edge_descriptor, bool>
472 add_edge_recur_up(Vertex u_global, Vertex v_global,
473 const typename Graph::edge_property_type& ep,
474 subgraph<Graph>& g, subgraph<Graph>* orig)
477 typename subgraph<Graph>::edge_descriptor e_global;
479 tie(e_global, inserted) = add_edge(u_global, v_global, ep, g.m_graph);
480 put(edge_index, g.m_graph, e_global, g.m_edge_counter++);
481 g.m_global_edge.push_back(e_global);
482 children_add_edge(u_global, v_global, e_global, g.m_children, orig);
483 return std::make_pair(e_global, inserted);
485 return add_edge_recur_up(u_global, v_global, ep, *g.m_parent, orig);
488 } // namespace detail
490 // Add an edge to the subgraph g, specified by the local vertex
491 // descriptors u and v. In addition, the edge will be added to any
492 // other subgraphs which contain vertex descriptors u and v.
494 template <typename G>
495 std::pair<typename subgraph<G>::edge_descriptor, bool>
496 add_edge(typename subgraph<G>::vertex_descriptor u_local,
497 typename subgraph<G>::vertex_descriptor v_local,
498 const typename G::edge_property_type& ep,
501 if (g.is_root()) // u_local and v_local are really global
502 return detail::add_edge_recur_up(u_local, v_local, ep, g, &g);
504 typename subgraph<G>::edge_descriptor e_local, e_global;
506 tie(e_global, inserted) = detail::add_edge_recur_up
507 (g.local_to_global(u_local), g.local_to_global(v_local), ep, g, &g);
508 e_local = g.local_add_edge(u_local, v_local, e_global);
509 return std::make_pair(e_local, inserted);
513 template <typename G>
514 std::pair<typename subgraph<G>::edge_descriptor, bool>
515 add_edge(typename subgraph<G>::vertex_descriptor u,
516 typename subgraph<G>::vertex_descriptor v,
519 typename G::edge_property_type ep;
520 return add_edge(u, v, ep, g);
525 //-------------------------------------------------------------------------
526 // implementation of remove_edge(u,v,g)
528 template <typename Vertex, typename Graph>
529 void remove_edge_recur_down(Vertex u_global, Vertex v_global,
532 template <typename Vertex, typename Children>
533 void children_remove_edge(Vertex u_global, Vertex v_global,
536 for (typename Children::iterator i = c.begin(); i != c.end(); ++i)
537 if ((*i)->find_vertex(u_global).second
538 && (*i)->find_vertex(v_global).second)
539 remove_edge_recur_down(u_global, v_global, **i);
542 template <typename Vertex, typename Graph>
543 void remove_edge_recur_down(Vertex u_global, Vertex v_global,
546 Vertex u_local, v_local;
547 u_local = g.m_local_vertex[u_global];
548 v_local = g.m_local_vertex[v_global];
549 remove_edge(u_local, v_local, g.m_graph);
550 children_remove_edge(u_global, v_global, g.m_children);
553 template <typename Vertex, typename Graph>
554 void remove_edge_recur_up(Vertex u_global, Vertex v_global,
558 remove_edge(u_global, v_global, g.m_graph);
559 children_remove_edge(u_global, v_global, g.m_children);
561 remove_edge_recur_up(u_global, v_global, *g.m_parent);
564 //-------------------------------------------------------------------------
565 // implementation of remove_edge(e,g)
567 template <typename Edge, typename Graph>
568 void remove_edge_recur_down(Edge e_global, subgraph<Graph>& g);
570 template <typename Edge, typename Children>
571 void children_remove_edge(Edge e_global, Children& c)
573 for (typename Children::iterator i = c.begin(); i != c.end(); ++i)
574 if ((*i)->find_vertex(source(e_global, **i)).second
575 && (*i)->find_vertex(target(e_global, **i)).second)
576 remove_edge_recur_down(source(e_global, **i),
577 target(e_global, **i), **i);
580 template <typename Edge, typename Graph>
581 void remove_edge_recur_down(Edge e_global, subgraph<Graph>& g)
583 remove_edge(g.global_to_local(e_global), g.m_graph);
584 children_remove_edge(e_global, g.m_children);
587 template <typename Edge, typename Graph>
588 void remove_edge_recur_up(Edge e_global, subgraph<Graph>& g)
591 remove_edge(e_global, g.m_graph);
592 children_remove_edge(e_global, g.m_children);
594 remove_edge_recur_up(e_global, *g.m_parent);
597 } // namespace detail
599 template <typename G>
601 remove_edge(typename subgraph<G>::vertex_descriptor u_local,
602 typename subgraph<G>::vertex_descriptor v_local,
606 detail::remove_edge_recur_up(u_local, v_local, g);
608 detail::remove_edge_recur_up(g.local_to_global(u_local),
609 g.local_to_global(v_local), g);
612 template <typename G>
614 remove_edge(typename subgraph<G>::edge_descriptor e_local,
618 detail::remove_edge_recur_up(e_local, g);
620 detail::remove_edge_recur_up(g.local_to_global(e_local), g);
623 template <typename Predicate, typename G>
625 remove_edge_if(Predicate p, subgraph<G>& g)
628 remove_edge_if(p, g.m_graph);
631 template <typename G>
633 clear_vertex(typename subgraph<G>::vertex_descriptor v_local,
637 clear_vertex(v_local, g.m_graph);
642 template <typename G>
643 typename subgraph<G>::vertex_descriptor
644 add_vertex_recur_up(subgraph<G>& g)
646 typename subgraph<G>::vertex_descriptor u_local, u_global;
648 u_global = add_vertex(g.m_graph);
649 g.m_global_vertex.push_back(u_global);
651 u_global = add_vertex_recur_up(*g.m_parent);
652 u_local = add_vertex(g.m_graph);
653 g.m_global_vertex.push_back(u_global);
654 g.m_local_vertex[u_global] = u_local;
659 } // namespace detail
661 template <typename G>
662 typename subgraph<G>::vertex_descriptor
663 add_vertex(subgraph<G>& g)
665 typename subgraph<G>::vertex_descriptor u_local, u_global;
667 u_global = add_vertex(g.m_graph);
668 g.m_global_vertex.push_back(u_global);
671 u_global = detail::add_vertex_recur_up(g.parent());
672 u_local = add_vertex(g.m_graph);
673 g.m_global_vertex.push_back(u_global);
674 g.m_local_vertex[u_global] = u_local;
679 template <typename G>
680 void remove_vertex(typename subgraph<G>::vertex_descriptor u,
683 // UNDER CONSTRUCTION
688 //===========================================================================
689 // Functions required by the PropertyGraph concept
691 template <typename GraphPtr, typename PropertyMap, typename Tag>
692 class subgraph_global_property_map
693 : public put_get_helper<
694 typename property_traits<PropertyMap>::reference,
695 subgraph_global_property_map<GraphPtr, PropertyMap, Tag> >
697 typedef property_traits<PropertyMap> Traits;
699 typedef typename Traits::category category;
700 typedef typename Traits::value_type value_type;
701 typedef typename Traits::key_type key_type;
702 typedef typename Traits::reference reference;
704 subgraph_global_property_map() { }
706 subgraph_global_property_map(GraphPtr g)
709 inline reference operator[](key_type e_local) const {
710 PropertyMap pmap = get(Tag(), m_g->root().m_graph);
711 if (m_g->m_parent == 0)
712 return pmap[e_local];
714 return pmap[m_g->local_to_global(e_local)];
719 template <typename GraphPtr, typename PropertyMap, typename Tag>
720 class subgraph_local_property_map
721 : public put_get_helper<
722 typename property_traits<PropertyMap>::reference,
723 subgraph_local_property_map<GraphPtr, PropertyMap, Tag> >
725 typedef property_traits<PropertyMap> Traits;
727 typedef typename Traits::category category;
728 typedef typename Traits::value_type value_type;
729 typedef typename Traits::key_type key_type;
730 typedef typename Traits::reference reference;
732 subgraph_local_property_map() { }
734 subgraph_local_property_map(GraphPtr g)
737 inline reference operator[](key_type e_local) const {
738 PropertyMap pmap = get(Tag(), *m_g);
739 return pmap[e_local];
746 struct subgraph_any_pmap {
747 template <class Tag, class SubGraph, class Property>
749 typedef typename SubGraph::graph_type Graph;
750 typedef SubGraph* SubGraphPtr;
751 typedef const SubGraph* const_SubGraphPtr;
752 typedef typename property_map<Graph, Tag>::type PMap;
753 typedef typename property_map<Graph, Tag>::const_type const_PMap;
755 typedef subgraph_global_property_map<SubGraphPtr, PMap, Tag> type;
756 typedef subgraph_global_property_map<const_SubGraphPtr, const_PMap, Tag>
760 struct subgraph_id_pmap {
761 template <class Tag, class SubGraph, class Property>
763 typedef typename SubGraph::graph_type Graph;
764 typedef SubGraph* SubGraphPtr;
765 typedef const SubGraph* const_SubGraphPtr;
766 typedef typename property_map<Graph, Tag>::type PMap;
767 typedef typename property_map<Graph, Tag>::const_type const_PMap;
769 typedef subgraph_local_property_map<SubGraphPtr, PMap, Tag> type;
770 typedef subgraph_local_property_map<const_SubGraphPtr, const_PMap, Tag>
775 struct subgraph_choose_pmap_helper {
776 typedef subgraph_any_pmap type;
779 struct subgraph_choose_pmap_helper<vertex_index_t> {
780 typedef subgraph_id_pmap type;
782 template <class Tag, class Graph, class Property>
783 struct subgraph_choose_pmap {
784 typedef typename subgraph_choose_pmap_helper<Tag>::type Helper;
785 typedef typename Helper::template bind_<Tag, Graph, Property> Bind;
786 typedef typename Bind::type type;
787 typedef typename Bind::const_type const_type;
789 struct subgraph_property_generator {
790 template <class SubGraph, class Property, class Tag>
792 typedef subgraph_choose_pmap<Tag, SubGraph, Property> Choice;
793 typedef typename Choice::type type;
794 typedef typename Choice::const_type const_type;
798 } // namespace detail
801 struct vertex_property_selector<subgraph_tag> {
802 typedef detail::subgraph_property_generator type;
806 struct edge_property_selector<subgraph_tag> {
807 typedef detail::subgraph_property_generator type;
810 template <typename G, typename Property>
811 typename property_map< subgraph<G>, Property>::type
812 get(Property, subgraph<G>& g)
814 typedef typename property_map< subgraph<G>, Property>::type PMap;
818 template <typename G, typename Property>
819 typename property_map< subgraph<G>, Property>::const_type
820 get(Property, const subgraph<G>& g)
822 typedef typename property_map< subgraph<G>, Property>::const_type PMap;
826 template <typename G, typename Property, typename Key>
827 typename property_traits<
828 typename property_map< subgraph<G>, Property>::const_type
830 get(Property, const subgraph<G>& g, const Key& k)
832 typedef typename property_map< subgraph<G>, Property>::const_type PMap;
837 template <typename G, typename Property, typename Key, typename Value>
839 put(Property, subgraph<G>& g, const Key& k, const Value& val)
841 typedef typename property_map< subgraph<G>, Property>::type PMap;
846 template <typename G, typename Tag>
848 typename graph_property<G, Tag>::type&
849 get_property(subgraph<G>& g, Tag tag) {
850 return get_property(g.m_graph, tag);
853 template <typename G, typename Tag>
855 const typename graph_property<G, Tag>::type&
856 get_property(const subgraph<G>& g, Tag tag) {
857 return get_property(g.m_graph, tag);
860 //===========================================================================
861 // Miscellaneous Functions
863 template <typename G>
864 typename subgraph<G>::vertex_descriptor
865 vertex(typename subgraph<G>::vertices_size_type n, const subgraph<G>& g)
867 return vertex(n, g.m_graph);
872 #endif // BOOST_SUBGRAPH_HPP