PageRenderTime 116ms CodeModel.GetById 20ms app.highlight 86ms RepoModel.GetById 1ms app.codeStats 0ms

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