LCOV - code coverage report
Current view: top level - usr/include/boost/graph/detail - adjacency_list.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 159 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 25 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // -*- c++ -*-
       2             : //=======================================================================
       3             : // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
       4             : // Copyright 2010 Thomas Claveirole
       5             : // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Thomas Claveirole
       6             : //
       7             : // Distributed under the Boost Software License, Version 1.0. (See
       8             : // accompanying file LICENSE_1_0.txt or copy at
       9             : // http://www.boost.org/LICENSE_1_0.txt)
      10             : //=======================================================================
      11             : 
      12             : #ifndef BOOST_GRAPH_DETAIL_ADJACENCY_LIST_HPP
      13             : #define BOOST_GRAPH_DETAIL_ADJACENCY_LIST_HPP
      14             : 
      15             : #include <map> // for vertex_map in copy_impl
      16             : #include <boost/config.hpp>
      17             : #include <boost/detail/workaround.hpp>
      18             : #include <boost/operators.hpp>
      19             : #include <boost/property_map/property_map.hpp>
      20             : #include <boost/pending/container_traits.hpp>
      21             : #include <boost/range/irange.hpp>
      22             : #include <boost/graph/graph_traits.hpp>
      23             : #include <memory>
      24             : #include <algorithm>
      25             : #include <boost/limits.hpp>
      26             : 
      27             : #include <boost/iterator/iterator_adaptor.hpp>
      28             : 
      29             : #include <boost/mpl/if.hpp>
      30             : #include <boost/mpl/not.hpp>
      31             : #include <boost/mpl/and.hpp>
      32             : #include <boost/graph/graph_concepts.hpp>
      33             : #include <boost/pending/container_traits.hpp>
      34             : #include <boost/graph/detail/adj_list_edge_iterator.hpp>
      35             : #include <boost/graph/properties.hpp>
      36             : #include <boost/pending/property.hpp>
      37             : #include <boost/graph/adjacency_iterator.hpp>
      38             : #include <boost/static_assert.hpp>
      39             : #include <boost/assert.hpp>
      40             : 
      41             : #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
      42             : #define BOOST_GRAPH_MOVE_IF_POSSIBLE(x) (x)
      43             : #else
      44             : #include <utility>
      45             : #define BOOST_GRAPH_MOVE_IF_POSSIBLE(x) (std::move((x)))
      46             : #endif
      47             : 
      48             : /*
      49             :   Outline for this file:
      50             : 
      51             :   out_edge_iterator and in_edge_iterator implementation
      52             :   edge_iterator for undirected graph
      53             :   stored edge types (these object live in the out-edge/in-edge lists)
      54             :   directed edges helper class
      55             :   directed graph helper class
      56             :   undirected graph helper class
      57             :   bidirectional graph helper class
      58             :   bidirectional graph helper class (without edge properties)
      59             :   bidirectional graph helper class (with edge properties)
      60             :   adjacency_list helper class
      61             :   adj_list_impl class
      62             :   vec_adj_list_impl class
      63             :   adj_list_gen class
      64             :   vertex property map
      65             :   edge property map
      66             : 
      67             : 
      68             :   Note: it would be nice to merge some of the undirected and
      69             :   bidirectional code... it is awful similar.
      70             :  */
      71             : 
      72             : 
      73             : namespace boost {
      74             : 
      75             :   namespace detail {
      76             : 
      77             :     template <typename DirectedS>
      78             :     struct directed_category_traits {
      79             :       typedef directed_tag directed_category;
      80             :     };
      81             : 
      82             :     template <>
      83             :     struct directed_category_traits<directedS> {
      84             :       typedef directed_tag directed_category;
      85             :     };
      86             :     template <>
      87             :     struct directed_category_traits<undirectedS> {
      88             :       typedef undirected_tag directed_category;
      89             :     };
      90             :     template <>
      91             :     struct directed_category_traits<bidirectionalS> {
      92             :       typedef bidirectional_tag directed_category;
      93             :     };
      94             : 
      95             :     template <class Vertex>
      96             :     struct target_is {
      97             :       target_is(const Vertex& v) : m_target(v) { }
      98             :       template <class StoredEdge>
      99             :       bool operator()(const StoredEdge& e) const {
     100             :         return e.get_target() == m_target;
     101             :       }
     102             :       Vertex m_target;
     103             :     };
     104             : 
     105             :     // O(E/V)
     106             :     template <class EdgeList, class vertex_descriptor>
     107             :     void erase_from_incidence_list(EdgeList& el, vertex_descriptor v,
     108             :                                    allow_parallel_edge_tag)
     109             :     {
     110             :       boost::graph_detail::erase_if(el, detail::target_is<vertex_descriptor>(v));
     111             :     }
     112             :     // O(log(E/V))
     113             :     template <class EdgeList, class vertex_descriptor>
     114             :     void erase_from_incidence_list(EdgeList& el, vertex_descriptor v,
     115             :                                    disallow_parallel_edge_tag)
     116             :     {
     117             :       typedef typename EdgeList::value_type StoredEdge;
     118             :       el.erase(StoredEdge(v));
     119             :     }
     120             : 
     121             :     //=========================================================================
     122             :     // Out-Edge and In-Edge Iterator Implementation
     123             : 
     124             :     template <class BaseIter, class VertexDescriptor, class EdgeDescriptor, class Difference>
     125             :     struct out_edge_iter
     126             :       : iterator_adaptor<
     127             :             out_edge_iter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>
     128             :           , BaseIter
     129             :           , EdgeDescriptor
     130             :           , use_default
     131             :           , EdgeDescriptor
     132             :           , Difference
     133             :         >
     134             :     {
     135             :       typedef iterator_adaptor<
     136             :           out_edge_iter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>
     137             :         , BaseIter
     138             :         , EdgeDescriptor
     139             :         , use_default
     140             :         , EdgeDescriptor
     141             :         , Difference
     142             :       > super_t;
     143             : 
     144           0 :       inline out_edge_iter() { }
     145           0 :         inline out_edge_iter(const BaseIter& i, const VertexDescriptor& src)
     146           0 :           : super_t(i), m_src(src) { }
     147             : 
     148             :       inline EdgeDescriptor
     149           0 :       dereference() const
     150             :       {
     151           0 :         return EdgeDescriptor(m_src, (*this->base()).get_target(),
     152           0 :                               &(*this->base()).get_property());
     153             :       }
     154             :       VertexDescriptor m_src;
     155             :     };
     156             : 
     157             :     template <class BaseIter, class VertexDescriptor, class EdgeDescriptor, class Difference>
     158             :     struct in_edge_iter
     159             :       : iterator_adaptor<
     160             :             in_edge_iter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>
     161             :           , BaseIter
     162             :           , EdgeDescriptor
     163             :           , use_default
     164             :           , EdgeDescriptor
     165             :           , Difference
     166             :         >
     167             :     {
     168             :       typedef iterator_adaptor<
     169             :           in_edge_iter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>
     170             :         , BaseIter
     171             :         , EdgeDescriptor
     172             :         , use_default
     173             :         , EdgeDescriptor
     174             :         , Difference
     175             :       > super_t;
     176             : 
     177           0 :       inline in_edge_iter() { }
     178           0 :       inline in_edge_iter(const BaseIter& i, const VertexDescriptor& src)
     179           0 :         : super_t(i), m_src(src) { }
     180             : 
     181             :       inline EdgeDescriptor
     182           0 :       dereference() const
     183             :       {
     184           0 :         return EdgeDescriptor((*this->base()).get_target(), m_src,
     185           0 :                               &this->base()->get_property());
     186             :       }
     187             :       VertexDescriptor m_src;
     188             :     };
     189             : 
     190             :     //=========================================================================
     191             :     // Undirected Edge Iterator Implementation
     192             : 
     193             :     template <class EdgeIter, class EdgeDescriptor, class Difference>
     194             :     struct undirected_edge_iter
     195             :       : iterator_adaptor<
     196             :             undirected_edge_iter<EdgeIter, EdgeDescriptor, Difference>
     197             :           , EdgeIter
     198             :           , EdgeDescriptor
     199             :           , use_default
     200             :           , EdgeDescriptor
     201             :           , Difference
     202             :         >
     203             :     {
     204             :       typedef iterator_adaptor<
     205             :           undirected_edge_iter<EdgeIter, EdgeDescriptor, Difference>
     206             :         , EdgeIter
     207             :         , EdgeDescriptor
     208             :         , use_default
     209             :         , EdgeDescriptor
     210             :         , Difference
     211             :       > super_t;
     212             : 
     213             :       undirected_edge_iter() {}
     214             : 
     215             :       explicit undirected_edge_iter(EdgeIter i)
     216             :           : super_t(i) {}
     217             : 
     218             :       inline EdgeDescriptor
     219             :       dereference() const {
     220             :         return EdgeDescriptor(
     221             :             (*this->base()).m_source
     222             :           , (*this->base()).m_target
     223             :           , &this->base()->get_property());
     224             :       }
     225             :     };
     226             : 
     227             :     //=========================================================================
     228             :     // Edge Storage Types (stored in the out-edge/in-edge lists)
     229             : 
     230             :     template <class Vertex>
     231             :     class stored_edge
     232             :       : public boost::equality_comparable1< stored_edge<Vertex>,
     233             :         boost::less_than_comparable1< stored_edge<Vertex> > >
     234             :     {
     235             :     public:
     236             :       typedef no_property property_type;
     237             :       inline stored_edge() { }
     238           0 :       inline stored_edge(Vertex target, const no_property& = no_property())
     239           0 :         : m_target(target) { }
     240           0 :       inline Vertex& get_target() const { return m_target; }
     241             :       inline const no_property& get_property() const { return s_prop; }
     242             :       inline bool operator==(const stored_edge& x) const
     243             :         { return m_target == x.get_target(); }
     244             :       inline bool operator<(const stored_edge& x) const
     245             :         { return m_target < x.get_target(); }
     246             :       //protected: need to add hash<> as a friend
     247             :       static no_property s_prop;
     248             :       // Sometimes target not used as key in the set, and in that case
     249             :       // it is ok to change the target.
     250             :       mutable Vertex m_target;
     251             :     };
     252             :     template <class Vertex>
     253             :     no_property stored_edge<Vertex>::s_prop;
     254             : 
     255             : #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_SMART_PTR)
     256             :     template <class Vertex, class Property>
     257             :     class stored_edge_property : public stored_edge<Vertex> {
     258             :       typedef stored_edge_property self;
     259             :       typedef stored_edge<Vertex> Base;
     260             :     public:
     261             :       typedef Property property_type;
     262             :       inline stored_edge_property() { }
     263             :       inline stored_edge_property(Vertex target,
     264             :                                   const Property& p = Property())
     265             :         : stored_edge<Vertex>(target), m_property(new Property(p)) { }
     266             :       stored_edge_property(const self& x)
     267             :         : Base(static_cast< Base const& >(x)), m_property(const_cast<self&>(x).m_property) { }
     268             :       self& operator=(const self& x) {
     269             :         // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla).
     270             :         static_cast<Base&>(*this) = static_cast< Base const& >(x);
     271             :         m_property = const_cast<self&>(x).m_property;
     272             :         return *this;
     273             :       }
     274             : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
     275             :       // NOTE Don't rely on default operators, their behavior is broken on several compilers (GCC 4.6).
     276             :       stored_edge_property(self&& x)
     277             :         : Base(static_cast< Base&& >(x)), m_property(std::move(x.m_property)) { }
     278             :       self& operator=(self&& x) {
     279             :         // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla).
     280             :         static_cast<Base&>(*this) = static_cast< Base&& >(x);
     281             :         m_property = std::move(x.m_property);
     282             :         return *this;
     283             :       }
     284             : #endif
     285             :       inline Property& get_property() { return *m_property; }
     286             :       inline const Property& get_property() const { return *m_property; }
     287             :     protected:
     288             :       // Holding the property by-value causes edge-descriptor
     289             :       // invalidation for add_edge() with EdgeList=vecS. Instead we
     290             :       // hold a pointer to the property. std::auto_ptr is not
     291             :       // a perfect fit for the job, but it is darn close.
     292             : #ifdef BOOST_NO_AUTO_PTR
     293             :       std::unique_ptr<Property> m_property;
     294             : #else
     295             :       std::auto_ptr<Property> m_property;
     296             : #endif
     297             :     };
     298             : #else
     299             :     template <class Vertex, class Property>
     300           0 :     class stored_edge_property : public stored_edge<Vertex> {
     301             :       typedef stored_edge_property self;
     302             :       typedef stored_edge<Vertex> Base;
     303             :     public:
     304             :       typedef Property property_type;
     305             :       inline stored_edge_property() { }
     306           0 :       inline stored_edge_property(Vertex target,
     307             :                                   const Property& p = Property())
     308           0 :         : stored_edge<Vertex>(target), m_property(new Property(p)) { }
     309           0 :       stored_edge_property(self&& x) : Base(static_cast< Base&& >(x)),
     310           0 :           m_property(std::move(x.m_property)) { }
     311             :       stored_edge_property(self const& x) : Base(static_cast< Base const& >(x)),
     312             :           m_property(std::move(const_cast<self&>(x).m_property)) { }
     313             :       self& operator=(self&& x) {
     314             :         // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla).
     315             :         static_cast<Base&>(*this) = static_cast< Base&& >(x);
     316             :         m_property = std::move(x.m_property);
     317             :         return *this;
     318             :       }
     319             :       self& operator=(self const& x) {
     320             :         // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla).
     321             :         static_cast<Base&>(*this) = static_cast< Base const& >(x);
     322             :         m_property = std::move(const_cast<self&>(x).m_property);
     323             :         return *this;
     324             :       }
     325           0 :       inline Property& get_property() { return *m_property; }
     326             :       inline const Property& get_property() const { return *m_property; }
     327             :     protected:
     328             :       std::unique_ptr<Property> m_property;
     329             :     };
     330             : #endif
     331             : 
     332             : 
     333             :     template <class Vertex, class Iter, class Property>
     334             :     class stored_edge_iter
     335             :       : public stored_edge<Vertex>
     336             :     {
     337             :     public:
     338             :       typedef Property property_type;
     339             :       inline stored_edge_iter() { }
     340             :       inline stored_edge_iter(Vertex v)
     341             :         : stored_edge<Vertex>(v) { }
     342           0 :       inline stored_edge_iter(Vertex v, Iter i, void* = 0)
     343           0 :         : stored_edge<Vertex>(v), m_iter(i) { }
     344           0 :       inline Property& get_property() { return m_iter->get_property(); }
     345             :       inline const Property& get_property() const {
     346             :         return m_iter->get_property();
     347             :       }
     348             :       inline Iter get_iter() const { return m_iter; }
     349             :     protected:
     350             :       Iter m_iter;
     351             :     };
     352             : 
     353             :     // For when the EdgeList is a std::vector.
     354             :     // Want to make the iterator stable, so use an offset
     355             :     // instead of an iterator into a std::vector
     356             :     template <class Vertex, class EdgeVec, class Property>
     357             :     class stored_ra_edge_iter
     358             :       : public stored_edge<Vertex>
     359             :     {
     360             :       typedef typename EdgeVec::iterator Iter;
     361             :     public:
     362             :       typedef Property property_type;
     363             :       inline stored_ra_edge_iter() { }
     364             :       inline explicit stored_ra_edge_iter(Vertex v) // Only used for comparisons
     365             :         : stored_edge<Vertex>(v), m_i(0), m_vec(0){ }
     366             :       inline stored_ra_edge_iter(Vertex v, Iter i, EdgeVec* edge_vec)
     367             :         : stored_edge<Vertex>(v), m_i(i - edge_vec->begin()), m_vec(edge_vec){ }
     368             :       inline Property& get_property() { BOOST_ASSERT ((m_vec != 0)); return (*m_vec)[m_i].get_property(); }
     369             :       inline const Property& get_property() const {
     370             :         BOOST_ASSERT ((m_vec != 0));
     371             :         return (*m_vec)[m_i].get_property();
     372             :       }
     373             :       inline Iter get_iter() const { BOOST_ASSERT ((m_vec != 0)); return m_vec->begin() + m_i; }
     374             :     protected:
     375             :       std::size_t m_i;
     376             :       EdgeVec* m_vec;
     377             :     };
     378             : 
     379             :   } // namespace detail
     380             : 
     381             :   template <class Tag, class Vertex, class Property>
     382             :   const typename property_value<Property,Tag>::type&
     383             :   get(Tag property_tag,
     384             :       const detail::stored_edge_property<Vertex, Property>& e)
     385             :   {
     386             :     return get_property_value(e.get_property(), property_tag);
     387             :   }
     388             : 
     389             :   template <class Tag, class Vertex, class Iter, class Property>
     390             :   const typename property_value<Property,Tag>::type&
     391             :   get(Tag property_tag,
     392             :       const detail::stored_edge_iter<Vertex, Iter, Property>& e)
     393             :   {
     394             :     return get_property_value(e.get_property(), property_tag);
     395             :   }
     396             : 
     397             :   template <class Tag, class Vertex, class EdgeVec, class Property>
     398             :   const typename property_value<Property,Tag>::type&
     399             :   get(Tag property_tag,
     400             :       const detail::stored_ra_edge_iter<Vertex, EdgeVec, Property>& e)
     401             :   {
     402             :     return get_property_value(e.get_property(), property_tag);
     403             :   }
     404             : 
     405             :     //=========================================================================
     406             :     // Directed Edges Helper Class
     407             : 
     408             :     namespace detail {
     409             : 
     410             :       // O(E/V)
     411             :       template <class edge_descriptor, class EdgeList, class StoredProperty>
     412             :       inline void
     413             :       remove_directed_edge_dispatch(edge_descriptor, EdgeList& el,
     414             :                                     StoredProperty& p)
     415             :       {
     416             :         for (typename EdgeList::iterator i = el.begin();
     417             :              i != el.end(); ++i)
     418             :           if (&(*i).get_property() == &p) {
     419             :             el.erase(i);
     420             :             return;
     421             :           }
     422             :       }
     423             : 
     424             :       template <class incidence_iterator, class EdgeList, class Predicate>
     425             :       inline void
     426             :       remove_directed_edge_if_dispatch(incidence_iterator first,
     427             :                                        incidence_iterator last,
     428             :                                        EdgeList& el, Predicate pred,
     429             :                                        boost::allow_parallel_edge_tag)
     430             :       {
     431             :         // remove_if
     432             :         while (first != last && !pred(*first))
     433             :           ++first;
     434             :         incidence_iterator i = first;
     435             :         if (first != last)
     436             :           for (++i; i != last; ++i)
     437             :             if (!pred(*i)) {
     438             :               *first.base() = BOOST_GRAPH_MOVE_IF_POSSIBLE(*i.base());
     439             :               ++first;
     440             :             }
     441             :         el.erase(first.base(), el.end());
     442             :       }
     443             :       template <class incidence_iterator, class EdgeList, class Predicate>
     444             :       inline void
     445             :       remove_directed_edge_if_dispatch(incidence_iterator first,
     446             :                                        incidence_iterator last,
     447             :                                        EdgeList& el,
     448             :                                        Predicate pred,
     449             :                                        boost::disallow_parallel_edge_tag)
     450             :       {
     451             :         for (incidence_iterator next = first;
     452             :              first != last; first = next) {
     453             :           ++next;
     454             :           if (pred(*first))
     455             :             el.erase( first.base() );
     456             :         }
     457             :       }
     458             : 
     459             :       template <class PropT, class Graph, class incidence_iterator,
     460             :                 class EdgeList, class Predicate>
     461             :       inline void
     462             :       undirected_remove_out_edge_if_dispatch(Graph& g,
     463             :                                              incidence_iterator first,
     464             :                                              incidence_iterator last,
     465             :                                              EdgeList& el, Predicate pred,
     466             :                                              boost::allow_parallel_edge_tag)
     467             :       {
     468             :         typedef typename Graph::global_edgelist_selector EdgeListS;
     469             :         BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
     470             : 
     471             :         // remove_if
     472             :         while (first != last && !pred(*first))
     473             :           ++first;
     474             :         incidence_iterator i = first;
     475             :         bool self_loop_removed = false;
     476             :         if (first != last)
     477             :           for (; i != last; ++i) {
     478             :             if (self_loop_removed) {
     479             :               /* With self loops, the descriptor will show up
     480             :                * twice. The first time it will be removed, and now it
     481             :                * will be skipped.
     482             :                */
     483             :               self_loop_removed = false;
     484             :             }
     485             :             else if (!pred(*i)) {
     486             :               *first.base() = BOOST_GRAPH_MOVE_IF_POSSIBLE(*i.base());
     487             :               ++first;
     488             :             } else {
     489             :               if (source(*i, g) == target(*i, g)) self_loop_removed = true;
     490             :               else {
     491             :                 // Remove the edge from the target
     492             :                 detail::remove_directed_edge_dispatch
     493             :                   (*i,
     494             :                    g.out_edge_list(target(*i, g)),
     495             :                    *(PropT*)(*i).get_property());
     496             :               }
     497             : 
     498             :               // Erase the edge property
     499             :               g.m_edges.erase( (*i.base()).get_iter() );
     500             :             }
     501             :           }
     502             :         el.erase(first.base(), el.end());
     503             :       }
     504             :       template <class PropT, class Graph, class incidence_iterator,
     505             :                 class EdgeList, class Predicate>
     506             :       inline void
     507             :       undirected_remove_out_edge_if_dispatch(Graph& g,
     508             :                                              incidence_iterator first,
     509             :                                              incidence_iterator last,
     510             :                                              EdgeList& el,
     511             :                                              Predicate pred,
     512             :                                              boost::disallow_parallel_edge_tag)
     513             :       {
     514             :         typedef typename Graph::global_edgelist_selector EdgeListS;
     515             :         BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
     516             : 
     517             :         for (incidence_iterator next = first;
     518             :              first != last; first = next) {
     519             :           ++next;
     520             :           if (pred(*first)) {
     521             :             if (source(*first, g) != target(*first, g)) {
     522             :               // Remove the edge from the target
     523             :               detail::remove_directed_edge_dispatch
     524             :                 (*first,
     525             :                  g.out_edge_list(target(*first, g)),
     526             :                  *(PropT*)(*first).get_property());
     527             :             }
     528             : 
     529             :             // Erase the edge property
     530             :             g.m_edges.erase( (*first.base()).get_iter() );
     531             : 
     532             :             // Erase the edge in the source
     533             :             el.erase( first.base() );
     534             :           }
     535             :         }
     536             :       }
     537             : 
     538             :       // O(E/V)
     539             :       template <class edge_descriptor, class EdgeList, class StoredProperty>
     540             :       inline void
     541             :       remove_directed_edge_dispatch(edge_descriptor e, EdgeList& el,
     542             :                                     no_property&)
     543             :       {
     544             :         for (typename EdgeList::iterator i = el.begin();
     545             :              i != el.end(); ++i)
     546             :           if ((*i).get_target() == e.m_target) {
     547             :             el.erase(i);
     548             :             return;
     549             :           }
     550             :       }
     551             : 
     552             :     } // namespace detail
     553             : 
     554             :     template <class Config>
     555             :     struct directed_edges_helper {
     556             : 
     557             :       // Placement of these overloaded remove_edge() functions
     558             :       // inside the class avoids a VC++ bug.
     559             : 
     560             :       // O(E/V)
     561             :       inline void
     562             :       remove_edge(typename Config::edge_descriptor e)
     563             :       {
     564             :         typedef typename Config::graph_type graph_type;
     565             :         graph_type& g = static_cast<graph_type&>(*this);
     566             :         typename Config::OutEdgeList& el = g.out_edge_list(source(e, g));
     567             :         typedef typename Config::OutEdgeList::value_type::property_type PType;
     568             :         detail::remove_directed_edge_dispatch(e, el,
     569             :                                               *(PType*)e.get_property());
     570             :       }
     571             : 
     572             :       // O(1)
     573             :       inline void
     574             :       remove_edge(typename Config::out_edge_iterator iter)
     575             :       {
     576             :         typedef typename Config::graph_type graph_type;
     577             :         graph_type& g = static_cast<graph_type&>(*this);
     578             :         typename Config::edge_descriptor e = *iter;
     579             :         typename Config::OutEdgeList& el = g.out_edge_list(source(e, g));
     580             :         el.erase(iter.base());
     581             :       }
     582             : 
     583             :     };
     584             : 
     585             :     // O(1)
     586             :     template <class Config>
     587             :     inline std::pair<typename Config::edge_iterator,
     588             :                      typename Config::edge_iterator>
     589           0 :     edges(const directed_edges_helper<Config>& g_)
     590             :     {
     591             :       typedef typename Config::graph_type graph_type;
     592             :       typedef typename Config::edge_iterator edge_iterator;
     593           0 :       const graph_type& cg = static_cast<const graph_type&>(g_);
     594           0 :       graph_type& g = const_cast<graph_type&>(cg);
     595           0 :       return std::make_pair( edge_iterator(g.vertex_set().begin(),
     596           0 :                                            g.vertex_set().begin(),
     597           0 :                                            g.vertex_set().end(), g),
     598           0 :                              edge_iterator(g.vertex_set().begin(),
     599           0 :                                            g.vertex_set().end(),
     600           0 :                                            g.vertex_set().end(), g) );
     601             :     }
     602             : 
     603             :     //=========================================================================
     604             :     // Directed Graph Helper Class
     605             : 
     606             :     struct adj_list_dir_traversal_tag :
     607             :       public virtual vertex_list_graph_tag,
     608             :       public virtual incidence_graph_tag,
     609             :       public virtual adjacency_graph_tag,
     610             :       public virtual edge_list_graph_tag { };
     611             : 
     612             :     template <class Config>
     613             :     struct directed_graph_helper
     614             :       : public directed_edges_helper<Config> {
     615             :       typedef typename Config::edge_descriptor edge_descriptor;
     616             :       typedef adj_list_dir_traversal_tag traversal_category;
     617             :     };
     618             : 
     619             :     // O(E/V)
     620             :     template <class Config>
     621             :     inline void
     622             :     remove_edge(typename Config::vertex_descriptor u,
     623             :                 typename Config::vertex_descriptor v,
     624             :                 directed_graph_helper<Config>& g_)
     625             :     {
     626             :       typedef typename Config::graph_type graph_type;
     627             :       typedef typename Config::edge_parallel_category Cat;
     628             :       graph_type& g = static_cast<graph_type&>(g_);
     629             :       detail::erase_from_incidence_list(g.out_edge_list(u), v, Cat());
     630             :     }
     631             : 
     632             :     template <class Config, class Predicate>
     633             :     inline void
     634             :     remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred,
     635             :                        directed_graph_helper<Config>& g_)
     636             :     {
     637             :       typedef typename Config::graph_type graph_type;
     638             :       graph_type& g = static_cast<graph_type&>(g_);
     639             :       typename Config::out_edge_iterator first, last;
     640             :       boost::tie(first, last) = out_edges(u, g);
     641             :       typedef typename Config::edge_parallel_category edge_parallel_category;
     642             :       detail::remove_directed_edge_if_dispatch
     643             :         (first, last, g.out_edge_list(u), pred, edge_parallel_category());
     644             :     }
     645             : 
     646             :     template <class Config, class Predicate>
     647             :     inline void
     648             :     remove_edge_if(Predicate pred, directed_graph_helper<Config>& g_)
     649             :     {
     650             :       typedef typename Config::graph_type graph_type;
     651             :       graph_type& g = static_cast<graph_type&>(g_);
     652             : 
     653             :       typename Config::vertex_iterator vi, vi_end;
     654             :       for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
     655             :         remove_out_edge_if(*vi, pred, g);
     656             :     }
     657             : 
     658             :     template <class EdgeOrIter, class Config>
     659             :     inline void
     660             :     remove_edge(EdgeOrIter e_or_iter, directed_graph_helper<Config>& g_)
     661             :     {
     662             :       g_.remove_edge(e_or_iter);
     663             :     }
     664             : 
     665             :     // O(V + E) for allow_parallel_edges
     666             :     // O(V * log(E/V)) for disallow_parallel_edges
     667             :     template <class Config>
     668             :     inline void
     669             :     clear_vertex(typename Config::vertex_descriptor u,
     670             :                  directed_graph_helper<Config>& g_)
     671             :     {
     672             :       typedef typename Config::graph_type graph_type;
     673             :       typedef typename Config::edge_parallel_category Cat;
     674             :       graph_type& g = static_cast<graph_type&>(g_);
     675             :       typename Config::vertex_iterator vi, viend;
     676             :       for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
     677             :         detail::erase_from_incidence_list(g.out_edge_list(*vi), u, Cat());
     678             :       g.out_edge_list(u).clear();
     679             :       // clear() should be a req of Sequence and AssociativeContainer,
     680             :       // or maybe just Container
     681             :     }
     682             : 
     683             :     template <class Config>
     684             :     inline void
     685             :     clear_out_edges(typename Config::vertex_descriptor u,
     686             :                     directed_graph_helper<Config>& g_)
     687             :     {
     688             :       typedef typename Config::graph_type graph_type;
     689             :       graph_type& g = static_cast<graph_type&>(g_);
     690             :       g.out_edge_list(u).clear();
     691             :       // clear() should be a req of Sequence and AssociativeContainer,
     692             :       // or maybe just Container
     693             :     }
     694             : 
     695             :     // O(V), could do better...
     696             :     template <class Config>
     697             :     inline typename Config::edges_size_type
     698           0 :     num_edges(const directed_graph_helper<Config>& g_)
     699             :     {
     700             :       typedef typename Config::graph_type graph_type;
     701           0 :       const graph_type& g = static_cast<const graph_type&>(g_);
     702           0 :       typename Config::edges_size_type num_e = 0;
     703           0 :       typename Config::vertex_iterator vi, vi_end;
     704           0 :       for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
     705           0 :         num_e += out_degree(*vi, g);
     706             :       return num_e;
     707             :     }
     708             :     // O(1) for allow_parallel_edge_tag
     709             :     // O(log(E/V)) for disallow_parallel_edge_tag
     710             :     template <class Config>
     711             :     inline std::pair<typename directed_graph_helper<Config>::edge_descriptor, bool>
     712           0 :     add_edge(typename Config::vertex_descriptor u,
     713             :              typename Config::vertex_descriptor v,
     714             :              const typename Config::edge_property_type& p,
     715             :              directed_graph_helper<Config>& g_)
     716             :     {
     717             :       typedef typename Config::edge_descriptor edge_descriptor;
     718             :       typedef typename Config::graph_type graph_type;
     719             :       typedef typename Config::StoredEdge StoredEdge;
     720           0 :       graph_type& g = static_cast<graph_type&>(g_);
     721           0 :       typename Config::OutEdgeList::iterator i;
     722             :       bool inserted;
     723           0 :       boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u),
     724             :                                             StoredEdge(v, p));
     725           0 :       return std::make_pair(edge_descriptor(u, v, &(*i).get_property()),
     726           0 :                             inserted);
     727             :     }
     728             :     // Did not use default argument here because that
     729             :     // causes Visual C++ to get confused.
     730             :     template <class Config>
     731             :     inline std::pair<typename Config::edge_descriptor, bool>
     732             :     add_edge(typename Config::vertex_descriptor u,
     733             :              typename Config::vertex_descriptor v,
     734             :              directed_graph_helper<Config>& g_)
     735             :     {
     736             :       typename Config::edge_property_type p;
     737             :       return add_edge(u, v, p, g_);
     738             :     }
     739             :     //=========================================================================
     740             :     // Undirected Graph Helper Class
     741             : 
     742             :     template <class Config>
     743             :     struct undirected_graph_helper;
     744             : 
     745             :     struct undir_adj_list_traversal_tag :
     746             :       public virtual vertex_list_graph_tag,
     747             :       public virtual incidence_graph_tag,
     748             :       public virtual adjacency_graph_tag,
     749             :       public virtual edge_list_graph_tag,
     750             :       public virtual bidirectional_graph_tag { };
     751             : 
     752             :     namespace detail {
     753             : 
     754             :       // using class with specialization for dispatch is a VC++ workaround.
     755             :       template <class StoredProperty>
     756             :       struct remove_undirected_edge_dispatch {
     757             : 
     758             :         // O(E/V)
     759             :         template <class edge_descriptor, class Config>
     760             :         static void
     761             :         apply(edge_descriptor e,
     762             :               undirected_graph_helper<Config>& g_,
     763             :               StoredProperty& p)
     764             :         {
     765             :           typedef typename Config::global_edgelist_selector EdgeListS;
     766             :           BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
     767             : 
     768             :           typedef typename Config::graph_type graph_type;
     769             :           graph_type& g = static_cast<graph_type&>(g_);
     770             : 
     771             :           typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g));
     772             :           typename Config::OutEdgeList::iterator out_i = out_el.begin();
     773             :           typename Config::EdgeIter edge_iter_to_erase;
     774             :           for (; out_i != out_el.end(); ++out_i)
     775             :             if (&(*out_i).get_property() == &p) {
     776             :               edge_iter_to_erase = (*out_i).get_iter();
     777             :               out_el.erase(out_i);
     778             :               break;
     779             :             }
     780             :           typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g));
     781             :           typename Config::OutEdgeList::iterator in_i = in_el.begin();
     782             :           for (; in_i != in_el.end(); ++in_i)
     783             :             if (&(*in_i).get_property() == &p) {
     784             :               in_el.erase(in_i);
     785             :               break;
     786             :             }
     787             :           g.m_edges.erase(edge_iter_to_erase);
     788             :         }
     789             :       };
     790             : 
     791             :       template <>
     792             :       struct remove_undirected_edge_dispatch<no_property> {
     793             :         // O(E/V)
     794             :         template <class edge_descriptor, class Config>
     795             :         static void
     796             :         apply(edge_descriptor e,
     797             :               undirected_graph_helper<Config>& g_,
     798             :               no_property&)
     799             :         {
     800             :           typedef typename Config::global_edgelist_selector EdgeListS;
     801             :           BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
     802             : 
     803             :           typedef typename Config::graph_type graph_type;
     804             :           graph_type& g = static_cast<graph_type&>(g_);
     805             :           no_property* p = (no_property*)e.get_property();
     806             :           typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g));
     807             :           typename Config::OutEdgeList::iterator out_i = out_el.begin();
     808             :           typename Config::EdgeIter edge_iter_to_erase;
     809             :           for (; out_i != out_el.end(); ++out_i)
     810             :             if (&(*out_i).get_property() == p) {
     811             :               edge_iter_to_erase = (*out_i).get_iter();
     812             :               out_el.erase(out_i);
     813             :               break;
     814             :             }
     815             :           typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g));
     816             :           typename Config::OutEdgeList::iterator in_i = in_el.begin();
     817             :           for (; in_i != in_el.end(); ++in_i)
     818             :             if (&(*in_i).get_property() == p) {
     819             :               in_el.erase(in_i);
     820             :               break;
     821             :             }
     822             :           g.m_edges.erase(edge_iter_to_erase);
     823             :         }
     824             :       };
     825             : 
     826             :       // O(E/V)
     827             :       template <class Graph, class EdgeList, class Vertex>
     828             :       inline void
     829             :       remove_edge_and_property(Graph& g, EdgeList& el, Vertex v,
     830             :                                boost::allow_parallel_edge_tag cat)
     831             :       {
     832             :         typedef typename Graph::global_edgelist_selector EdgeListS;
     833             :         BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
     834             : 
     835             :         typename EdgeList::iterator i = el.begin(), end = el.end();
     836             :         for (; i != end; ++i) {
     837             :           if ((*i).get_target() == v) {
     838             :             // NOTE: Wihtout this skip, this loop will double-delete properties
     839             :             // of loop edges. This solution is based on the observation that
     840             :             // the incidence edges of a vertex with a loop are adjacent in the
     841             :             // out edge list. This *may* actually hold for multisets also.
     842             :             bool skip = (boost::next(i) != end && i->get_iter() == boost::next(i)->get_iter());
     843             :             g.m_edges.erase((*i).get_iter());
     844             :             if (skip) ++i;
     845             :           }
     846             :         }
     847             :         detail::erase_from_incidence_list(el, v, cat);
     848             :       }
     849             :       // O(log(E/V))
     850             :       template <class Graph, class EdgeList, class Vertex>
     851             :       inline void
     852             :       remove_edge_and_property(Graph& g, EdgeList& el, Vertex v,
     853             :                                boost::disallow_parallel_edge_tag)
     854             :       {
     855             :         typedef typename Graph::global_edgelist_selector EdgeListS;
     856             :         BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
     857             : 
     858             :         typedef typename EdgeList::value_type StoredEdge;
     859             :         typename EdgeList::iterator i = el.find(StoredEdge(v)), end = el.end();
     860             :         if (i != end) {
     861             :           g.m_edges.erase((*i).get_iter());
     862             :           el.erase(i);
     863             :         }
     864             :       }
     865             : 
     866             :     } // namespace detail
     867             : 
     868             :     template <class Vertex, class EdgeProperty>
     869           0 :     struct list_edge // short name due to VC++ truncation and linker problems
     870             :       : public boost::detail::edge_base<boost::undirected_tag, Vertex>
     871             :     {
     872             :       typedef EdgeProperty property_type;
     873             :       typedef boost::detail::edge_base<boost::undirected_tag, Vertex> Base;
     874           0 :       list_edge(Vertex u, Vertex v, const EdgeProperty& p = EdgeProperty())
     875           0 :         : Base(u, v), m_property(p) { }
     876           0 :       EdgeProperty& get_property() { return m_property; }
     877             :       const EdgeProperty& get_property() const { return m_property; }
     878             :       // the following methods should never be used, but are needed
     879             :       // to make SGI MIPSpro C++ happy
     880             :       list_edge() { }
     881             :       bool operator==(const list_edge&) const { return false; }
     882             :       bool operator<(const list_edge&) const { return false; }
     883             :       EdgeProperty m_property;
     884             :     };
     885             : 
     886             :     template <class Config>
     887             :     struct undirected_graph_helper {
     888             : 
     889             :       typedef undir_adj_list_traversal_tag traversal_category;
     890             : 
     891             :       // Placement of these overloaded remove_edge() functions
     892             :       // inside the class avoids a VC++ bug.
     893             : 
     894             :       // O(E/V)
     895             :       inline void
     896             :       remove_edge(typename Config::edge_descriptor e)
     897             :       {
     898             :         typedef typename Config::global_edgelist_selector EdgeListS;
     899             :         BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
     900             : 
     901             :         typedef typename Config::OutEdgeList::value_type::property_type PType;
     902             :         detail::remove_undirected_edge_dispatch<PType>::apply
     903             :           (e, *this, *(PType*)e.get_property());
     904             :       }
     905             :       // O(E/V)
     906             :       inline void
     907             :       remove_edge(typename Config::out_edge_iterator iter)
     908             :       {
     909             :         this->remove_edge(*iter);
     910             :       }
     911             :     };
     912             : 
     913             :     // Had to make these non-members to avoid accidental instantiation
     914             :     // on SGI MIPSpro C++
     915             :     template <class C>
     916             :     inline typename C::InEdgeList&
     917             :     in_edge_list(undirected_graph_helper<C>&,
     918             :                  typename C::vertex_descriptor v)
     919             :     {
     920             :       typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
     921             :       return sv->m_out_edges;
     922             :     }
     923             :     template <class C>
     924             :     inline const typename C::InEdgeList&
     925             :     in_edge_list(const undirected_graph_helper<C>&,
     926             :                  typename C::vertex_descriptor v) {
     927             :       typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
     928             :       return sv->m_out_edges;
     929             :     }
     930             : 
     931             :     // O(E/V)
     932             :     template <class EdgeOrIter, class Config>
     933             :     inline void
     934             :     remove_edge(EdgeOrIter e, undirected_graph_helper<Config>& g_)
     935             :     {
     936             :       typedef typename Config::global_edgelist_selector EdgeListS;
     937             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
     938             : 
     939             :       g_.remove_edge(e);
     940             :     }
     941             : 
     942             :     // O(E/V) or O(log(E/V))
     943             :     template <class Config>
     944             :     void
     945             :     remove_edge(typename Config::vertex_descriptor u,
     946             :                 typename Config::vertex_descriptor v,
     947             :                 undirected_graph_helper<Config>& g_)
     948             :     {
     949             :       typedef typename Config::global_edgelist_selector EdgeListS;
     950             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
     951             : 
     952             :       typedef typename Config::graph_type graph_type;
     953             :       graph_type& g = static_cast<graph_type&>(g_);
     954             :       typedef typename Config::edge_parallel_category Cat;
     955             :       detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat());
     956             :       detail::erase_from_incidence_list(g.out_edge_list(v), u, Cat());
     957             :     }
     958             : 
     959             :     template <class Config, class Predicate>
     960             :     void
     961             :     remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred,
     962             :                        undirected_graph_helper<Config>& g_)
     963             :     {
     964             :       typedef typename Config::global_edgelist_selector EdgeListS;
     965             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
     966             : 
     967             :       typedef typename Config::graph_type graph_type;
     968             :       typedef typename Config::OutEdgeList::value_type::property_type PropT;
     969             :       graph_type& g = static_cast<graph_type&>(g_);
     970             :       typename Config::out_edge_iterator first, last;
     971             :       boost::tie(first, last) = out_edges(u, g);
     972             :       typedef typename Config::edge_parallel_category Cat;
     973             :       detail::undirected_remove_out_edge_if_dispatch<PropT>
     974             :         (g, first, last, g.out_edge_list(u), pred, Cat());
     975             :     }
     976             :     template <class Config, class Predicate>
     977             :     void
     978             :     remove_in_edge_if(typename Config::vertex_descriptor u, Predicate pred,
     979             :                       undirected_graph_helper<Config>& g_)
     980             :     {
     981             :       typedef typename Config::global_edgelist_selector EdgeListS;
     982             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
     983             : 
     984             :       remove_out_edge_if(u, pred, g_);
     985             :     }
     986             : 
     987             :     // O(E/V * E) or O(log(E/V) * E)
     988             :     template <class Predicate, class Config>
     989             :     void
     990             :     remove_edge_if(Predicate pred, undirected_graph_helper<Config>& g_)
     991             :     {
     992             :       typedef typename Config::global_edgelist_selector EdgeListS;
     993             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
     994             : 
     995             :       typedef typename Config::graph_type graph_type;
     996             :       graph_type& g = static_cast<graph_type&>(g_);
     997             :       typename Config::edge_iterator ei, ei_end, next;
     998             :       boost::tie(ei, ei_end) = edges(g);
     999             :       for (next = ei; ei != ei_end; ei = next) {
    1000             :         ++next;
    1001             :         if (pred(*ei))
    1002             :           remove_edge(*ei, g);
    1003             :       }
    1004             :     }
    1005             : 
    1006             :     // O(1)
    1007             :     template <class Config>
    1008             :     inline std::pair<typename Config::edge_iterator,
    1009             :                      typename Config::edge_iterator>
    1010             :     edges(const undirected_graph_helper<Config>& g_)
    1011             :     {
    1012             :       typedef typename Config::graph_type graph_type;
    1013             :       typedef typename Config::edge_iterator edge_iterator;
    1014             :       const graph_type& cg = static_cast<const graph_type&>(g_);
    1015             :       graph_type& g = const_cast<graph_type&>(cg);
    1016             :       return std::make_pair( edge_iterator(g.m_edges.begin()),
    1017             :                              edge_iterator(g.m_edges.end()) );
    1018             :     }
    1019             :     // O(1)
    1020             :     template <class Config>
    1021             :     inline typename Config::edges_size_type
    1022             :     num_edges(const undirected_graph_helper<Config>& g_)
    1023             :     {
    1024             :       typedef typename Config::graph_type graph_type;
    1025             :       const graph_type& g = static_cast<const graph_type&>(g_);
    1026             :       return g.m_edges.size();
    1027             :     }
    1028             :     // O(E/V * E/V)
    1029             :     template <class Config>
    1030             :     inline void
    1031             :     clear_vertex(typename Config::vertex_descriptor u,
    1032             :                  undirected_graph_helper<Config>& g_)
    1033             :     {
    1034             :       typedef typename Config::global_edgelist_selector EdgeListS;
    1035             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    1036             : 
    1037             :       typedef typename Config::graph_type graph_type;
    1038             :       graph_type& g = static_cast<graph_type&>(g_);
    1039             :       while (true) {
    1040             :         typename Config::out_edge_iterator ei, ei_end;
    1041             :         boost::tie(ei, ei_end) = out_edges(u, g);
    1042             :         if (ei == ei_end) break;
    1043             :         remove_edge(*ei, g);
    1044             :       }
    1045             :     }
    1046             :     // O(1) for allow_parallel_edge_tag
    1047             :     // O(log(E/V)) for disallow_parallel_edge_tag
    1048             :     template <class Config>
    1049             :     inline std::pair<typename Config::edge_descriptor, bool>
    1050             :     add_edge(typename Config::vertex_descriptor u,
    1051             :              typename Config::vertex_descriptor v,
    1052             :              const typename Config::edge_property_type& p,
    1053             :              undirected_graph_helper<Config>& g_)
    1054             :     {
    1055             :       typedef typename Config::StoredEdge StoredEdge;
    1056             :       typedef typename Config::edge_descriptor edge_descriptor;
    1057             :       typedef typename Config::graph_type graph_type;
    1058             :       graph_type& g = static_cast<graph_type&>(g_);
    1059             : 
    1060             :       bool inserted;
    1061             :       typename Config::EdgeContainer::value_type e(u, v, p);
    1062             :       typename Config::EdgeContainer::iterator p_iter
    1063             :         = graph_detail::push(g.m_edges, e).first;
    1064             : 
    1065             :       typename Config::OutEdgeList::iterator i;
    1066             :       boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u),
    1067             :                                     StoredEdge(v, p_iter, &g.m_edges));
    1068             :       if (inserted) {
    1069             :         boost::graph_detail::push(g.out_edge_list(v), StoredEdge(u, p_iter, &g.m_edges));
    1070             :         return std::make_pair(edge_descriptor(u, v, &p_iter->get_property()),
    1071             :                               true);
    1072             :       } else {
    1073             :         g.m_edges.erase(p_iter);
    1074             :         return std::make_pair
    1075             :           (edge_descriptor(u, v, &i->get_iter()->get_property()), false);
    1076             :       }
    1077             :     }
    1078             :     template <class Config>
    1079             :     inline std::pair<typename Config::edge_descriptor, bool>
    1080             :     add_edge(typename Config::vertex_descriptor u,
    1081             :              typename Config::vertex_descriptor v,
    1082             :              undirected_graph_helper<Config>& g_)
    1083             :     {
    1084             :       typename Config::edge_property_type p;
    1085             :       return add_edge(u, v, p, g_);
    1086             :     }
    1087             : 
    1088             :     // O(1)
    1089             :     template <class Config>
    1090             :     inline typename Config::degree_size_type
    1091             :     degree(typename Config::vertex_descriptor u,
    1092             :            const undirected_graph_helper<Config>& g_)
    1093             :     {
    1094             :       typedef typename Config::graph_type Graph;
    1095             :       const Graph& g = static_cast<const Graph&>(g_);
    1096             :       return out_degree(u, g);
    1097             :     }
    1098             : 
    1099             :     template <class Config>
    1100             :     inline std::pair<typename Config::in_edge_iterator,
    1101             :                      typename Config::in_edge_iterator>
    1102             :     in_edges(typename Config::vertex_descriptor u,
    1103             :              const undirected_graph_helper<Config>& g_)
    1104             :     {
    1105             :       typedef typename Config::graph_type Graph;
    1106             :       const Graph& cg = static_cast<const Graph&>(g_);
    1107             :       Graph& g = const_cast<Graph&>(cg);
    1108             :       typedef typename Config::in_edge_iterator in_edge_iterator;
    1109             :       return
    1110             :         std::make_pair(in_edge_iterator(g.out_edge_list(u).begin(), u),
    1111             :                        in_edge_iterator(g.out_edge_list(u).end(), u));
    1112             :     }
    1113             : 
    1114             :     template <class Config>
    1115             :     inline typename Config::degree_size_type
    1116             :     in_degree(typename Config::vertex_descriptor u,
    1117             :               const undirected_graph_helper<Config>& g_)
    1118             :     { return degree(u, g_); }
    1119             : 
    1120             :     //=========================================================================
    1121             :     // Bidirectional Graph Helper Class
    1122             : 
    1123             :     struct bidir_adj_list_traversal_tag :
    1124             :       public virtual vertex_list_graph_tag,
    1125             :       public virtual incidence_graph_tag,
    1126             :       public virtual adjacency_graph_tag,
    1127             :       public virtual edge_list_graph_tag,
    1128             :       public virtual bidirectional_graph_tag { };
    1129             : 
    1130             :     template <class Config>
    1131             :     struct bidirectional_graph_helper
    1132             :       : public directed_edges_helper<Config> {
    1133             :       typedef bidir_adj_list_traversal_tag traversal_category;
    1134             :     };
    1135             : 
    1136             :     // Had to make these non-members to avoid accidental instantiation
    1137             :     // on SGI MIPSpro C++
    1138             :     template <class C>
    1139             :     inline typename C::InEdgeList&
    1140             :     in_edge_list(bidirectional_graph_helper<C>&,
    1141             :                  typename C::vertex_descriptor v)
    1142             :     {
    1143             :       typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
    1144             :       return sv->m_in_edges;
    1145             :     }
    1146             :     template <class C>
    1147             :     inline const typename C::InEdgeList&
    1148             :     in_edge_list(const bidirectional_graph_helper<C>&,
    1149             :                  typename C::vertex_descriptor v) {
    1150             :       typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
    1151             :       return sv->m_in_edges;
    1152             :     }
    1153             : 
    1154             :     template <class Predicate, class Config>
    1155             :     inline void
    1156             :     remove_edge_if(Predicate pred, bidirectional_graph_helper<Config>& g_)
    1157             :     {
    1158             :       typedef typename Config::global_edgelist_selector EdgeListS;
    1159             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    1160             : 
    1161             :       typedef typename Config::graph_type graph_type;
    1162             :       graph_type& g = static_cast<graph_type&>(g_);
    1163             :       typename Config::edge_iterator ei, ei_end, next;
    1164             :       boost::tie(ei, ei_end) = edges(g);
    1165             :       for (next = ei; ei != ei_end; ei = next) {
    1166             :         ++next;
    1167             :         if (pred(*ei))
    1168             :           remove_edge(*ei, g);
    1169             :       }
    1170             :     }
    1171             : 
    1172             :     template <class Config>
    1173             :     inline std::pair<typename Config::in_edge_iterator,
    1174             :                      typename Config::in_edge_iterator>
    1175           0 :     in_edges(typename Config::vertex_descriptor u,
    1176             :              const bidirectional_graph_helper<Config>& g_)
    1177             :     {
    1178             :       typedef typename Config::graph_type graph_type;
    1179           0 :       const graph_type& cg = static_cast<const graph_type&>(g_);
    1180           0 :       graph_type& g = const_cast<graph_type&>(cg);
    1181             :       typedef typename Config::in_edge_iterator in_edge_iterator;
    1182             :       return
    1183           0 :         std::make_pair(in_edge_iterator(in_edge_list(g, u).begin(), u),
    1184           0 :                        in_edge_iterator(in_edge_list(g, u).end(), u));
    1185             :     }
    1186             : 
    1187             :     // O(1)
    1188             :     template <class Config>
    1189             :     inline std::pair<typename Config::edge_iterator,
    1190             :                      typename Config::edge_iterator>
    1191             :     edges(const bidirectional_graph_helper<Config>& g_)
    1192             :     {
    1193             :       typedef typename Config::graph_type graph_type;
    1194             :       typedef typename Config::edge_iterator edge_iterator;
    1195             :       const graph_type& cg = static_cast<const graph_type&>(g_);
    1196             :       graph_type& g = const_cast<graph_type&>(cg);
    1197             :       return std::make_pair( edge_iterator(g.m_edges.begin()),
    1198             :                              edge_iterator(g.m_edges.end()) );
    1199             :     }
    1200             : 
    1201             :     //=========================================================================
    1202             :     // Bidirectional Graph Helper Class (with edge properties)
    1203             : 
    1204             : 
    1205             :     template <class Config>
    1206             :     struct bidirectional_graph_helper_with_property
    1207             :       : public bidirectional_graph_helper<Config>
    1208             :     {
    1209             :       typedef typename Config::graph_type graph_type;
    1210             :       typedef typename Config::out_edge_iterator out_edge_iterator;
    1211             : 
    1212             :       std::pair<out_edge_iterator, out_edge_iterator>
    1213             :       get_parallel_edge_sublist(typename Config::edge_descriptor e,
    1214             :                                 const graph_type& g,
    1215             :                                 void*)
    1216             :       { return out_edges(source(e, g), g); }
    1217             : 
    1218             :       std::pair<out_edge_iterator, out_edge_iterator>
    1219             :       get_parallel_edge_sublist(typename Config::edge_descriptor e,
    1220             :                                 const graph_type& g,
    1221             :                                 setS*)
    1222             :       { return edge_range(source(e, g), target(e, g), g); }
    1223             : 
    1224             :       std::pair<out_edge_iterator, out_edge_iterator>
    1225             :       get_parallel_edge_sublist(typename Config::edge_descriptor e,
    1226             :                                 const graph_type& g,
    1227             :                                 multisetS*)
    1228             :       { return edge_range(source(e, g), target(e, g), g); }
    1229             : 
    1230             :       std::pair<out_edge_iterator, out_edge_iterator>
    1231             :       get_parallel_edge_sublist(typename Config::edge_descriptor e,
    1232             :                                 const graph_type& g,
    1233             :                                 hash_setS*)
    1234             :       { return edge_range(source(e, g), target(e, g), g); }
    1235             : 
    1236             :       // Placement of these overloaded remove_edge() functions
    1237             :       // inside the class avoids a VC++ bug.
    1238             : 
    1239             :       // O(E/V) or O(log(E/V))
    1240             :       void
    1241             :       remove_edge(typename Config::edge_descriptor e)
    1242             :       {
    1243             :         typedef typename Config::global_edgelist_selector EdgeListS;
    1244             :         BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    1245             : 
    1246             :         graph_type& g = static_cast<graph_type&>(*this);
    1247             : 
    1248             :         typedef typename Config::edgelist_selector OutEdgeListS;
    1249             : 
    1250             :         std::pair<out_edge_iterator, out_edge_iterator> rng =
    1251             :           get_parallel_edge_sublist(e, g, (OutEdgeListS*)(0));
    1252             :         rng.first = std::find(rng.first, rng.second, e);
    1253             :         BOOST_ASSERT(rng.first != rng.second);
    1254             :         remove_edge(rng.first);
    1255             :       }
    1256             : 
    1257             :       inline void
    1258             :       remove_edge(typename Config::out_edge_iterator iter)
    1259             :       {
    1260             :         typedef typename Config::global_edgelist_selector EdgeListS;
    1261             :         BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    1262             : 
    1263             :         typedef typename Config::graph_type graph_type;
    1264             :         graph_type& g = static_cast<graph_type&>(*this);
    1265             :         typename Config::edge_descriptor e = *iter;
    1266             :         typename Config::OutEdgeList& oel = g.out_edge_list(source(e, g));
    1267             :         typename Config::InEdgeList& iel = in_edge_list(g, target(e, g));
    1268             :         typedef typename Config::OutEdgeList::value_type::property_type PType;
    1269             :         PType& p = *(PType*)e.get_property();
    1270             :         detail::remove_directed_edge_dispatch(*iter, iel, p);
    1271             :         g.m_edges.erase(iter.base()->get_iter());
    1272             :         oel.erase(iter.base());
    1273             :       }
    1274             :     };
    1275             : 
    1276             :     // O(E/V) for allow_parallel_edge_tag
    1277             :     // O(log(E/V)) for disallow_parallel_edge_tag
    1278             :     template <class Config>
    1279             :     inline void
    1280             :     remove_edge(typename Config::vertex_descriptor u,
    1281             :                 typename Config::vertex_descriptor v,
    1282             :                 bidirectional_graph_helper_with_property<Config>& g_)
    1283             :     {
    1284             :       typedef typename Config::global_edgelist_selector EdgeListS;
    1285             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    1286             : 
    1287             :       typedef typename Config::graph_type graph_type;
    1288             :       graph_type& g = static_cast<graph_type&>(g_);
    1289             :       typedef typename Config::edge_parallel_category Cat;
    1290             :       detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat());
    1291             :       detail::erase_from_incidence_list(in_edge_list(g, v), u, Cat());
    1292             :     }
    1293             : 
    1294             :     // O(E/V) or O(log(E/V))
    1295             :     template <class EdgeOrIter, class Config>
    1296             :     inline void
    1297             :     remove_edge(EdgeOrIter e,
    1298             :                 bidirectional_graph_helper_with_property<Config>& g_)
    1299             :     {
    1300             :       typedef typename Config::global_edgelist_selector EdgeListS;
    1301             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    1302             : 
    1303             :       g_.remove_edge(e);
    1304             :     }
    1305             : 
    1306             :     template <class Config, class Predicate>
    1307             :     inline void
    1308             :     remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred,
    1309             :                        bidirectional_graph_helper_with_property<Config>& g_)
    1310             :     {
    1311             :       typedef typename Config::global_edgelist_selector EdgeListS;
    1312             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    1313             : 
    1314             :       typedef typename Config::graph_type graph_type;
    1315             :       typedef typename Config::OutEdgeList::value_type::property_type PropT;
    1316             :       graph_type& g = static_cast<graph_type&>(g_);
    1317             : 
    1318             :       typedef typename Config::EdgeIter EdgeIter;
    1319             :       typedef std::vector<EdgeIter> Garbage;
    1320             :       Garbage garbage;
    1321             : 
    1322             :       // First remove the edges from the targets' in-edge lists and
    1323             :       // from the graph's edge set list.
    1324             :       typename Config::out_edge_iterator out_i, out_end;
    1325             :       for (boost::tie(out_i, out_end) = out_edges(u, g); out_i != out_end; ++out_i)
    1326             :         if (pred(*out_i)) {
    1327             :           detail::remove_directed_edge_dispatch
    1328             :             (*out_i, in_edge_list(g, target(*out_i, g)),
    1329             :              *(PropT*)(*out_i).get_property());
    1330             :           // Put in garbage to delete later. Will need the properties
    1331             :           // for the remove_if of the out-edges.
    1332             :           garbage.push_back((*out_i.base()).get_iter());
    1333             :         }
    1334             : 
    1335             :       // Now remove the edges from this out-edge list.
    1336             :       typename Config::out_edge_iterator first, last;
    1337             :       boost::tie(first, last) = out_edges(u, g);
    1338             :       typedef typename Config::edge_parallel_category Cat;
    1339             :       detail::remove_directed_edge_if_dispatch
    1340             :         (first, last, g.out_edge_list(u), pred, Cat());
    1341             : 
    1342             :       // Now delete the edge properties from the g.m_edges list
    1343             :       for (typename Garbage::iterator i = garbage.begin();
    1344             :            i != garbage.end(); ++i)
    1345             :         g.m_edges.erase(*i);
    1346             :     }
    1347             :     template <class Config, class Predicate>
    1348             :     inline void
    1349             :     remove_in_edge_if(typename Config::vertex_descriptor v, Predicate pred,
    1350             :                       bidirectional_graph_helper_with_property<Config>& g_)
    1351             :     {
    1352             :       typedef typename Config::global_edgelist_selector EdgeListS;
    1353             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    1354             : 
    1355             :       typedef typename Config::graph_type graph_type;
    1356             :       typedef typename Config::OutEdgeList::value_type::property_type PropT;
    1357             :       graph_type& g = static_cast<graph_type&>(g_);
    1358             : 
    1359             :       typedef typename Config::EdgeIter EdgeIter;
    1360             :       typedef std::vector<EdgeIter> Garbage;
    1361             :       Garbage garbage;
    1362             : 
    1363             :       // First remove the edges from the sources' out-edge lists and
    1364             :       // from the graph's edge set list.
    1365             :       typename Config::in_edge_iterator in_i, in_end;
    1366             :       for (boost::tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i)
    1367             :         if (pred(*in_i)) {
    1368             :           typename Config::vertex_descriptor u = source(*in_i, g);
    1369             :           detail::remove_directed_edge_dispatch
    1370             :             (*in_i, g.out_edge_list(u), *(PropT*)(*in_i).get_property());
    1371             :           // Put in garbage to delete later. Will need the properties
    1372             :           // for the remove_if of the out-edges.
    1373             :           garbage.push_back((*in_i.base()).get_iter());
    1374             :         }
    1375             :       // Now remove the edges from this in-edge list.
    1376             :       typename Config::in_edge_iterator first, last;
    1377             :       boost::tie(first, last) = in_edges(v, g);
    1378             :       typedef typename Config::edge_parallel_category Cat;
    1379             :       detail::remove_directed_edge_if_dispatch
    1380             :         (first, last, in_edge_list(g, v), pred, Cat());
    1381             : 
    1382             :       // Now delete the edge properties from the g.m_edges list
    1383             :       for (typename Garbage::iterator i = garbage.begin();
    1384             :            i != garbage.end(); ++i)
    1385             :         g.m_edges.erase(*i);
    1386             :     }
    1387             : 
    1388             :     // O(1)
    1389             :     template <class Config>
    1390             :     inline typename Config::edges_size_type
    1391             :     num_edges(const bidirectional_graph_helper_with_property<Config>& g_)
    1392             :     {
    1393             :       typedef typename Config::graph_type graph_type;
    1394             :       const graph_type& g = static_cast<const graph_type&>(g_);
    1395             :       return g.m_edges.size();
    1396             :     }
    1397             :     // O(E/V * E/V) for allow_parallel_edge_tag
    1398             :     // O(E/V * log(E/V)) for disallow_parallel_edge_tag
    1399             :     template <class Config>
    1400             :     inline void
    1401             :     clear_vertex(typename Config::vertex_descriptor u,
    1402             :                  bidirectional_graph_helper_with_property<Config>& g_)
    1403             :     {
    1404             :       typedef typename Config::global_edgelist_selector EdgeListS;
    1405             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    1406             : 
    1407             :       typedef typename Config::graph_type graph_type;
    1408             :       typedef typename Config::edge_parallel_category Cat;
    1409             :       graph_type& g = static_cast<graph_type&>(g_);
    1410             :       typename Config::OutEdgeList& el = g.out_edge_list(u);
    1411             :       typename Config::OutEdgeList::iterator
    1412             :         ei = el.begin(), ei_end = el.end();
    1413             :       for (; ei != ei_end; ++ei) {
    1414             :         detail::erase_from_incidence_list
    1415             :           (in_edge_list(g, (*ei).get_target()), u, Cat());
    1416             :         g.m_edges.erase((*ei).get_iter());
    1417             :       }
    1418             :       typename Config::InEdgeList& in_el = in_edge_list(g, u);
    1419             :       typename Config::InEdgeList::iterator
    1420             :         in_ei = in_el.begin(), in_ei_end = in_el.end();
    1421             :       for (; in_ei != in_ei_end; ++in_ei) {
    1422             :         detail::erase_from_incidence_list
    1423             :           (g.out_edge_list((*in_ei).get_target()), u, Cat());
    1424             :         g.m_edges.erase((*in_ei).get_iter());
    1425             :       }
    1426             :       g.out_edge_list(u).clear();
    1427             :       in_edge_list(g, u).clear();
    1428             :     }
    1429             : 
    1430             :     template <class Config>
    1431             :     inline void
    1432             :     clear_out_edges(typename Config::vertex_descriptor u,
    1433             :                     bidirectional_graph_helper_with_property<Config>& g_)
    1434             :     {
    1435             :       typedef typename Config::global_edgelist_selector EdgeListS;
    1436             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    1437             : 
    1438             :       typedef typename Config::graph_type graph_type;
    1439             :       typedef typename Config::edge_parallel_category Cat;
    1440             :       graph_type& g = static_cast<graph_type&>(g_);
    1441             :       typename Config::OutEdgeList& el = g.out_edge_list(u);
    1442             :       typename Config::OutEdgeList::iterator
    1443             :         ei = el.begin(), ei_end = el.end();
    1444             :       for (; ei != ei_end; ++ei) {
    1445             :         detail::erase_from_incidence_list
    1446             :           (in_edge_list(g, (*ei).get_target()), u, Cat());
    1447             :         g.m_edges.erase((*ei).get_iter());
    1448             :       }
    1449             :       g.out_edge_list(u).clear();
    1450             :     }
    1451             : 
    1452             :     template <class Config>
    1453             :     inline void
    1454             :     clear_in_edges(typename Config::vertex_descriptor u,
    1455             :                    bidirectional_graph_helper_with_property<Config>& g_)
    1456             :     {
    1457             :       typedef typename Config::global_edgelist_selector EdgeListS;
    1458             :       BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    1459             : 
    1460             :       typedef typename Config::graph_type graph_type;
    1461             :       typedef typename Config::edge_parallel_category Cat;
    1462             :       graph_type& g = static_cast<graph_type&>(g_);
    1463             :       typename Config::InEdgeList& in_el = in_edge_list(g, u);
    1464             :       typename Config::InEdgeList::iterator
    1465             :         in_ei = in_el.begin(), in_ei_end = in_el.end();
    1466             :       for (; in_ei != in_ei_end; ++in_ei) {
    1467             :         detail::erase_from_incidence_list
    1468             :           (g.out_edge_list((*in_ei).get_target()), u, Cat());
    1469             :         g.m_edges.erase((*in_ei).get_iter());
    1470             :       }
    1471             :       in_edge_list(g, u).clear();
    1472             :     }
    1473             : 
    1474             :     // O(1) for allow_parallel_edge_tag
    1475             :     // O(log(E/V)) for disallow_parallel_edge_tag
    1476             :     template <class Config>
    1477             :     inline std::pair<typename Config::edge_descriptor, bool>
    1478           0 :     add_edge(typename Config::vertex_descriptor u,
    1479             :              typename Config::vertex_descriptor v,
    1480             :              const typename Config::edge_property_type& p,
    1481             :              bidirectional_graph_helper_with_property<Config>& g_)
    1482             :     {
    1483             :       typedef typename Config::graph_type graph_type;
    1484           0 :       graph_type& g = static_cast<graph_type&>(g_);
    1485             :       typedef typename Config::edge_descriptor edge_descriptor;
    1486             :       typedef typename Config::StoredEdge StoredEdge;
    1487             :       bool inserted;
    1488           0 :       typename Config::EdgeContainer::value_type e(u, v, p);
    1489           0 :       typename Config::EdgeContainer::iterator p_iter
    1490           0 :         = graph_detail::push(g.m_edges, e).first;
    1491           0 :       typename Config::OutEdgeList::iterator i;
    1492           0 :       boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u),
    1493           0 :                                         StoredEdge(v, p_iter, &g.m_edges));
    1494             :       if (inserted) {
    1495           0 :         boost::graph_detail::push(in_edge_list(g, v), StoredEdge(u, p_iter, &g.m_edges));
    1496           0 :         return std::make_pair(edge_descriptor(u, v, &p_iter->m_property),
    1497             :                               true);
    1498             :       } else {
    1499             :         g.m_edges.erase(p_iter);
    1500             :         return std::make_pair(edge_descriptor(u, v,
    1501             :                                      &i->get_iter()->get_property()),
    1502             :                               false);
    1503             :       }
    1504             :     }
    1505             : 
    1506             :     template <class Config>
    1507             :     inline std::pair<typename Config::edge_descriptor, bool>
    1508             :     add_edge(typename Config::vertex_descriptor u,
    1509             :              typename Config::vertex_descriptor v,
    1510             :              bidirectional_graph_helper_with_property<Config>& g_)
    1511             :     {
    1512             :       typename Config::edge_property_type p;
    1513             :       return add_edge(u, v, p, g_);
    1514             :     }
    1515             :     // O(1)
    1516             :     template <class Config>
    1517             :     inline typename Config::degree_size_type
    1518             :     degree(typename Config::vertex_descriptor u,
    1519             :            const bidirectional_graph_helper_with_property<Config>& g_)
    1520             :     {
    1521             :       typedef typename Config::graph_type graph_type;
    1522             :       const graph_type& g = static_cast<const graph_type&>(g_);
    1523             :       return in_degree(u, g) + out_degree(u, g);
    1524             :     }
    1525             : 
    1526             :     //=========================================================================
    1527             :     // Adjacency List Helper Class
    1528             : 
    1529             :     template <class Config, class Base>
    1530             :     struct adj_list_helper : public Base
    1531             :     {
    1532             :       typedef typename Config::graph_type AdjList;
    1533             :       typedef typename Config::vertex_descriptor vertex_descriptor;
    1534             :       typedef typename Config::edge_descriptor edge_descriptor;
    1535             :       typedef typename Config::out_edge_iterator out_edge_iterator;
    1536             :       typedef typename Config::in_edge_iterator in_edge_iterator;
    1537             :       typedef typename Config::adjacency_iterator adjacency_iterator;
    1538             :       typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator;
    1539             :       typedef typename Config::vertex_iterator vertex_iterator;
    1540             :       typedef typename Config::edge_iterator edge_iterator;
    1541             :       typedef typename Config::directed_category directed_category;
    1542             :       typedef typename Config::edge_parallel_category edge_parallel_category;
    1543             :       typedef typename Config::vertices_size_type vertices_size_type;
    1544             :       typedef typename Config::edges_size_type edges_size_type;
    1545             :       typedef typename Config::degree_size_type degree_size_type;
    1546             :       typedef typename Config::StoredEdge StoredEdge;
    1547             :       typedef typename Config::vertex_property_type vertex_property_type;
    1548             :       typedef typename Config::edge_property_type edge_property_type;
    1549             :       typedef typename Config::graph_property_type graph_property_type;
    1550             : 
    1551             :       typedef typename Config::global_edgelist_selector
    1552             :         global_edgelist_selector;
    1553             : 
    1554             :       typedef typename lookup_one_property<vertex_property_type, vertex_bundle_t>::type vertex_bundled;
    1555             :       typedef typename lookup_one_property<edge_property_type, edge_bundle_t>::type edge_bundled;
    1556             :       typedef typename lookup_one_property<graph_property_type, graph_bundle_t>::type graph_bundled;
    1557             :     };
    1558             : 
    1559             :     template <class Config, class Base>
    1560             :     inline std::pair<typename Config::adjacency_iterator,
    1561             :                      typename Config::adjacency_iterator>
    1562           0 :     adjacent_vertices(typename Config::vertex_descriptor u,
    1563             :                       const adj_list_helper<Config, Base>& g_)
    1564             :     {
    1565             :       typedef typename Config::graph_type AdjList;
    1566           0 :       const AdjList& cg = static_cast<const AdjList&>(g_);
    1567           0 :       AdjList& g = const_cast<AdjList&>(cg);
    1568             :       typedef typename Config::adjacency_iterator adjacency_iterator;
    1569           0 :       typename Config::out_edge_iterator first, last;
    1570           0 :       boost::tie(first, last) = out_edges(u, g);
    1571           0 :       return std::make_pair(adjacency_iterator(first, &g),
    1572           0 :                             adjacency_iterator(last, &g));
    1573             :     }
    1574             :     template <class Config, class Base>
    1575             :     inline std::pair<typename Config::inv_adjacency_iterator,
    1576             :                      typename Config::inv_adjacency_iterator>
    1577             :     inv_adjacent_vertices(typename Config::vertex_descriptor u,
    1578             :                           const adj_list_helper<Config, Base>& g_)
    1579             :     {
    1580             :       typedef typename Config::graph_type AdjList;
    1581             :       const AdjList& cg = static_cast<const AdjList&>(g_);
    1582             :       AdjList& g = const_cast<AdjList&>(cg);
    1583             :       typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator;
    1584             :       typename Config::in_edge_iterator first, last;
    1585             :       boost::tie(first, last) = in_edges(u, g);
    1586             :       return std::make_pair(inv_adjacency_iterator(first, &g),
    1587             :                             inv_adjacency_iterator(last, &g));
    1588             :     }
    1589             :     template <class Config, class Base>
    1590             :     inline std::pair<typename Config::out_edge_iterator,
    1591             :                      typename Config::out_edge_iterator>
    1592           0 :     out_edges(typename Config::vertex_descriptor u,
    1593             :               const adj_list_helper<Config, Base>& g_)
    1594             :     {
    1595             :       typedef typename Config::graph_type AdjList;
    1596             :       typedef typename Config::out_edge_iterator out_edge_iterator;
    1597           0 :       const AdjList& cg = static_cast<const AdjList&>(g_);
    1598           0 :       AdjList& g = const_cast<AdjList&>(cg);
    1599             :       return
    1600           0 :         std::make_pair(out_edge_iterator(g.out_edge_list(u).begin(), u),
    1601           0 :                        out_edge_iterator(g.out_edge_list(u).end(), u));
    1602             :     }
    1603             :     template <class Config, class Base>
    1604             :     inline std::pair<typename Config::vertex_iterator,
    1605             :                      typename Config::vertex_iterator>
    1606           0 :     vertices(const adj_list_helper<Config, Base>& g_)
    1607             :     {
    1608             :       typedef typename Config::graph_type AdjList;
    1609           0 :       const AdjList& cg = static_cast<const AdjList&>(g_);
    1610           0 :       AdjList& g = const_cast<AdjList&>(cg);
    1611           0 :       return std::make_pair( g.vertex_set().begin(), g.vertex_set().end() );
    1612             :     }
    1613             :     template <class Config, class Base>
    1614             :     inline typename Config::vertices_size_type
    1615           0 :     num_vertices(const adj_list_helper<Config, Base>& g_)
    1616             :     {
    1617             :       typedef typename Config::graph_type AdjList;
    1618           0 :       const AdjList& g = static_cast<const AdjList&>(g_);
    1619           0 :       return g.vertex_set().size();
    1620             :     }
    1621             :     template <class Config, class Base>
    1622             :     inline typename Config::degree_size_type
    1623           0 :     out_degree(typename Config::vertex_descriptor u,
    1624             :                const adj_list_helper<Config, Base>& g_)
    1625             :     {
    1626             :       typedef typename Config::graph_type AdjList;
    1627           0 :       const AdjList& g = static_cast<const AdjList&>(g_);
    1628           0 :       return g.out_edge_list(u).size();
    1629             :     }
    1630             :     template <class Config, class Base>
    1631             :     inline std::pair<typename Config::edge_descriptor, bool>
    1632             :     edge(typename Config::vertex_descriptor u,
    1633             :          typename Config::vertex_descriptor v,
    1634             :          const adj_list_helper<Config, Base>& g_)
    1635             :     {
    1636             :       typedef typename Config::graph_type Graph;
    1637             :       typedef typename Config::StoredEdge StoredEdge;
    1638             :       const Graph& cg = static_cast<const Graph&>(g_);
    1639             :       const typename Config::OutEdgeList& el = cg.out_edge_list(u);
    1640             :       typename Config::OutEdgeList::const_iterator it = graph_detail::
    1641             :         find(el, StoredEdge(v));
    1642             :       return std::make_pair(
    1643             :                typename Config::edge_descriptor
    1644             :                      (u, v, (it == el.end() ? 0 : &(*it).get_property())),
    1645             :                (it != el.end()));
    1646             :     }
    1647             : 
    1648             :     template <class Config, class Base>
    1649             :     inline std::pair<typename Config::out_edge_iterator,
    1650             :                      typename Config::out_edge_iterator>
    1651             :     edge_range(typename Config::vertex_descriptor u,
    1652             :                typename Config::vertex_descriptor v,
    1653             :                const adj_list_helper<Config, Base>& g_)
    1654             :     {
    1655             :       typedef typename Config::graph_type Graph;
    1656             :       typedef typename Config::StoredEdge StoredEdge;
    1657             :       const Graph& cg = static_cast<const Graph&>(g_);
    1658             :       Graph& g = const_cast<Graph&>(cg);
    1659             :       typedef typename Config::out_edge_iterator out_edge_iterator;
    1660             :       typename Config::OutEdgeList& el = g.out_edge_list(u);
    1661             :       typename Config::OutEdgeList::iterator first, last;
    1662             :       typename Config::EdgeContainer fake_edge_container;
    1663             :       boost::tie(first, last) = graph_detail::
    1664             :         equal_range(el, StoredEdge(v));
    1665             :       return std::make_pair(out_edge_iterator(first, u),
    1666             :                             out_edge_iterator(last, u));
    1667             :     }
    1668             : 
    1669             :     template <class Config>
    1670             :     inline typename Config::degree_size_type
    1671             :     in_degree(typename Config::vertex_descriptor u,
    1672             :               const directed_edges_helper<Config>& g_)
    1673             :     {
    1674             :       typedef typename Config::graph_type Graph;
    1675             :       const Graph& cg = static_cast<const Graph&>(g_);
    1676             :       Graph& g = const_cast<Graph&>(cg);
    1677             :       return in_edge_list(g, u).size();
    1678             :     }
    1679             : 
    1680             :     namespace detail {
    1681             :       template <class Config, class Base, class Property>
    1682             :       inline
    1683             :       typename boost::property_map<typename Config::graph_type,
    1684             :         Property>::type
    1685           0 :       get_dispatch(adj_list_helper<Config,Base>&, Property p,
    1686             :                    boost::edge_property_tag) {
    1687             :         typedef typename Config::graph_type Graph;
    1688             :         typedef typename boost::property_map<Graph, Property>::type PA;
    1689           0 :         return PA(p);
    1690             :       }
    1691             :       template <class Config, class Base, class Property>
    1692             :       inline
    1693             :       typename boost::property_map<typename Config::graph_type,
    1694             :         Property>::const_type
    1695           0 :       get_dispatch(const adj_list_helper<Config,Base>&, Property p,
    1696             :                    boost::edge_property_tag) {
    1697             :         typedef typename Config::graph_type Graph;
    1698             :         typedef typename boost::property_map<Graph, Property>::const_type PA;
    1699           0 :         return PA(p);
    1700             :       }
    1701             : 
    1702             :       template <class Config, class Base, class Property>
    1703             :       inline
    1704             :       typename boost::property_map<typename Config::graph_type,
    1705             :         Property>::type
    1706           0 :       get_dispatch(adj_list_helper<Config,Base>& g, Property p,
    1707             :                    boost::vertex_property_tag) {
    1708             :         typedef typename Config::graph_type Graph;
    1709             :         typedef typename boost::property_map<Graph, Property>::type PA;
    1710           0 :         return PA(&static_cast<Graph&>(g), p);
    1711             :       }
    1712             :       template <class Config, class Base, class Property>
    1713             :       inline
    1714             :       typename boost::property_map<typename Config::graph_type,
    1715             :         Property>::const_type
    1716           0 :       get_dispatch(const adj_list_helper<Config, Base>& g, Property p,
    1717             :                    boost::vertex_property_tag) {
    1718             :         typedef typename Config::graph_type Graph;
    1719             :         typedef typename boost::property_map<Graph, Property>::const_type PA;
    1720           0 :         const Graph& cg = static_cast<const Graph&>(g);
    1721           0 :         return PA(&cg, p);
    1722             :       }
    1723             : 
    1724             :     } // namespace detail
    1725             : 
    1726             :     // Implementation of the PropertyGraph interface
    1727             :     template <class Config, class Base, class Property>
    1728             :     inline
    1729             :     typename boost::property_map<typename Config::graph_type, Property>::type
    1730           0 :     get(Property p, adj_list_helper<Config, Base>& g) {
    1731             :       typedef typename detail::property_kind_from_graph<adj_list_helper<Config, Base>, Property>::type Kind;
    1732           0 :       return detail::get_dispatch(g, p, Kind());
    1733             :     }
    1734             :     template <class Config, class Base, class Property>
    1735             :     inline
    1736             :     typename boost::property_map<typename Config::graph_type,
    1737             :       Property>::const_type
    1738           0 :     get(Property p, const adj_list_helper<Config, Base>& g) {
    1739             :       typedef typename detail::property_kind_from_graph<adj_list_helper<Config, Base>, Property>::type Kind;
    1740           0 :       return detail::get_dispatch(g, p, Kind());
    1741             :     }
    1742             : 
    1743             :     template <class Config, class Base, class Property, class Key>
    1744             :     inline
    1745             :     typename boost::property_traits<
    1746             :       typename boost::property_map<typename Config::graph_type,
    1747             :         Property>::type
    1748             :     >::reference
    1749             :     get(Property p, adj_list_helper<Config, Base>& g, const Key& key) {
    1750             :       return get(get(p, g), key);
    1751             :     }
    1752             : 
    1753             :     template <class Config, class Base, class Property, class Key>
    1754             :     inline
    1755             :     typename boost::property_traits<
    1756             :       typename boost::property_map<typename Config::graph_type,
    1757             :         Property>::const_type
    1758             :     >::reference
    1759             :     get(Property p, const adj_list_helper<Config, Base>& g, const Key& key) {
    1760             :       return get(get(p, g), key);
    1761             :     }
    1762             : 
    1763             :     template <class Config, class Base, class Property, class Key,class Value>
    1764             :     inline void
    1765             :     put(Property p, adj_list_helper<Config, Base>& g,
    1766             :         const Key& key, const Value& value)
    1767             :     {
    1768             :       typedef typename Config::graph_type Graph;
    1769             :       typedef typename boost::property_map<Graph, Property>::type Map;
    1770             :       Map pmap = get(p, static_cast<Graph&>(g));
    1771             :       put(pmap, key, value);
    1772             :     }
    1773             : 
    1774             : 
    1775             :     //=========================================================================
    1776             :     // Generalize Adjacency List Implementation
    1777             : 
    1778             :     struct adj_list_tag { };
    1779             : 
    1780             :     template <class Derived, class Config, class Base>
    1781             :     class adj_list_impl
    1782             :       : public adj_list_helper<Config, Base>
    1783             :     {
    1784             :       typedef typename Config::OutEdgeList OutEdgeList;
    1785             :       typedef typename Config::InEdgeList InEdgeList;
    1786             :       typedef typename Config::StoredVertexList StoredVertexList;
    1787             :     public:
    1788             :       typedef typename Config::stored_vertex stored_vertex;
    1789             :       typedef typename Config::EdgeContainer EdgeContainer;
    1790             :       typedef typename Config::vertex_descriptor vertex_descriptor;
    1791             :       typedef typename Config::edge_descriptor edge_descriptor;
    1792             :       typedef typename Config::vertex_iterator vertex_iterator;
    1793             :       typedef typename Config::edge_iterator edge_iterator;
    1794             :       typedef typename Config::edge_parallel_category edge_parallel_category;
    1795             :       typedef typename Config::vertices_size_type vertices_size_type;
    1796             :       typedef typename Config::edges_size_type edges_size_type;
    1797             :       typedef typename Config::degree_size_type degree_size_type;
    1798             :       typedef typename Config::edge_property_type edge_property_type;
    1799             :       typedef adj_list_tag graph_tag;
    1800             : 
    1801             :       static vertex_descriptor null_vertex()
    1802             :       {
    1803             :         return 0;
    1804             :       }
    1805             : 
    1806             :       inline adj_list_impl() { }
    1807             : 
    1808             :       inline adj_list_impl(const adj_list_impl& x) {
    1809             :         copy_impl(x);
    1810             :       }
    1811             :       inline adj_list_impl& operator=(const adj_list_impl& x) {
    1812             :         this->clear();
    1813             :         copy_impl(x);
    1814             :         return *this;
    1815             :       }
    1816             :       inline void clear() {
    1817             :         for (typename StoredVertexList::iterator i = m_vertices.begin();
    1818             :              i != m_vertices.end(); ++i)
    1819             :           delete (stored_vertex*)*i;
    1820             :         m_vertices.clear();
    1821             :         m_edges.clear();
    1822             :       }
    1823             :       inline adj_list_impl(vertices_size_type num_vertices) {
    1824             :         for (vertices_size_type i = 0; i < num_vertices; ++i)
    1825             :           add_vertex(static_cast<Derived&>(*this));
    1826             :       }
    1827             :       template <class EdgeIterator>
    1828             :       inline adj_list_impl(vertices_size_type num_vertices,
    1829             :                            EdgeIterator first, EdgeIterator last)
    1830             :       {
    1831             :         vertex_descriptor* v = new vertex_descriptor[num_vertices];
    1832             :         for (vertices_size_type i = 0; i < num_vertices; ++i)
    1833             :           v[i] = add_vertex(static_cast<Derived&>(*this));
    1834             : 
    1835             :         while (first != last) {
    1836             :           add_edge(v[(*first).first], v[(*first).second], *this);
    1837             :           ++first;
    1838             :         }
    1839             :         delete [] v;
    1840             :       }
    1841             :       template <class EdgeIterator, class EdgePropertyIterator>
    1842             :       inline adj_list_impl(vertices_size_type num_vertices,
    1843             :                            EdgeIterator first, EdgeIterator last,
    1844             :                            EdgePropertyIterator ep_iter)
    1845             :       {
    1846             :         vertex_descriptor* v = new vertex_descriptor[num_vertices];
    1847             :         for (vertices_size_type i = 0; i < num_vertices; ++i)
    1848             :           v[i] = add_vertex(static_cast<Derived&>(*this));
    1849             : 
    1850             :         while (first != last) {
    1851             :           add_edge(v[(*first).first], v[(*first).second], *ep_iter, *this);
    1852             :           ++first;
    1853             :           ++ep_iter;
    1854             :         }
    1855             :         delete [] v;
    1856             :       }
    1857             :       ~adj_list_impl() {
    1858             :         for (typename StoredVertexList::iterator i = m_vertices.begin();
    1859             :              i != m_vertices.end(); ++i)
    1860             :           delete (stored_vertex*)*i;
    1861             :       }
    1862             :       //    protected:
    1863             :       inline OutEdgeList& out_edge_list(vertex_descriptor v) {
    1864             :         stored_vertex* sv = (stored_vertex*)v;
    1865             :         return sv->m_out_edges;
    1866             :       }
    1867             :       inline const OutEdgeList& out_edge_list(vertex_descriptor v) const {
    1868             :         stored_vertex* sv = (stored_vertex*)v;
    1869             :         return sv->m_out_edges;
    1870             :       }
    1871             :       inline StoredVertexList& vertex_set() { return m_vertices; }
    1872             :       inline const StoredVertexList& vertex_set() const { return m_vertices; }
    1873             : 
    1874             :       inline void copy_impl(const adj_list_impl& x_)
    1875             :       {
    1876             :         const Derived& x = static_cast<const Derived&>(x_);
    1877             : 
    1878             :         // Would be better to have a constant time way to get from
    1879             :         // vertices in x to the corresponding vertices in *this.
    1880             :         std::map<stored_vertex*,stored_vertex*> vertex_map;
    1881             : 
    1882             :         // Copy the stored vertex objects by adding each vertex
    1883             :         // and copying its property object.
    1884             :         vertex_iterator vi, vi_end;
    1885             :         for (boost::tie(vi, vi_end) = vertices(x); vi != vi_end; ++vi) {
    1886             :           stored_vertex* v = (stored_vertex*)add_vertex(*this);
    1887             :           v->m_property = ((stored_vertex*)*vi)->m_property;
    1888             :           vertex_map[(stored_vertex*)*vi] = v;
    1889             :         }
    1890             :         // Copy the edges by adding each edge and copying its
    1891             :         // property object.
    1892             :         edge_iterator ei, ei_end;
    1893             :         for (boost::tie(ei, ei_end) = edges(x); ei != ei_end; ++ei) {
    1894             :           edge_descriptor e;
    1895             :           bool inserted;
    1896             :           vertex_descriptor s = source(*ei,x), t = target(*ei,x);
    1897             :           boost::tie(e, inserted) = add_edge(vertex_map[(stored_vertex*)s],
    1898             :                                              vertex_map[(stored_vertex*)t], *this);
    1899             :           *((edge_property_type*)e.m_eproperty)
    1900             :             = *((edge_property_type*)(*ei).m_eproperty);
    1901             :         }
    1902             :       }
    1903             : 
    1904             : 
    1905             :       typename Config::EdgeContainer m_edges;
    1906             :       StoredVertexList m_vertices;
    1907             :     };
    1908             : 
    1909             :     // O(1)
    1910             :     template <class Derived, class Config, class Base>
    1911             :     inline typename Config::vertex_descriptor
    1912             :     add_vertex(adj_list_impl<Derived, Config, Base>& g_)
    1913             :     {
    1914             :       Derived& g = static_cast<Derived&>(g_);
    1915             :       typedef typename Config::stored_vertex stored_vertex;
    1916             :       stored_vertex* v = new stored_vertex;
    1917             :       typename Config::StoredVertexList::iterator pos;
    1918             :       bool inserted;
    1919             :       boost::tie(pos,inserted) = boost::graph_detail::push(g.m_vertices, v);
    1920             :       v->m_position = pos;
    1921             :       g.added_vertex(v);
    1922             :       return v;
    1923             :     }
    1924             :     // O(1)
    1925             :     template <class Derived, class Config, class Base>
    1926             :     inline typename Config::vertex_descriptor
    1927             :     add_vertex(const typename Config::vertex_property_type& p,
    1928             :                adj_list_impl<Derived, Config, Base>& g_)
    1929             :     {
    1930             :       typedef typename Config::vertex_descriptor vertex_descriptor;
    1931             :       Derived& g = static_cast<Derived&>(g_);
    1932             :       if (optional<vertex_descriptor> v
    1933             :             = g.vertex_by_property(get_property_value(p, vertex_bundle)))
    1934             :         return *v;
    1935             : 
    1936             :       typedef typename Config::stored_vertex stored_vertex;
    1937             :       stored_vertex* v = new stored_vertex(p);
    1938             :       typename Config::StoredVertexList::iterator pos;
    1939             :       bool inserted;
    1940             :       boost::tie(pos,inserted) = boost::graph_detail::push(g.m_vertices, v);
    1941             :       v->m_position = pos;
    1942             :       g.added_vertex(v);
    1943             :       return v;
    1944             :     }
    1945             :     // O(1)
    1946             :     template <class Derived, class Config, class Base>
    1947             :     inline void remove_vertex(typename Config::vertex_descriptor u,
    1948             :                               adj_list_impl<Derived, Config, Base>& g_)
    1949             :     {
    1950             :       typedef typename Config::stored_vertex stored_vertex;
    1951             :       Derived& g = static_cast<Derived&>(g_);
    1952             :       g.removing_vertex(u, boost::graph_detail::iterator_stability(g_.m_vertices));
    1953             :       stored_vertex* su = (stored_vertex*)u;
    1954             :       g.m_vertices.erase(su->m_position);
    1955             :       delete su;
    1956             :     }
    1957             :     // O(V)
    1958             :     template <class Derived, class Config, class Base>
    1959             :     inline typename Config::vertex_descriptor
    1960             :     vertex(typename Config::vertices_size_type n,
    1961             :            const adj_list_impl<Derived, Config, Base>& g_)
    1962             :     {
    1963             :       const Derived& g = static_cast<const Derived&>(g_);
    1964             :       typename Config::vertex_iterator i = vertices(g).first;
    1965             :       while (n--) ++i; // std::advance(i, n); (not VC++ portable)
    1966             :       return *i;
    1967             :     }
    1968             : 
    1969             :     //=========================================================================
    1970             :     // Vector-Backbone Adjacency List Implementation
    1971             : 
    1972             :     namespace detail {
    1973             : 
    1974             :       template <class Graph, class vertex_descriptor>
    1975             :       inline void
    1976             :       remove_vertex_dispatch(Graph& g, vertex_descriptor u,
    1977             :                              boost::directed_tag)
    1978             :       {
    1979             :         typedef typename Graph::edge_parallel_category edge_parallel_category;
    1980             :         g.m_vertices.erase(g.m_vertices.begin() + u);
    1981             :         vertex_descriptor V = num_vertices(g);
    1982             :         if (u != V) {
    1983             :           for (vertex_descriptor v = 0; v < V; ++v)
    1984             :             reindex_edge_list(g.out_edge_list(v), u, edge_parallel_category());
    1985             :         }
    1986             :       }
    1987             : 
    1988             :       template <class Graph, class vertex_descriptor>
    1989             :       inline void
    1990             :       remove_vertex_dispatch(Graph& g, vertex_descriptor u,
    1991             :                              boost::undirected_tag)
    1992             :       {
    1993             :         typedef typename Graph::global_edgelist_selector EdgeListS;
    1994             :         BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    1995             : 
    1996             :         typedef typename Graph::edge_parallel_category edge_parallel_category;
    1997             :         g.m_vertices.erase(g.m_vertices.begin() + u);
    1998             :         vertex_descriptor V = num_vertices(g);
    1999             :         for (vertex_descriptor v = 0; v < V; ++v)
    2000             :           reindex_edge_list(g.out_edge_list(v), u,
    2001             :                             edge_parallel_category());
    2002             :         typedef typename Graph::EdgeContainer Container;
    2003             :         typedef typename Container::iterator Iter;
    2004             :         Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end();
    2005             :         for (; ei != ei_end; ++ei) {
    2006             :           if (ei->m_source > u)
    2007             :             --ei->m_source;
    2008             :           if (ei->m_target > u)
    2009             :             --ei->m_target;
    2010             :         }
    2011             :       }
    2012             :       template <class Graph, class vertex_descriptor>
    2013             :       inline void
    2014             :       remove_vertex_dispatch(Graph& g, vertex_descriptor u,
    2015             :                              boost::bidirectional_tag)
    2016             :       {
    2017             :         typedef typename Graph::global_edgelist_selector EdgeListS;
    2018             :         BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
    2019             : 
    2020             :         typedef typename Graph::edge_parallel_category edge_parallel_category;
    2021             :         g.m_vertices.erase(g.m_vertices.begin() + u);
    2022             :         vertex_descriptor V = num_vertices(g);
    2023             :         vertex_descriptor v;
    2024             :         if (u != V) {
    2025             :           for (v = 0; v < V; ++v)
    2026             :             reindex_edge_list(g.out_edge_list(v), u,
    2027             :                               edge_parallel_category());
    2028             :           for (v = 0; v < V; ++v)
    2029             :             reindex_edge_list(in_edge_list(g, v), u,
    2030             :                               edge_parallel_category());
    2031             : 
    2032             :           typedef typename Graph::EdgeContainer Container;
    2033             :           typedef typename Container::iterator Iter;
    2034             :           Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end();
    2035             :           for (; ei != ei_end; ++ei) {
    2036             :             if (ei->m_source > u)
    2037             :               --ei->m_source;
    2038             :             if (ei->m_target > u)
    2039             :               --ei->m_target;
    2040             :           }
    2041             :         }
    2042             :       }
    2043             : 
    2044             :       template <class EdgeList, class vertex_descriptor>
    2045             :       inline void
    2046             :       reindex_edge_list(EdgeList& el, vertex_descriptor u,
    2047             :                         boost::allow_parallel_edge_tag)
    2048             :       {
    2049             :         typename EdgeList::iterator ei = el.begin(), e_end = el.end();
    2050             :         for (; ei != e_end; ++ei)
    2051             :           if ((*ei).get_target() > u)
    2052             :             --(*ei).get_target();
    2053             :       }
    2054             : 
    2055             :       template <class EdgeList, class vertex_descriptor>
    2056             :       inline void
    2057             :       reindex_edge_list(EdgeList& el, vertex_descriptor u,
    2058             :                         boost::disallow_parallel_edge_tag)
    2059             :       {
    2060             :         for(typename EdgeList::iterator ei = el.begin(); ei != el.end(); ++ei) {
    2061             :           if (ei->get_target() > u) {
    2062             :             typename EdgeList::value_type ce = *ei;
    2063             :             el.erase(ce);
    2064             :             --ce.get_target();
    2065             :             el.insert(ce);
    2066             :           }
    2067             :         }
    2068             :       }
    2069             :     } // namespace detail
    2070             : 
    2071             :     struct vec_adj_list_tag { };
    2072             : 
    2073             :     template <class Graph, class Config, class Base>
    2074           0 :     class vec_adj_list_impl
    2075             :       : public adj_list_helper<Config, Base>
    2076             :     {
    2077             :       typedef typename Config::OutEdgeList OutEdgeList;
    2078             :       typedef typename Config::InEdgeList InEdgeList;
    2079             :       typedef typename Config::StoredVertexList StoredVertexList;
    2080             :     public:
    2081             :       typedef typename Config::vertex_descriptor vertex_descriptor;
    2082             :       typedef typename Config::edge_descriptor edge_descriptor;
    2083             :       typedef typename Config::out_edge_iterator out_edge_iterator;
    2084             :       typedef typename Config::edge_iterator edge_iterator;
    2085             :       typedef typename Config::directed_category directed_category;
    2086             :       typedef typename Config::vertices_size_type vertices_size_type;
    2087             :       typedef typename Config::edges_size_type edges_size_type;
    2088             :       typedef typename Config::degree_size_type degree_size_type;
    2089             :       typedef typename Config::StoredEdge StoredEdge;
    2090             :       typedef typename Config::stored_vertex stored_vertex;
    2091             :       typedef typename Config::EdgeContainer EdgeContainer;
    2092             :       typedef typename Config::edge_property_type edge_property_type;
    2093             :       typedef vec_adj_list_tag graph_tag;
    2094             : 
    2095           0 :       static vertex_descriptor null_vertex()
    2096             :       {
    2097             :         return (std::numeric_limits<vertex_descriptor>::max)();
    2098             :       }
    2099             : 
    2100           0 :       inline vec_adj_list_impl() { }
    2101             : 
    2102             :       inline vec_adj_list_impl(const vec_adj_list_impl& x) {
    2103             :         copy_impl(x);
    2104             :       }
    2105           0 :       inline vec_adj_list_impl& operator=(const vec_adj_list_impl& x) {
    2106           0 :         this->clear();
    2107           0 :         copy_impl(x);
    2108             :         return *this;
    2109             :       }
    2110           0 :       inline void clear() {
    2111           0 :         m_vertices.clear();
    2112           0 :         m_edges.clear();
    2113           0 :       }
    2114             : 
    2115           0 :       inline vec_adj_list_impl(vertices_size_type _num_vertices)
    2116           0 :         : m_vertices(_num_vertices) { }
    2117             : 
    2118             :       template <class EdgeIterator>
    2119             :       inline vec_adj_list_impl(vertices_size_type num_vertices,
    2120             :                                EdgeIterator first, EdgeIterator last)
    2121             :         : m_vertices(num_vertices)
    2122             :       {
    2123             :         while (first != last) {
    2124             :           add_edge((*first).first, (*first).second,
    2125             :                    static_cast<Graph&>(*this));
    2126             :           ++first;
    2127             :         }
    2128             :       }
    2129             :       template <class EdgeIterator, class EdgePropertyIterator>
    2130             :       inline vec_adj_list_impl(vertices_size_type num_vertices,
    2131             :                                EdgeIterator first, EdgeIterator last,
    2132             :                                EdgePropertyIterator ep_iter)
    2133             :         : m_vertices(num_vertices)
    2134             :       {
    2135             :         while (first != last) {
    2136             :           add_edge((*first).first, (*first).second, *ep_iter,
    2137             :                    static_cast<Graph&>(*this));
    2138             :           ++first;
    2139             :           ++ep_iter;
    2140             :         }
    2141             :       }
    2142             : 
    2143             :       //    protected:
    2144           0 :       inline boost::integer_range<vertex_descriptor> vertex_set() const {
    2145           0 :         return boost::integer_range<vertex_descriptor>(0, m_vertices.size());
    2146             :       }
    2147           0 :       inline OutEdgeList& out_edge_list(vertex_descriptor v) {
    2148           0 :         return m_vertices[v].m_out_edges;
    2149             :       }
    2150           0 :       inline const OutEdgeList& out_edge_list(vertex_descriptor v) const {
    2151           0 :         return m_vertices[v].m_out_edges;
    2152             :       }
    2153           0 :       inline void copy_impl(const vec_adj_list_impl& x_)
    2154             :       {
    2155           0 :         const Graph& x = static_cast<const Graph&>(x_);
    2156             :         // Copy the stored vertex objects by adding each vertex
    2157             :         // and copying its property object.
    2158           0 :         for (vertices_size_type i = 0; i < num_vertices(x); ++i) {
    2159           0 :           vertex_descriptor v = add_vertex(*this);
    2160           0 :           m_vertices[v].m_property = x.m_vertices[i].m_property;
    2161             :         }
    2162             :         // Copy the edges by adding each edge and copying its
    2163             :         // property object.
    2164           0 :         edge_iterator ei, ei_end;
    2165           0 :         for (boost::tie(ei, ei_end) = edges(x); ei != ei_end; ++ei) {
    2166           0 :           edge_descriptor e;
    2167             :           bool inserted;
    2168           0 :           boost::tie(e, inserted) = add_edge(source(*ei,x), target(*ei,x) , *this);
    2169           0 :           *((edge_property_type*)e.m_eproperty)
    2170           0 :             = *((edge_property_type*)(*ei).m_eproperty);
    2171             :         }
    2172           0 :       }
    2173             :       typename Config::EdgeContainer m_edges;
    2174             :       StoredVertexList m_vertices;
    2175             :     };
    2176             :     // Had to make these non-members to avoid accidental instantiation
    2177             :     // on SGI MIPSpro C++
    2178             :     template <class G, class C, class B>
    2179             :     inline typename C::InEdgeList&
    2180           0 :     in_edge_list(vec_adj_list_impl<G,C,B>& g,
    2181             :                  typename C::vertex_descriptor v) {
    2182           0 :       return g.m_vertices[v].m_in_edges;
    2183             :     }
    2184             :     template <class G, class C, class B>
    2185             :     inline const typename C::InEdgeList&
    2186             :     in_edge_list(const vec_adj_list_impl<G,C,B>& g,
    2187             :                  typename C::vertex_descriptor v) {
    2188             :       return g.m_vertices[v].m_in_edges;
    2189             :     }
    2190             : 
    2191             :       // O(1)
    2192             :     template <class Graph, class Config, class Base>
    2193             :     inline typename Config::vertex_descriptor
    2194           0 :     add_vertex(vec_adj_list_impl<Graph, Config, Base>& g_) {
    2195           0 :       Graph& g = static_cast<Graph&>(g_);
    2196           0 :       g.m_vertices.resize(g.m_vertices.size() + 1);
    2197           0 :       g.added_vertex(g.m_vertices.size() - 1);
    2198           0 :       return g.m_vertices.size() - 1;
    2199             :     }
    2200             : 
    2201             :     template <class Graph, class Config, class Base>
    2202             :     inline typename Config::vertex_descriptor
    2203             :     add_vertex(const typename Config::vertex_property_type& p,
    2204             :                vec_adj_list_impl<Graph, Config, Base>& g_) {
    2205             :       typedef typename Config::vertex_descriptor vertex_descriptor;
    2206             :       Graph& g = static_cast<Graph&>(g_);
    2207             :       if (optional<vertex_descriptor> v
    2208             :             = g.vertex_by_property(get_property_value(p, vertex_bundle)))
    2209             :         return *v;
    2210             :       typedef typename Config::stored_vertex stored_vertex;
    2211             :       g.m_vertices.push_back(stored_vertex(p));
    2212             :       g.added_vertex(g.m_vertices.size() - 1);
    2213             :       return g.m_vertices.size() - 1;
    2214             :     }
    2215             : 
    2216             :     // Here we override the directed_graph_helper add_edge() function
    2217             :     // so that the number of vertices is automatically changed if
    2218             :     // either u or v is greater than the number of vertices.
    2219             :     template <class Graph, class Config, class Base>
    2220             :     inline std::pair<typename Config::edge_descriptor, bool>
    2221           0 :     add_edge(typename Config::vertex_descriptor u,
    2222             :              typename Config::vertex_descriptor v,
    2223             :              const typename Config::edge_property_type& p,
    2224             :              vec_adj_list_impl<Graph, Config, Base>& g_)
    2225             :     {
    2226             :       BOOST_USING_STD_MAX();
    2227           0 :       typename Config::vertex_descriptor x = max BOOST_PREVENT_MACRO_SUBSTITUTION(u, v);
    2228           0 :       if (x >= num_vertices(g_))
    2229           0 :         g_.m_vertices.resize(x + 1);
    2230           0 :       adj_list_helper<Config, Base>& g = g_;
    2231           0 :       return add_edge(u, v, p, g);
    2232             :     }
    2233             :     template <class Graph, class Config, class Base>
    2234             :     inline std::pair<typename Config::edge_descriptor, bool>
    2235           0 :     add_edge(typename Config::vertex_descriptor u,
    2236             :              typename Config::vertex_descriptor v,
    2237             :              vec_adj_list_impl<Graph, Config, Base>& g_)
    2238             :     {
    2239           0 :       typename Config::edge_property_type p;
    2240           0 :       return add_edge(u, v, p, g_);
    2241             :     }
    2242             : 
    2243             : 
    2244             :     // O(V + E)
    2245             :     template <class Graph, class Config, class Base>
    2246             :     inline void remove_vertex(typename Config::vertex_descriptor v,
    2247             :                               vec_adj_list_impl<Graph, Config, Base>& g_)
    2248             :     {
    2249             :       typedef typename Config::directed_category Cat;
    2250             :       Graph& g = static_cast<Graph&>(g_);
    2251             :       g.removing_vertex(v, boost::graph_detail::iterator_stability(g_.m_vertices));
    2252             :       detail::remove_vertex_dispatch(g, v, Cat());
    2253             :     }
    2254             :     // O(1)
    2255             :     template <class Graph, class Config, class Base>
    2256             :     inline typename Config::vertex_descriptor
    2257             :     vertex(typename Config::vertices_size_type n,
    2258             :            const vec_adj_list_impl<Graph, Config, Base>&)
    2259             :     {
    2260             :       return n;
    2261             :     }
    2262             : 
    2263             : 
    2264             :   namespace detail {
    2265             : 
    2266             :     //=========================================================================
    2267             :     // Adjacency List Generator
    2268             : 
    2269             :     template <class Graph, class VertexListS, class OutEdgeListS,
    2270             :               class DirectedS, class VertexProperty, class EdgeProperty,
    2271             :               class GraphProperty, class EdgeListS>
    2272             :     struct adj_list_gen
    2273             :     {
    2274             :       typedef typename detail::is_random_access<VertexListS>::type
    2275             :         is_rand_access;
    2276             :       typedef typename has_property<EdgeProperty>::type has_edge_property;
    2277             :       typedef typename DirectedS::is_directed_t DirectedT;
    2278             :       typedef typename DirectedS::is_bidir_t BidirectionalT;
    2279             : 
    2280             :       struct config
    2281             :       {
    2282             :         typedef OutEdgeListS edgelist_selector;
    2283             :         typedef EdgeListS global_edgelist_selector;
    2284             : 
    2285             :         typedef Graph graph_type;
    2286             :         typedef EdgeProperty edge_property_type;
    2287             :         typedef VertexProperty vertex_property_type;
    2288             :         typedef GraphProperty graph_property_type;
    2289             :         typedef std::size_t vertices_size_type;
    2290             : 
    2291             :         typedef adjacency_list_traits<OutEdgeListS, VertexListS, DirectedS>
    2292             :            Traits;
    2293             : 
    2294             :         typedef typename Traits::directed_category directed_category;
    2295             :         typedef typename Traits::edge_parallel_category edge_parallel_category;
    2296             :         typedef typename Traits::vertex_descriptor vertex_descriptor;
    2297             :         typedef typename Traits::edge_descriptor edge_descriptor;
    2298             : 
    2299             :         typedef void* vertex_ptr;
    2300             : 
    2301             :         // need to reorganize this to avoid instantiating stuff
    2302             :         // that doesn't get used -JGS
    2303             : 
    2304             :         // VertexList and vertex_iterator
    2305             :         typedef typename container_gen<VertexListS,
    2306             :           vertex_ptr>::type SeqVertexList;
    2307             :         typedef boost::integer_range<vertex_descriptor> RandVertexList;
    2308             :         typedef typename mpl::if_<is_rand_access,
    2309             :           RandVertexList, SeqVertexList>::type VertexList;
    2310             : 
    2311             :         typedef typename VertexList::iterator vertex_iterator;
    2312             : 
    2313             :         // EdgeContainer and StoredEdge
    2314             : 
    2315             :         typedef typename container_gen<EdgeListS,
    2316             :           list_edge<vertex_descriptor, EdgeProperty> >::type EdgeContainer;
    2317             : 
    2318             :         typedef typename mpl::and_<DirectedT,
    2319             :              typename mpl::not_<BidirectionalT>::type >::type on_edge_storage;
    2320             : 
    2321             :         typedef typename mpl::if_<on_edge_storage,
    2322             :           std::size_t, typename EdgeContainer::size_type
    2323             :         >::type edges_size_type;
    2324             : 
    2325             :         typedef typename EdgeContainer::iterator EdgeIter;
    2326             : 
    2327             :         typedef typename detail::is_random_access<EdgeListS>::type is_edge_ra;
    2328             : 
    2329             :         typedef typename mpl::if_<on_edge_storage,
    2330             :           stored_edge_property<vertex_descriptor, EdgeProperty>,
    2331             :           typename mpl::if_<is_edge_ra,
    2332             :             stored_ra_edge_iter<vertex_descriptor, EdgeContainer, EdgeProperty>,
    2333             :             stored_edge_iter<vertex_descriptor, EdgeIter, EdgeProperty>
    2334             :           >::type
    2335             :         >::type StoredEdge;
    2336             : 
    2337             :         // Adjacency Types
    2338             : 
    2339             :         typedef typename container_gen<OutEdgeListS, StoredEdge>::type
    2340             :           OutEdgeList;
    2341             :         typedef typename OutEdgeList::size_type degree_size_type;
    2342             :         typedef typename OutEdgeList::iterator OutEdgeIter;
    2343             : 
    2344             :         typedef boost::detail::iterator_traits<OutEdgeIter> OutEdgeIterTraits;
    2345             :         typedef typename OutEdgeIterTraits::iterator_category OutEdgeIterCat;
    2346             :         typedef typename OutEdgeIterTraits::difference_type OutEdgeIterDiff;
    2347             : 
    2348             :         typedef out_edge_iter<
    2349             :             OutEdgeIter, vertex_descriptor, edge_descriptor, OutEdgeIterDiff
    2350             :         > out_edge_iterator;
    2351             : 
    2352             :         typedef typename adjacency_iterator_generator<graph_type,
    2353             :            vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
    2354             : 
    2355             :         typedef OutEdgeList InEdgeList;
    2356             :         typedef OutEdgeIter InEdgeIter;
    2357             :         typedef OutEdgeIterCat InEdgeIterCat;
    2358             :         typedef OutEdgeIterDiff InEdgeIterDiff;
    2359             : 
    2360             :         typedef in_edge_iter<
    2361             :             InEdgeIter, vertex_descriptor, edge_descriptor, InEdgeIterDiff
    2362             :         > in_edge_iterator;
    2363             : 
    2364             :         typedef typename inv_adjacency_iterator_generator<graph_type,
    2365             :            vertex_descriptor, in_edge_iterator>::type inv_adjacency_iterator;
    2366             : 
    2367             :         // Edge Iterator
    2368             : 
    2369             :         typedef boost::detail::iterator_traits<EdgeIter> EdgeIterTraits;
    2370             :         typedef typename EdgeIterTraits::iterator_category EdgeIterCat;
    2371             :         typedef typename EdgeIterTraits::difference_type EdgeIterDiff;
    2372             : 
    2373             :         typedef undirected_edge_iter<
    2374             :             EdgeIter
    2375             :           , edge_descriptor
    2376             :           , EdgeIterDiff
    2377             :         > UndirectedEdgeIter; // also used for bidirectional
    2378             : 
    2379             :         typedef adj_list_edge_iterator<vertex_iterator, out_edge_iterator,
    2380             :            graph_type> DirectedEdgeIter;
    2381             : 
    2382             :         typedef typename mpl::if_<on_edge_storage,
    2383             :           DirectedEdgeIter, UndirectedEdgeIter>::type edge_iterator;
    2384             : 
    2385             :         // stored_vertex and StoredVertexList
    2386             :         typedef typename container_gen<VertexListS, vertex_ptr>::type
    2387             :           SeqStoredVertexList;
    2388             :         struct seq_stored_vertex {
    2389             :           seq_stored_vertex() { }
    2390             :           seq_stored_vertex(const VertexProperty& p) : m_property(p) { }
    2391             :           OutEdgeList m_out_edges;
    2392             :           VertexProperty m_property;
    2393             :           typename SeqStoredVertexList::iterator m_position;
    2394             :         };
    2395             :         struct bidir_seq_stored_vertex {
    2396             :           bidir_seq_stored_vertex() { }
    2397             :           bidir_seq_stored_vertex(const VertexProperty& p) : m_property(p) { }
    2398             :           OutEdgeList m_out_edges;
    2399             :           InEdgeList m_in_edges;
    2400             :           VertexProperty m_property;
    2401             :           typename SeqStoredVertexList::iterator m_position;
    2402             :         };
    2403           0 :         struct rand_stored_vertex {
    2404           0 :           rand_stored_vertex() { }
    2405             :           rand_stored_vertex(const VertexProperty& p) : m_property(p) { }
    2406             :           OutEdgeList m_out_edges;
    2407             :           VertexProperty m_property;
    2408             :         };
    2409             :         struct bidir_rand_stored_vertex {
    2410           0 :           bidir_rand_stored_vertex() { }
    2411             :           bidir_rand_stored_vertex(const VertexProperty& p) : m_property(p) { }
    2412             :           OutEdgeList m_out_edges;
    2413             :           InEdgeList m_in_edges;
    2414             :           VertexProperty m_property;
    2415             :         };
    2416             :         typedef typename mpl::if_<is_rand_access,
    2417             :           typename mpl::if_<BidirectionalT,
    2418             :             bidir_rand_stored_vertex, rand_stored_vertex>::type,
    2419             :           typename mpl::if_<BidirectionalT,
    2420             :             bidir_seq_stored_vertex, seq_stored_vertex>::type
    2421             :         >::type StoredVertex;
    2422           0 :         struct stored_vertex : public StoredVertex {
    2423           0 :           stored_vertex() { }
    2424             :           stored_vertex(const VertexProperty& p) : StoredVertex(p) { }
    2425             :         };
    2426             : 
    2427             :         typedef typename container_gen<VertexListS, stored_vertex>::type
    2428             :           RandStoredVertexList;
    2429             :         typedef typename mpl::if_< is_rand_access,
    2430             :           RandStoredVertexList, SeqStoredVertexList>::type StoredVertexList;
    2431             :       }; // end of config
    2432             : 
    2433             : 
    2434             :       typedef typename mpl::if_<BidirectionalT,
    2435             :         bidirectional_graph_helper_with_property<config>,
    2436             :         typename mpl::if_<DirectedT,
    2437             :           directed_graph_helper<config>,
    2438             :           undirected_graph_helper<config>
    2439             :         >::type
    2440             :       >::type DirectedHelper;
    2441             : 
    2442             :       typedef typename mpl::if_<is_rand_access,
    2443             :         vec_adj_list_impl<Graph, config, DirectedHelper>,
    2444             :         adj_list_impl<Graph, config, DirectedHelper>
    2445             :       >::type type;
    2446             : 
    2447             :     };
    2448             : 
    2449             :   } // namespace detail
    2450             : 
    2451             :     //=========================================================================
    2452             :     // Vertex Property Maps
    2453             : 
    2454             :     template <class Graph, class ValueType, class Reference, class Tag>
    2455             :     struct adj_list_vertex_property_map
    2456             :       : public boost::put_get_helper<
    2457             :           Reference,
    2458             :           adj_list_vertex_property_map<Graph, ValueType, Reference, Tag>
    2459             :         >
    2460             :     {
    2461             :       typedef typename Graph::stored_vertex StoredVertex;
    2462             :       typedef ValueType value_type;
    2463             :       typedef Reference reference;
    2464             :       typedef typename Graph::vertex_descriptor key_type;
    2465             :       typedef boost::lvalue_property_map_tag category;
    2466             :       inline adj_list_vertex_property_map(const Graph* = 0, Tag tag = Tag()): m_tag(tag) { }
    2467             :       inline Reference operator[](key_type v) const {
    2468             :         StoredVertex* sv = (StoredVertex*)v;
    2469             :         return get_property_value(sv->m_property, m_tag);
    2470             :       }
    2471             :       inline Reference operator()(key_type v) const {
    2472             :         return this->operator[](v);
    2473             :       }
    2474             :       Tag m_tag;
    2475             :     };
    2476             : 
    2477             :     template <class Graph, class Property, class PropRef>
    2478             :     struct adj_list_vertex_all_properties_map
    2479             :       : public boost::put_get_helper<PropRef,
    2480             :           adj_list_vertex_all_properties_map<Graph, Property, PropRef>
    2481             :         >
    2482             :     {
    2483             :       typedef typename Graph::stored_vertex StoredVertex;
    2484             :       typedef Property value_type;
    2485             :       typedef PropRef reference;
    2486             :       typedef typename Graph::vertex_descriptor key_type;
    2487             :       typedef boost::lvalue_property_map_tag category;
    2488             :       inline adj_list_vertex_all_properties_map(const Graph* = 0, vertex_all_t = vertex_all_t()) { }
    2489             :       inline PropRef operator[](key_type v) const {
    2490             :         StoredVertex* sv = (StoredVertex*)v;
    2491             :         return sv->m_property;
    2492             :       }
    2493             :       inline PropRef operator()(key_type v) const {
    2494             :         return this->operator[](v);
    2495             :       }
    2496             :     };
    2497             : 
    2498             :     template <class Graph, class GraphPtr, class ValueType, class Reference,
    2499             :               class Tag>
    2500             :     struct vec_adj_list_vertex_property_map
    2501             :       : public boost::put_get_helper<
    2502             :           Reference,
    2503             :           vec_adj_list_vertex_property_map<Graph,GraphPtr,ValueType,Reference,
    2504             :              Tag>
    2505             :         >
    2506             :     {
    2507             :       typedef ValueType value_type;
    2508             :       typedef Reference reference;
    2509             :       typedef typename boost::graph_traits<Graph>::vertex_descriptor key_type;
    2510             :       typedef boost::lvalue_property_map_tag category;
    2511           0 :       vec_adj_list_vertex_property_map(GraphPtr g = 0, Tag tag = Tag()) : m_g(g), m_tag(tag) { }
    2512           0 :       inline Reference operator[](key_type v) const {
    2513           0 :         return get_property_value(m_g->m_vertices[v].m_property, m_tag);
    2514             :       }
    2515             :       inline Reference operator()(key_type v) const {
    2516             :         return this->operator[](v);
    2517             :       }
    2518             :       GraphPtr m_g;
    2519             :       Tag m_tag;
    2520             :     };
    2521             : 
    2522             :     template <class Graph, class GraphPtr, class Property, class PropertyRef>
    2523             :     struct vec_adj_list_vertex_all_properties_map
    2524             :       : public boost::put_get_helper<PropertyRef,
    2525             :           vec_adj_list_vertex_all_properties_map<Graph,GraphPtr,Property,
    2526             :             PropertyRef>
    2527             :         >
    2528             :     {
    2529             :       typedef Property value_type;
    2530             :       typedef PropertyRef reference;
    2531             :       typedef typename boost::graph_traits<Graph>::vertex_descriptor key_type;
    2532             :       typedef boost::lvalue_property_map_tag category;
    2533             :       vec_adj_list_vertex_all_properties_map(GraphPtr g = 0, vertex_all_t = vertex_all_t()) : m_g(g) { }
    2534             :       inline PropertyRef operator[](key_type v) const {
    2535             :         return m_g->m_vertices[v].m_property;
    2536             :       }
    2537             :       inline PropertyRef operator()(key_type v) const {
    2538             :         return this->operator[](v);
    2539             :       }
    2540             :       GraphPtr m_g;
    2541             :     };
    2542             : 
    2543             :     struct adj_list_any_vertex_pa {
    2544             :       template <class Tag, class Graph, class Property>
    2545             :       struct bind_ {
    2546             :         typedef typename property_value<Property, Tag>::type value_type;
    2547             :         typedef value_type& reference;
    2548             :         typedef const value_type& const_reference;
    2549             : 
    2550             :         typedef adj_list_vertex_property_map
    2551             :           <Graph, value_type, reference, Tag> type;
    2552             :         typedef adj_list_vertex_property_map
    2553             :           <Graph, value_type, const_reference, Tag> const_type;
    2554             :       };
    2555             :     };
    2556             :     struct adj_list_all_vertex_pa {
    2557             :       template <class Tag, class Graph, class Property>
    2558             :       struct bind_ {
    2559             :         typedef typename Graph::vertex_descriptor Vertex;
    2560             :         typedef adj_list_vertex_all_properties_map<Graph,Property,
    2561             :           Property&> type;
    2562             :         typedef adj_list_vertex_all_properties_map<Graph,Property,
    2563             :           const Property&> const_type;
    2564             :       };
    2565             :     };
    2566             : 
    2567             :     template <class Property, class Vertex>
    2568             :     struct vec_adj_list_vertex_id_map
    2569             :       : public boost::put_get_helper<
    2570             :           Vertex, vec_adj_list_vertex_id_map<Property, Vertex>
    2571             :         >
    2572             :     {
    2573             :       typedef Vertex value_type;
    2574             :       typedef Vertex key_type;
    2575             :       typedef Vertex reference;
    2576             :       typedef boost::readable_property_map_tag category;
    2577             :       inline vec_adj_list_vertex_id_map() { }
    2578             :       template <class Graph>
    2579           0 :       inline vec_adj_list_vertex_id_map(const Graph&, vertex_index_t) { }
    2580           0 :       inline value_type operator[](key_type v) const { return v; }
    2581             :       inline value_type operator()(key_type v) const { return v; }
    2582             :     };
    2583             : 
    2584             :     struct vec_adj_list_any_vertex_pa {
    2585             :       template <class Tag, class Graph, class Property>
    2586             :       struct bind_ {
    2587             :         typedef typename property_value<Property, Tag>::type value_type;
    2588             :         typedef value_type& reference;
    2589             :         typedef const value_type& const_reference;
    2590             : 
    2591             :         typedef vec_adj_list_vertex_property_map
    2592             :           <Graph, Graph*, value_type, reference, Tag> type;
    2593             :         typedef vec_adj_list_vertex_property_map
    2594             :           <Graph, const Graph*, value_type, const_reference, Tag> const_type;
    2595             :       };
    2596             :     };
    2597             :     struct vec_adj_list_id_vertex_pa {
    2598             :       template <class Tag, class Graph, class Property>
    2599             :       struct bind_ {
    2600             :         typedef typename Graph::vertex_descriptor Vertex;
    2601             :         typedef vec_adj_list_vertex_id_map<Property, Vertex> type;
    2602             :         typedef vec_adj_list_vertex_id_map<Property, Vertex> const_type;
    2603             :       };
    2604             :     };
    2605             :     struct vec_adj_list_all_vertex_pa {
    2606             :       template <class Tag, class Graph, class Property>
    2607             :       struct bind_ {
    2608             :         typedef typename Graph::vertex_descriptor Vertex;
    2609             :         typedef vec_adj_list_vertex_all_properties_map
    2610             :           <Graph, Graph*, Property, Property&> type;
    2611             :         typedef vec_adj_list_vertex_all_properties_map
    2612             :           <Graph, const Graph*, Property, const Property&> const_type;
    2613             :       };
    2614             :     };
    2615             :   namespace detail {
    2616             :     template <class Tag, class Graph, class Property>
    2617             :     struct adj_list_choose_vertex_pa
    2618             :       : boost::mpl::if_<
    2619             :           boost::is_same<Tag, vertex_all_t>,
    2620             :           adj_list_all_vertex_pa,
    2621             :           adj_list_any_vertex_pa>::type
    2622             :         ::template bind_<Tag, Graph, Property>
    2623             :     {};
    2624             : 
    2625             : 
    2626             :     template <class Tag>
    2627             :     struct vec_adj_list_choose_vertex_pa_helper {
    2628             :       typedef vec_adj_list_any_vertex_pa type;
    2629             :     };
    2630             :     template <>
    2631             :     struct vec_adj_list_choose_vertex_pa_helper<vertex_index_t> {
    2632             :       typedef vec_adj_list_id_vertex_pa type;
    2633             :     };
    2634             :     template <>
    2635             :     struct vec_adj_list_choose_vertex_pa_helper<vertex_all_t> {
    2636             :       typedef vec_adj_list_all_vertex_pa type;
    2637             :     };
    2638             :     template <class Tag, class Graph, class Property>
    2639             :     struct vec_adj_list_choose_vertex_pa
    2640             :       : vec_adj_list_choose_vertex_pa_helper<Tag>::type::template bind_<Tag,Graph,Property>
    2641             :     {};
    2642             :   } // namespace detail
    2643             : 
    2644             :     //=========================================================================
    2645             :     // Edge Property Map
    2646             : 
    2647             :     template <class Directed, class Value, class Ref, class Vertex,
    2648             :               class Property, class Tag>
    2649             :     struct adj_list_edge_property_map
    2650             :       : public put_get_helper<
    2651             :           Ref,
    2652             :           adj_list_edge_property_map<Directed, Value, Ref, Vertex, Property,
    2653             :             Tag>
    2654             :         >
    2655             :     {
    2656             :       Tag tag;
    2657           0 :       explicit adj_list_edge_property_map(Tag tag = Tag()): tag(tag) {}
    2658             : 
    2659             :       typedef Value value_type;
    2660             :       typedef Ref reference;
    2661             :       typedef detail::edge_desc_impl<Directed, Vertex> key_type;
    2662             :       typedef boost::lvalue_property_map_tag category;
    2663           0 :       inline Ref operator[](key_type e) const {
    2664           0 :         Property& p = *(Property*)e.get_property();
    2665           0 :         return get_property_value(p, tag);
    2666             :       }
    2667             :       inline Ref operator()(key_type e) const {
    2668             :         return this->operator[](e);
    2669             :       }
    2670             :     };
    2671             : 
    2672             :     template <class Directed, class Property, class PropRef, class PropPtr,
    2673             :       class Vertex>
    2674             :     struct adj_list_edge_all_properties_map
    2675             :       : public put_get_helper<PropRef,
    2676             :           adj_list_edge_all_properties_map<Directed, Property, PropRef,
    2677             :             PropPtr, Vertex>
    2678             :         >
    2679             :     {
    2680             :       explicit adj_list_edge_all_properties_map(edge_all_t = edge_all_t()) {}
    2681             :       typedef Property value_type;
    2682             :       typedef PropRef reference;
    2683             :       typedef detail::edge_desc_impl<Directed, Vertex> key_type;
    2684             :       typedef boost::lvalue_property_map_tag category;
    2685             :       inline PropRef operator[](key_type e) const {
    2686             :         return *(PropPtr)e.get_property();
    2687             :       }
    2688             :       inline PropRef operator()(key_type e) const {
    2689             :         return this->operator[](e);
    2690             :       }
    2691             :     };
    2692             : 
    2693             :   // Edge Property Maps
    2694             : 
    2695             :   namespace detail {
    2696             :     struct adj_list_any_edge_pmap {
    2697             :       template <class Graph, class Property, class Tag>
    2698             :       struct bind_ {
    2699             :         typedef typename property_value<Property,Tag>::type value_type;
    2700             :         typedef value_type& reference;
    2701             :         typedef const value_type& const_reference;
    2702             : 
    2703             :         typedef adj_list_edge_property_map
    2704             :            <typename Graph::directed_category, value_type, reference,
    2705             :             typename Graph::vertex_descriptor,Property,Tag> type;
    2706             :         typedef adj_list_edge_property_map
    2707             :            <typename Graph::directed_category, value_type, const_reference,
    2708             :             typename Graph::vertex_descriptor,const Property, Tag> const_type;
    2709             :       };
    2710             :     };
    2711             :     struct adj_list_all_edge_pmap {
    2712             :       template <class Graph, class Property, class Tag>
    2713             :       struct bind_ {
    2714             :         typedef adj_list_edge_all_properties_map
    2715             :         <typename Graph::directed_category, Property, Property&, Property*,
    2716             :             typename Graph::vertex_descriptor> type;
    2717             :         typedef adj_list_edge_all_properties_map
    2718             :         <typename Graph::directed_category, Property, const Property&,
    2719             :             const Property*, typename Graph::vertex_descriptor> const_type;
    2720             :       };
    2721             :     };
    2722             : 
    2723             :     template <class Tag>
    2724             :     struct adj_list_choose_edge_pmap_helper {
    2725             :       typedef adj_list_any_edge_pmap type;
    2726             :     };
    2727             :     template <>
    2728             :     struct adj_list_choose_edge_pmap_helper<edge_all_t> {
    2729             :       typedef adj_list_all_edge_pmap type;
    2730             :     };
    2731             :     template <class Tag, class Graph, class Property>
    2732             :     struct adj_list_choose_edge_pmap
    2733             :       : adj_list_choose_edge_pmap_helper<Tag>::type::template bind_<Graph, Property, Tag>
    2734             :       {};
    2735             :     struct adj_list_edge_property_selector {
    2736             :       template <class Graph, class Property, class Tag>
    2737             :       struct bind_: adj_list_choose_edge_pmap<Tag, Graph, Property> {};
    2738             :     };
    2739             :   } // namespace detail
    2740             : 
    2741             :   template <>
    2742             :   struct edge_property_selector<adj_list_tag> {
    2743             :     typedef detail::adj_list_edge_property_selector type;
    2744             :   };
    2745             :   template <>
    2746             :   struct edge_property_selector<vec_adj_list_tag> {
    2747             :     typedef detail::adj_list_edge_property_selector type;
    2748             :   };
    2749             : 
    2750             :   // Vertex Property Maps
    2751             : 
    2752             :   struct adj_list_vertex_property_selector {
    2753             :     template <class Graph, class Property, class Tag>
    2754             :     struct bind_
    2755             :       : detail::adj_list_choose_vertex_pa<Tag,Graph,Property>
    2756             :     {};
    2757             :   };
    2758             :   template <>
    2759             :   struct vertex_property_selector<adj_list_tag> {
    2760             :     typedef adj_list_vertex_property_selector type;
    2761             :   };
    2762             : 
    2763             :   struct vec_adj_list_vertex_property_selector {
    2764             :     template <class Graph, class Property, class Tag>
    2765             :     struct bind_: detail::vec_adj_list_choose_vertex_pa<Tag,Graph,Property> {};
    2766             :   };
    2767             :   template <>
    2768             :   struct vertex_property_selector<vec_adj_list_tag> {
    2769             :     typedef vec_adj_list_vertex_property_selector type;
    2770             :   };
    2771             : 
    2772             : } // namespace boost
    2773             : 
    2774             : namespace boost {
    2775             : 
    2776             :   template <typename V>
    2777             :   struct hash< boost::detail::stored_edge<V> >
    2778             :   {
    2779             :     std::size_t
    2780             :     operator()(const boost::detail::stored_edge<V>& e) const
    2781             :     {
    2782             :       return hash<V>()(e.m_target);
    2783             :     }
    2784             :   };
    2785             : 
    2786             :   template <typename V, typename P>
    2787             :   struct hash< boost::detail::stored_edge_property <V,P> >
    2788             :   {
    2789             :     std::size_t
    2790             :     operator()(const boost::detail::stored_edge_property<V,P>& e) const
    2791             :     {
    2792             :       return hash<V>()(e.m_target);
    2793             :     }
    2794             :   };
    2795             : 
    2796             :   template <typename V, typename I, typename P>
    2797             :   struct hash< boost::detail::stored_edge_iter<V,I, P> >
    2798             :   {
    2799             :     std::size_t
    2800             :     operator()(const boost::detail::stored_edge_iter<V,I,P>& e) const
    2801             :     {
    2802             :       return hash<V>()(e.m_target);
    2803             :     }
    2804             :   };
    2805             : 
    2806             : }
    2807             : 
    2808             : 
    2809             : #endif // BOOST_GRAPH_DETAIL_DETAIL_ADJACENCY_LIST_CCT
    2810             : 
    2811             : /*
    2812             :   Implementation Notes:
    2813             : 
    2814             :   Many of the public interface functions in this file would have been
    2815             :   more conveniently implemented as inline friend functions.
    2816             :   However there are a few compiler bugs that make that approach
    2817             :   non-portable.
    2818             : 
    2819             :   1. g++ inline friend in namespace bug
    2820             :   2. g++ using clause doesn't work with inline friends
    2821             :   3. VC++ doesn't have Koenig lookup
    2822             : 
    2823             :   For these reasons, the functions were all written as non-inline free
    2824             :   functions, and static cast was used to convert from the helper
    2825             :   class to the adjacency_list derived class.
    2826             : 
    2827             :   Looking back, it might have been better to write out all functions
    2828             :   in terms of the adjacency_list, and then use a tag to dispatch
    2829             :   to the various helpers instead of using inheritance.
    2830             : 
    2831             :  */

Generated by: LCOV version 1.14