ossrv_pub/boost_apis/boost/graph/adjacency_matrix.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 //=======================================================================
       
     2 // Copyright 2001 University of Notre Dame.
       
     3 // Copyright 2006 Trustees of Indiana University
       
     4 // Authors: Jeremy G. Siek and Douglas Gregor <dgregor@cs.indiana.edu>
       
     5 //
       
     6 // Distributed under the Boost Software License, Version 1.0. (See
       
     7 // accompanying file LICENSE_1_0.txt or copy at
       
     8 // http://www.boost.org/LICENSE_1_0.txt)
       
     9 //=======================================================================
       
    10 
       
    11 #ifndef BOOST_ADJACENCY_MATRIX_HPP
       
    12 #define BOOST_ADJACENCY_MATRIX_HPP
       
    13 
       
    14 #include <boost/config.hpp>
       
    15 #include <vector>
       
    16 #include <memory>
       
    17 #include <cassert>
       
    18 #include <boost/limits.hpp>
       
    19 #include <boost/iterator.hpp>
       
    20 #include <boost/graph/graph_traits.hpp>
       
    21 #include <boost/graph/graph_selectors.hpp>
       
    22 #include <boost/pending/ct_if.hpp>
       
    23 #include <boost/graph/adjacency_iterator.hpp>
       
    24 #include <boost/graph/detail/edge.hpp>
       
    25 #include <boost/iterator/iterator_adaptor.hpp>
       
    26 #include <boost/iterator/filter_iterator.hpp>
       
    27 #include <boost/pending/integer_range.hpp>
       
    28 #include <boost/graph/properties.hpp>
       
    29 #include <boost/tuple/tuple.hpp>
       
    30 #include <boost/static_assert.hpp>
       
    31 #include <boost/type_traits/ice.hpp>
       
    32 
       
    33 namespace boost {
       
    34   
       
    35   namespace detail {
       
    36 
       
    37     template <class Directed, class Vertex>
       
    38     class matrix_edge_desc_impl : public edge_desc_impl<Directed,Vertex>
       
    39     {
       
    40       typedef edge_desc_impl<Directed,Vertex> Base;
       
    41     public:
       
    42       matrix_edge_desc_impl() { }
       
    43       matrix_edge_desc_impl(bool exists, Vertex s, Vertex d, 
       
    44                             const void* ep = 0)
       
    45         : Base(s, d, ep), m_exists(exists) { }
       
    46       bool exists() const { return m_exists; }
       
    47     private:
       
    48       bool m_exists;
       
    49     };
       
    50 
       
    51     struct does_edge_exist {
       
    52       template <class Edge>
       
    53       bool operator()(const Edge& e) const { return e.exists(); }
       
    54     };
       
    55 
       
    56     template <typename EdgeProperty>
       
    57     bool get_edge_exists(const std::pair<bool, EdgeProperty>& stored_edge, int) {
       
    58       return stored_edge.first;
       
    59     }
       
    60     template <typename EdgeProperty>
       
    61     void set_edge_exists(
       
    62         std::pair<bool, EdgeProperty>& stored_edge, 
       
    63         bool flag,
       
    64         int
       
    65         ) {
       
    66       stored_edge.first = flag;
       
    67     }
       
    68 
       
    69     template <typename EdgeProxy>
       
    70     bool get_edge_exists(const EdgeProxy& edge_proxy, ...) {
       
    71       return edge_proxy;
       
    72     }
       
    73     template <typename EdgeProxy>
       
    74     EdgeProxy& set_edge_exists(EdgeProxy& edge_proxy, bool flag, ...) {
       
    75       edge_proxy = flag;
       
    76       return edge_proxy; // just to avoid never used warning
       
    77     }
       
    78 
       
    79 
       
    80 
       
    81     template <typename EdgeProperty>
       
    82     const EdgeProperty&
       
    83     get_property(const std::pair<bool, EdgeProperty>& stored_edge) {
       
    84       return stored_edge.second;
       
    85     }
       
    86     template <typename EdgeProperty>
       
    87     EdgeProperty&
       
    88     get_property(std::pair<bool, EdgeProperty>& stored_edge) {
       
    89       return stored_edge.second;
       
    90     }
       
    91 
       
    92     template <typename StoredEdgeProperty, typename EdgeProperty>
       
    93     inline void
       
    94     set_property(std::pair<bool, StoredEdgeProperty>& stored_edge, 
       
    95                  const EdgeProperty& ep, int) {
       
    96       stored_edge.second = ep;
       
    97     }
       
    98 
       
    99     inline const no_property& get_property(const char&) {
       
   100       static no_property s_prop;
       
   101       return s_prop;
       
   102     }
       
   103     inline no_property& get_property(char&) {
       
   104       static no_property s_prop;
       
   105       return s_prop;
       
   106     }
       
   107     template <typename EdgeProxy, typename EdgeProperty>
       
   108     inline void
       
   109     set_property(EdgeProxy, const EdgeProperty&, ...) {}
       
   110     
       
   111     //=======================================================================
       
   112     // Directed Out Edge Iterator
       
   113 
       
   114     template <
       
   115         typename VertexDescriptor, typename MatrixIter
       
   116       , typename VerticesSizeType, typename EdgeDescriptor
       
   117     >
       
   118     struct dir_adj_matrix_out_edge_iter
       
   119       : iterator_adaptor<
       
   120             dir_adj_matrix_out_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
       
   121           , MatrixIter
       
   122           , EdgeDescriptor
       
   123           , use_default
       
   124           , EdgeDescriptor
       
   125           , std::ptrdiff_t
       
   126         >
       
   127     {
       
   128         typedef iterator_adaptor<
       
   129             dir_adj_matrix_out_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
       
   130           , MatrixIter
       
   131           , EdgeDescriptor
       
   132           , use_default
       
   133           , EdgeDescriptor
       
   134           , std::ptrdiff_t
       
   135         > super_t;
       
   136         
       
   137         dir_adj_matrix_out_edge_iter() { }
       
   138         
       
   139         dir_adj_matrix_out_edge_iter(
       
   140             const MatrixIter& i
       
   141           , const VertexDescriptor& src
       
   142           , const VerticesSizeType& n
       
   143            )
       
   144             : super_t(i), m_src(src), m_targ(0), m_n(n)
       
   145         { }
       
   146 
       
   147         void increment() {
       
   148             ++this->base_reference();
       
   149             ++m_targ;
       
   150         }
       
   151         
       
   152         inline EdgeDescriptor
       
   153         dereference() const 
       
   154         {
       
   155             return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, m_targ, 
       
   156                                   &get_property(*this->base()));
       
   157         }
       
   158         VertexDescriptor m_src, m_targ;
       
   159         VerticesSizeType m_n;
       
   160     };
       
   161 
       
   162     //=======================================================================
       
   163     // Directed In Edge Iterator
       
   164 
       
   165     template <
       
   166         typename VertexDescriptor, typename MatrixIter
       
   167       , typename VerticesSizeType, typename EdgeDescriptor
       
   168     >
       
   169     struct dir_adj_matrix_in_edge_iter
       
   170       : iterator_adaptor<
       
   171             dir_adj_matrix_in_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
       
   172           , MatrixIter
       
   173           , EdgeDescriptor
       
   174           , use_default
       
   175           , EdgeDescriptor
       
   176           , std::ptrdiff_t
       
   177         >
       
   178     {
       
   179         typedef iterator_adaptor<
       
   180             dir_adj_matrix_in_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
       
   181           , MatrixIter
       
   182           , EdgeDescriptor
       
   183           , use_default
       
   184           , EdgeDescriptor
       
   185           , std::ptrdiff_t
       
   186         > super_t;
       
   187         
       
   188         dir_adj_matrix_in_edge_iter() { }
       
   189         
       
   190         dir_adj_matrix_in_edge_iter(
       
   191             const MatrixIter& i
       
   192           , const MatrixIter& last
       
   193           , const VertexDescriptor& tgt
       
   194           , const VerticesSizeType& n
       
   195            )
       
   196           : super_t(i), m_last(last), m_src(0), m_targ(tgt), m_n(n)
       
   197         { }
       
   198 
       
   199         void increment() {
       
   200           if (VerticesSizeType(m_last - this->base_reference()) >= m_n) {
       
   201             this->base_reference() += m_n;
       
   202             ++m_src;
       
   203           } else {
       
   204             this->base_reference() = m_last;
       
   205           }
       
   206         }
       
   207         
       
   208         inline EdgeDescriptor
       
   209         dereference() const 
       
   210         {
       
   211             return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, m_targ, 
       
   212                                   &get_property(*this->base()));
       
   213         }
       
   214         MatrixIter m_last;
       
   215         VertexDescriptor m_src, m_targ;
       
   216         VerticesSizeType m_n;
       
   217     };
       
   218 
       
   219     //=======================================================================
       
   220     // Undirected Out Edge Iterator
       
   221 
       
   222     template <
       
   223         typename VertexDescriptor, typename MatrixIter
       
   224       , typename VerticesSizeType, typename EdgeDescriptor
       
   225     >
       
   226     struct undir_adj_matrix_out_edge_iter 
       
   227       : iterator_adaptor<
       
   228             undir_adj_matrix_out_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
       
   229           , MatrixIter
       
   230           , EdgeDescriptor
       
   231           , use_default
       
   232           , EdgeDescriptor
       
   233           , std::ptrdiff_t
       
   234         >
       
   235     {
       
   236         typedef iterator_adaptor<
       
   237             undir_adj_matrix_out_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
       
   238           , MatrixIter
       
   239           , EdgeDescriptor
       
   240           , use_default
       
   241           , EdgeDescriptor
       
   242           , std::ptrdiff_t
       
   243         > super_t;
       
   244         
       
   245         undir_adj_matrix_out_edge_iter() { }
       
   246         
       
   247         undir_adj_matrix_out_edge_iter(
       
   248             const MatrixIter& i
       
   249           , const VertexDescriptor& src
       
   250           , const VerticesSizeType& n
       
   251         )
       
   252           : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n)
       
   253         {}
       
   254 
       
   255         void increment()
       
   256         {
       
   257             if (m_targ < m_src)     // first half
       
   258             {
       
   259                 ++this->base_reference();
       
   260             }
       
   261             else if (m_targ < m_n - 1)
       
   262             {                  // second half
       
   263                 ++m_inc;
       
   264                 this->base_reference() += m_inc;
       
   265             }
       
   266             else
       
   267             {                  // past-the-end
       
   268                 this->base_reference() += m_n - m_src;
       
   269             }
       
   270             ++m_targ;
       
   271         }
       
   272         
       
   273         inline EdgeDescriptor
       
   274         dereference() const 
       
   275         {
       
   276             return EdgeDescriptor(
       
   277                 get_edge_exists(*this->base(), 0), m_src, m_targ
       
   278               , &get_property(*this->base())
       
   279             );
       
   280         }
       
   281         
       
   282         VertexDescriptor m_src, m_inc, m_targ;
       
   283         VerticesSizeType m_n;
       
   284     };
       
   285 
       
   286     //=======================================================================
       
   287     // Undirected In Edge Iterator
       
   288 
       
   289     template <
       
   290         typename VertexDescriptor, typename MatrixIter
       
   291       , typename VerticesSizeType, typename EdgeDescriptor
       
   292     >
       
   293     struct undir_adj_matrix_in_edge_iter 
       
   294       : iterator_adaptor<
       
   295             undir_adj_matrix_in_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
       
   296           , MatrixIter
       
   297           , EdgeDescriptor
       
   298           , use_default
       
   299           , EdgeDescriptor
       
   300           , std::ptrdiff_t
       
   301         >
       
   302     {
       
   303         typedef iterator_adaptor<
       
   304             undir_adj_matrix_in_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
       
   305           , MatrixIter
       
   306           , EdgeDescriptor
       
   307           , use_default
       
   308           , EdgeDescriptor
       
   309           , std::ptrdiff_t
       
   310         > super_t;
       
   311         
       
   312         undir_adj_matrix_in_edge_iter() { }
       
   313         
       
   314         undir_adj_matrix_in_edge_iter(
       
   315             const MatrixIter& i
       
   316           , const VertexDescriptor& src
       
   317           , const VerticesSizeType& n
       
   318         )
       
   319           : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n)
       
   320         {}
       
   321 
       
   322         void increment()
       
   323         {
       
   324             if (m_targ < m_src)     // first half
       
   325             {
       
   326                 ++this->base_reference();
       
   327             }
       
   328             else if (m_targ < m_n - 1)
       
   329             {                  // second half
       
   330                 ++m_inc;
       
   331                 this->base_reference() += m_inc;
       
   332             }
       
   333             else
       
   334             {                  // past-the-end
       
   335                 this->base_reference() += m_n - m_src;
       
   336             }
       
   337             ++m_targ;
       
   338         }
       
   339         
       
   340         inline EdgeDescriptor
       
   341         dereference() const 
       
   342         {
       
   343             return EdgeDescriptor(
       
   344                      get_edge_exists(*this->base(), 0), m_targ, m_src
       
   345               , &get_property(*this->base())
       
   346             );
       
   347         }
       
   348         
       
   349         VertexDescriptor m_src, m_inc, m_targ;
       
   350         VerticesSizeType m_n;
       
   351     };
       
   352 
       
   353     //=======================================================================
       
   354     // Edge Iterator
       
   355 
       
   356     template <typename Directed, typename MatrixIter, 
       
   357               typename VerticesSizeType, typename EdgeDescriptor>
       
   358     struct adj_matrix_edge_iter
       
   359       : iterator_adaptor<
       
   360             adj_matrix_edge_iter<Directed, MatrixIter,  VerticesSizeType, EdgeDescriptor>
       
   361           , MatrixIter
       
   362           , EdgeDescriptor
       
   363           , use_default
       
   364           , EdgeDescriptor
       
   365           , std::ptrdiff_t
       
   366         >
       
   367     {
       
   368         typedef iterator_adaptor<
       
   369             adj_matrix_edge_iter<Directed, MatrixIter,  VerticesSizeType, EdgeDescriptor>
       
   370           , MatrixIter
       
   371           , EdgeDescriptor
       
   372           , use_default
       
   373           , EdgeDescriptor
       
   374           , std::ptrdiff_t
       
   375         > super_t;
       
   376         
       
   377         adj_matrix_edge_iter() { }
       
   378         
       
   379         adj_matrix_edge_iter(const MatrixIter& i, const MatrixIter& start, const VerticesSizeType& n) 
       
   380             : super_t(i), m_start(start), m_src(0), m_targ(0), m_n(n) { }
       
   381 
       
   382         void increment()
       
   383         {
       
   384             increment_dispatch(this->base_reference(), Directed());
       
   385         }
       
   386         
       
   387         void increment_dispatch(MatrixIter& i, directedS)
       
   388         {
       
   389             ++i;
       
   390             if (m_targ == m_n - 1)
       
   391             {
       
   392                 m_targ = 0;
       
   393                 ++m_src;
       
   394             }
       
   395             else
       
   396             {
       
   397                 ++m_targ;
       
   398             }
       
   399         }
       
   400         
       
   401         void increment_dispatch(MatrixIter& i, undirectedS)
       
   402         {
       
   403             ++i;
       
   404             if (m_targ == m_src)
       
   405             {
       
   406                 m_targ = 0;
       
   407                 ++m_src;
       
   408             }
       
   409             else
       
   410             {
       
   411                 ++m_targ;
       
   412             }
       
   413         }
       
   414 
       
   415         inline EdgeDescriptor
       
   416         dereference() const 
       
   417         {
       
   418             return EdgeDescriptor(
       
   419                 get_edge_exists(
       
   420                     *this->base(), 0), m_src, m_targ, &get_property(*this->base())
       
   421             );
       
   422         }
       
   423       
       
   424         MatrixIter m_start;
       
   425         VerticesSizeType m_src, m_targ, m_n;
       
   426     };
       
   427 
       
   428   } // namespace detail
       
   429 
       
   430   //=========================================================================
       
   431   // Adjacency Matrix Traits
       
   432   template <typename Directed = directedS>
       
   433   class adjacency_matrix_traits {
       
   434     typedef typename Directed::is_directed_t is_directed;
       
   435   public:
       
   436     // The bidirectionalS tag is not allowed with the adjacency_matrix
       
   437     // graph type. Instead, use directedS, which also provides the
       
   438     // functionality required for a Bidirectional Graph (in_edges,
       
   439     // in_degree, etc.).
       
   440 #if !defined(_MSC_VER) || _MSC_VER > 1300
       
   441     BOOST_STATIC_ASSERT(type_traits::ice_not<(is_same<Directed, bidirectionalS>::value)>::value);
       
   442 #endif
       
   443 
       
   444     typedef typename boost::ct_if_t<is_directed,
       
   445                                     bidirectional_tag, undirected_tag>::type
       
   446       directed_category;
       
   447     
       
   448     typedef disallow_parallel_edge_tag edge_parallel_category;
       
   449     
       
   450     typedef std::size_t vertex_descriptor;
       
   451 
       
   452     typedef detail::matrix_edge_desc_impl<directed_category,
       
   453       vertex_descriptor> edge_descriptor;
       
   454   };
       
   455 
       
   456   struct adjacency_matrix_class_tag { };
       
   457 
       
   458   struct adj_matrix_traversal_tag :
       
   459     public virtual adjacency_matrix_tag,
       
   460     public virtual vertex_list_graph_tag,
       
   461     public virtual incidence_graph_tag,
       
   462     public virtual adjacency_graph_tag,
       
   463     public virtual edge_list_graph_tag { };
       
   464   
       
   465   //=========================================================================
       
   466   // Adjacency Matrix Class
       
   467   template <typename Directed = directedS,
       
   468             typename VertexProperty = no_property,
       
   469             typename EdgeProperty = no_property,
       
   470             typename GraphProperty = no_property,
       
   471             typename Allocator = std::allocator<bool> >
       
   472   class adjacency_matrix {
       
   473     typedef adjacency_matrix self;
       
   474     typedef adjacency_matrix_traits<Directed> Traits;
       
   475     
       
   476   public:
       
   477 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
       
   478     // The bidirectionalS tag is not allowed with the adjacency_matrix
       
   479     // graph type. Instead, use directedS, which also provides the
       
   480     // functionality required for a Bidirectional Graph (in_edges,
       
   481     // in_degree, etc.).
       
   482     BOOST_STATIC_ASSERT(!(is_same<Directed, bidirectionalS>::value));
       
   483 #endif
       
   484 
       
   485 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
       
   486     typedef typename detail::retag_property_list<vertex_bundle_t, VertexProperty>::type
       
   487       vertex_property_type;
       
   488     typedef typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::type
       
   489       edge_property_type;
       
   490       
       
   491   private:
       
   492     typedef typename detail::retag_property_list<vertex_bundle_t, VertexProperty>::retagged
       
   493       maybe_vertex_bundled;
       
   494 
       
   495     typedef typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::retagged
       
   496       maybe_edge_bundled;
       
   497     
       
   498   public:
       
   499     // The types that are actually bundled
       
   500     typedef typename ct_if<(is_same<maybe_vertex_bundled, no_property>::value),
       
   501                            no_vertex_bundle,
       
   502                            maybe_vertex_bundled>::type vertex_bundled;
       
   503     typedef typename ct_if<(is_same<maybe_edge_bundled, no_property>::value),
       
   504                            no_edge_bundle,
       
   505                            maybe_edge_bundled>::type edge_bundled;
       
   506 #else
       
   507     typedef EdgeProperty     edge_property_type;
       
   508     typedef VertexProperty   vertex_property_type;
       
   509     typedef no_vertex_bundle vertex_bundled;
       
   510     typedef no_edge_bundle   edge_bundled;
       
   511 #endif
       
   512 
       
   513   public: // should be private
       
   514     typedef typename ct_if_t<typename has_property<edge_property_type>::type,
       
   515       std::pair<bool, edge_property_type>, char>::type StoredEdge;
       
   516 #if (defined(BOOST_MSVC) && BOOST_MSVC <= 1300) || defined(BOOST_NO_STD_ALLOCATOR)
       
   517     typedef std::vector<StoredEdge> Matrix;
       
   518 #else
       
   519     // This causes internal compiler error for MSVC
       
   520     typedef typename Allocator::template rebind<StoredEdge>::other Alloc;
       
   521     typedef std::vector<StoredEdge, Alloc> Matrix;
       
   522 #endif
       
   523     typedef typename Matrix::iterator MatrixIter;
       
   524     typedef typename Matrix::size_type size_type;
       
   525   public:
       
   526     // Graph concept required types
       
   527     typedef typename Traits::vertex_descriptor vertex_descriptor;
       
   528     typedef typename Traits::edge_descriptor edge_descriptor;
       
   529     typedef typename Traits::directed_category directed_category;
       
   530     typedef typename Traits::edge_parallel_category edge_parallel_category;
       
   531     typedef adj_matrix_traversal_tag traversal_category;
       
   532 
       
   533     static vertex_descriptor null_vertex()
       
   534     {
       
   535       return (std::numeric_limits<vertex_descriptor>::max)();
       
   536     }
       
   537       
       
   538     //private: if friends worked, these would be private
       
   539 
       
   540     typedef detail::dir_adj_matrix_out_edge_iter<
       
   541         vertex_descriptor, MatrixIter, size_type, edge_descriptor
       
   542     > DirOutEdgeIter;
       
   543 
       
   544     typedef detail::undir_adj_matrix_out_edge_iter<
       
   545         vertex_descriptor, MatrixIter, size_type, edge_descriptor
       
   546     > UnDirOutEdgeIter;
       
   547 
       
   548     typedef typename ct_if_t<
       
   549         typename Directed::is_directed_t, DirOutEdgeIter, UnDirOutEdgeIter
       
   550     >::type unfiltered_out_edge_iter;
       
   551 
       
   552     typedef detail::dir_adj_matrix_in_edge_iter<
       
   553         vertex_descriptor, MatrixIter, size_type, edge_descriptor
       
   554     > DirInEdgeIter;
       
   555 
       
   556     typedef detail::undir_adj_matrix_in_edge_iter<
       
   557         vertex_descriptor, MatrixIter, size_type, edge_descriptor
       
   558     > UnDirInEdgeIter;
       
   559 
       
   560     typedef typename ct_if_t<
       
   561         typename Directed::is_directed_t, DirInEdgeIter, UnDirInEdgeIter
       
   562     >::type unfiltered_in_edge_iter;
       
   563     
       
   564     typedef detail::adj_matrix_edge_iter<
       
   565         Directed, MatrixIter, size_type, edge_descriptor
       
   566     > unfiltered_edge_iter;
       
   567     
       
   568   public:
       
   569 
       
   570     // IncidenceGraph concept required types
       
   571     typedef filter_iterator<detail::does_edge_exist, unfiltered_out_edge_iter>
       
   572       out_edge_iterator;
       
   573 
       
   574     typedef size_type degree_size_type;
       
   575 
       
   576     // BidirectionalGraph required types
       
   577     typedef filter_iterator<detail::does_edge_exist, unfiltered_in_edge_iter>
       
   578       in_edge_iterator;
       
   579 
       
   580     // AdjacencyGraph required types
       
   581      typedef typename adjacency_iterator_generator<self,
       
   582        vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
       
   583 
       
   584     // VertexListGraph required types
       
   585     typedef size_type vertices_size_type;
       
   586     typedef integer_range<vertex_descriptor> VertexList;
       
   587     typedef typename VertexList::iterator vertex_iterator;
       
   588 
       
   589     // EdgeListGraph required types
       
   590     typedef size_type edges_size_type;
       
   591     typedef filter_iterator<
       
   592         detail::does_edge_exist, unfiltered_edge_iter
       
   593     > edge_iterator;
       
   594 
       
   595     // PropertyGraph required types
       
   596     typedef adjacency_matrix_class_tag graph_tag;
       
   597 
       
   598     // Constructor required by MutableGraph
       
   599     adjacency_matrix(vertices_size_type n_vertices) 
       
   600       : m_matrix(Directed::is_directed ? 
       
   601                  (n_vertices * n_vertices)
       
   602                  : (n_vertices * (n_vertices + 1) / 2)),
       
   603       m_vertex_set(0, n_vertices),
       
   604       m_vertex_properties(n_vertices),
       
   605       m_num_edges(0) { }
       
   606 
       
   607 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
       
   608     // Directly access a vertex or edge bundle
       
   609     vertex_bundled& operator[](vertex_descriptor v)
       
   610     { return get(vertex_bundle, *this)[v]; }
       
   611 
       
   612     const vertex_bundled& operator[](vertex_descriptor v) const
       
   613     { return get(vertex_bundle, *this)[v]; }
       
   614 
       
   615     edge_bundled& operator[](edge_descriptor e)
       
   616     { return get(edge_bundle, *this)[e]; }
       
   617 
       
   618     const edge_bundled& operator[](edge_descriptor e) const
       
   619     { return get(edge_bundle, *this)[e]; }
       
   620 #endif
       
   621     
       
   622     //private: if friends worked, these would be private
       
   623 
       
   624     typename Matrix::const_reference
       
   625     get_edge(vertex_descriptor u, vertex_descriptor v) const {
       
   626       if (Directed::is_directed)
       
   627         return m_matrix[u * m_vertex_set.size() + v];
       
   628       else {
       
   629         if (v > u)
       
   630           std::swap(u, v);
       
   631         return m_matrix[u * (u + 1)/2 + v];
       
   632       }
       
   633     }
       
   634     typename Matrix::reference
       
   635     get_edge(vertex_descriptor u, vertex_descriptor v) {
       
   636       if (Directed::is_directed)
       
   637         return m_matrix[u * m_vertex_set.size() + v];
       
   638       else {
       
   639         if (v > u)
       
   640           std::swap(u, v);
       
   641         return m_matrix[u * (u + 1)/2 + v];
       
   642       }
       
   643     }
       
   644 
       
   645     Matrix m_matrix;
       
   646     VertexList m_vertex_set;
       
   647     std::vector<vertex_property_type> m_vertex_properties;
       
   648     size_type m_num_edges;
       
   649   };
       
   650   
       
   651   //=========================================================================
       
   652   // Functions required by the AdjacencyMatrix concept 
       
   653 
       
   654   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   655   std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor,
       
   656             bool>
       
   657   edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
       
   658        typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
       
   659        const adjacency_matrix<D,VP,EP,GP,A>& g)
       
   660   {
       
   661     bool exists = detail::get_edge_exists(g.get_edge(u,v), 0);
       
   662     typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor
       
   663       e(exists, u, v, &detail::get_property(g.get_edge(u,v)));
       
   664     return std::make_pair(e, exists);
       
   665   }
       
   666 
       
   667   //=========================================================================
       
   668   // Functions required by the IncidenceGraph concept 
       
   669 
       
   670   // O(1)
       
   671   template <typename VP, typename EP, typename GP, typename A>
       
   672   std::pair<typename adjacency_matrix<directedS,VP,EP,GP,A>::out_edge_iterator,
       
   673             typename adjacency_matrix<directedS,VP,EP,GP,A>::out_edge_iterator>
       
   674   out_edges
       
   675     (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u,
       
   676      const adjacency_matrix<directedS,VP,EP,GP,A>& g_)
       
   677   {
       
   678     typedef adjacency_matrix<directedS,VP,EP,GP,A> Graph;
       
   679     Graph& g = const_cast<Graph&>(g_);
       
   680     typename Graph::vertices_size_type offset = u * g.m_vertex_set.size();
       
   681     typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
       
   682     typename Graph::MatrixIter l = f + g.m_vertex_set.size();
       
   683     typename Graph::unfiltered_out_edge_iter
       
   684           first(f, u, g.m_vertex_set.size())
       
   685         , last(l, u, g.m_vertex_set.size());
       
   686     detail::does_edge_exist pred;
       
   687     typedef typename Graph::out_edge_iterator out_edge_iterator;
       
   688     return std::make_pair(out_edge_iterator(pred, first, last), 
       
   689                           out_edge_iterator(pred, last, last));
       
   690   }
       
   691 
       
   692   // O(1)
       
   693   template <typename VP, typename EP, typename GP, typename A>
       
   694   std::pair<
       
   695     typename adjacency_matrix<undirectedS,VP,EP,GP,A>::out_edge_iterator,
       
   696     typename adjacency_matrix<undirectedS,VP,EP,GP,A>::out_edge_iterator>
       
   697   out_edges
       
   698     (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u,
       
   699      const adjacency_matrix<undirectedS,VP,EP,GP,A>& g_)
       
   700   {
       
   701     typedef adjacency_matrix<undirectedS,VP,EP,GP,A> Graph;
       
   702     Graph& g = const_cast<Graph&>(g_);
       
   703     typename Graph::vertices_size_type offset = u * (u + 1) / 2;
       
   704     typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
       
   705     typename Graph::MatrixIter l = g.m_matrix.end();
       
   706 
       
   707     typename Graph::unfiltered_out_edge_iter
       
   708         first(f, u, g.m_vertex_set.size())
       
   709       , last(l, u, g.m_vertex_set.size());
       
   710     
       
   711     detail::does_edge_exist pred;
       
   712     typedef typename Graph::out_edge_iterator out_edge_iterator;
       
   713     return std::make_pair(out_edge_iterator(pred, first, last), 
       
   714                           out_edge_iterator(pred, last, last));
       
   715   }
       
   716   
       
   717   // O(N)
       
   718   template <typename D, typename VP, typename EP, typename GP, typename A>  
       
   719   typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type
       
   720   out_degree(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
       
   721              const adjacency_matrix<D,VP,EP,GP,A>& g)
       
   722   {
       
   723     typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type n = 0;
       
   724     typename adjacency_matrix<D,VP,EP,GP,A>::out_edge_iterator f, l;
       
   725     for (tie(f, l) = out_edges(u, g); f != l; ++f)
       
   726       ++n;
       
   727     return n;
       
   728   }
       
   729 
       
   730   // O(1)
       
   731   template <typename D, typename VP, typename EP, typename GP, typename A,
       
   732     typename Dir, typename Vertex>  
       
   733   typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
       
   734   source(const detail::matrix_edge_desc_impl<Dir,Vertex>& e,
       
   735          const adjacency_matrix<D,VP,EP,GP,A>&)
       
   736   {
       
   737     return e.m_source;
       
   738   }
       
   739 
       
   740   // O(1)
       
   741   template <typename D, typename VP, typename EP, typename GP, typename A,
       
   742     typename Dir, typename Vertex>  
       
   743   typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
       
   744   target(const detail::matrix_edge_desc_impl<Dir,Vertex>& e,
       
   745          const adjacency_matrix<D,VP,EP,GP,A>&)
       
   746   {
       
   747     return e.m_target;
       
   748   }
       
   749 
       
   750   //=========================================================================
       
   751   // Functions required by the BidirectionalGraph concept 
       
   752 
       
   753   // O(1)
       
   754   template <typename VP, typename EP, typename GP, typename A>
       
   755   std::pair<typename adjacency_matrix<directedS,VP,EP,GP,A>::in_edge_iterator,
       
   756             typename adjacency_matrix<directedS,VP,EP,GP,A>::in_edge_iterator>
       
   757   in_edges
       
   758     (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u,
       
   759      const adjacency_matrix<directedS,VP,EP,GP,A>& g_)
       
   760   {
       
   761     typedef adjacency_matrix<directedS,VP,EP,GP,A> Graph;
       
   762     Graph& g = const_cast<Graph&>(g_);
       
   763     typename Graph::MatrixIter f = g.m_matrix.begin() + u;
       
   764     typename Graph::MatrixIter l = g.m_matrix.end();
       
   765     typename Graph::unfiltered_in_edge_iter
       
   766         first(f, l, u, g.m_vertex_set.size())
       
   767       , last(l, l, u, g.m_vertex_set.size());
       
   768     detail::does_edge_exist pred;
       
   769     typedef typename Graph::in_edge_iterator in_edge_iterator;
       
   770     return std::make_pair(in_edge_iterator(pred, first, last), 
       
   771                           in_edge_iterator(pred, last, last));
       
   772   }
       
   773 
       
   774   // O(1)
       
   775   template <typename VP, typename EP, typename GP, typename A>
       
   776   std::pair<
       
   777     typename adjacency_matrix<undirectedS,VP,EP,GP,A>::in_edge_iterator,
       
   778     typename adjacency_matrix<undirectedS,VP,EP,GP,A>::in_edge_iterator>
       
   779   in_edges
       
   780     (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u,
       
   781      const adjacency_matrix<undirectedS,VP,EP,GP,A>& g_)
       
   782   {
       
   783     typedef adjacency_matrix<undirectedS,VP,EP,GP,A> Graph;
       
   784     Graph& g = const_cast<Graph&>(g_);
       
   785     typename Graph::vertices_size_type offset = u * (u + 1) / 2;
       
   786     typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
       
   787     typename Graph::MatrixIter l = g.m_matrix.end();
       
   788 
       
   789     typename Graph::unfiltered_in_edge_iter
       
   790         first(f, u, g.m_vertex_set.size())
       
   791       , last(l, u, g.m_vertex_set.size());
       
   792     
       
   793     detail::does_edge_exist pred;
       
   794     typedef typename Graph::in_edge_iterator in_edge_iterator;
       
   795     return std::make_pair(in_edge_iterator(pred, first, last), 
       
   796                           in_edge_iterator(pred, last, last));
       
   797   }
       
   798   
       
   799   // O(N)
       
   800   template <typename D, typename VP, typename EP, typename GP, typename A>  
       
   801   typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type
       
   802   in_degree(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
       
   803              const adjacency_matrix<D,VP,EP,GP,A>& g)
       
   804   {
       
   805     typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type n = 0;
       
   806     typename adjacency_matrix<D,VP,EP,GP,A>::in_edge_iterator f, l;
       
   807     for (tie(f, l) = in_edges(u, g); f != l; ++f)
       
   808       ++n;
       
   809     return n;
       
   810   }
       
   811 
       
   812   //=========================================================================
       
   813   // Functions required by the AdjacencyGraph concept 
       
   814 
       
   815   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   816   std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::adjacency_iterator,
       
   817             typename adjacency_matrix<D,VP,EP,GP,A>::adjacency_iterator>
       
   818   adjacent_vertices
       
   819     (typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
       
   820      const adjacency_matrix<D,VP,EP,GP,A>& g_)
       
   821   {
       
   822       typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
       
   823       const Graph& cg = static_cast<const Graph&>(g_);
       
   824       Graph& g = const_cast<Graph&>(cg);
       
   825       typedef typename Graph::adjacency_iterator adjacency_iterator;
       
   826       typename Graph::out_edge_iterator first, last;
       
   827       boost::tie(first, last) = out_edges(u, g);
       
   828       return std::make_pair(adjacency_iterator(first, &g),
       
   829                             adjacency_iterator(last, &g));
       
   830   }
       
   831 
       
   832   //=========================================================================
       
   833   // Functions required by the VertexListGraph concept 
       
   834 
       
   835   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   836   std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::vertex_iterator,
       
   837             typename adjacency_matrix<D,VP,EP,GP,A>::vertex_iterator>
       
   838   vertices(const adjacency_matrix<D,VP,EP,GP,A>& g_) {
       
   839     typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
       
   840     Graph& g = const_cast<Graph&>(g_);
       
   841     return std::make_pair(g.m_vertex_set.begin(), g.m_vertex_set.end());
       
   842   }
       
   843 
       
   844   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   845   typename adjacency_matrix<D,VP,EP,GP,A>::vertices_size_type
       
   846   num_vertices(const adjacency_matrix<D,VP,EP,GP,A>& g) {
       
   847     return g.m_vertex_set.size();
       
   848   }
       
   849   
       
   850   //=========================================================================
       
   851   // Functions required by the EdgeListGraph concept 
       
   852   
       
   853   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   854   std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_iterator,
       
   855             typename adjacency_matrix<D,VP,EP,GP,A>::edge_iterator>
       
   856   edges(const adjacency_matrix<D,VP,EP,GP,A>& g_)
       
   857   {
       
   858     typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
       
   859     Graph& g = const_cast<Graph&>(g_);
       
   860     
       
   861     typename Graph::unfiltered_edge_iter
       
   862       first(g.m_matrix.begin(), g.m_matrix.begin(), 
       
   863                                     g.m_vertex_set.size()),
       
   864       last(g.m_matrix.end(), g.m_matrix.begin(), 
       
   865                                     g.m_vertex_set.size());
       
   866     detail::does_edge_exist pred;
       
   867     typedef typename Graph::edge_iterator edge_iterator;
       
   868     return std::make_pair(edge_iterator(pred, first, last),
       
   869                           edge_iterator(pred, last, last));
       
   870   }
       
   871 
       
   872   // O(1)
       
   873   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   874   typename adjacency_matrix<D,VP,EP,GP,A>::edges_size_type
       
   875   num_edges(const adjacency_matrix<D,VP,EP,GP,A>& g)
       
   876   {
       
   877     return g.m_num_edges;
       
   878   }
       
   879   
       
   880   //=========================================================================
       
   881   // Functions required by the MutableGraph concept 
       
   882 
       
   883   // O(1)
       
   884   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   885   std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor, bool>
       
   886   add_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
       
   887            typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
       
   888            const EP& ep,
       
   889            adjacency_matrix<D,VP,EP,GP,A>& g)
       
   890   {
       
   891     typedef typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor 
       
   892       edge_descriptor;
       
   893     if (detail::get_edge_exists(g.get_edge(u,v), 0) == false) {
       
   894       ++(g.m_num_edges);
       
   895       detail::set_property(g.get_edge(u,v), ep, 0);
       
   896       detail::set_edge_exists(g.get_edge(u,v), true, 0);
       
   897       return std::make_pair
       
   898         (edge_descriptor(true, u, v, &detail::get_property(g.get_edge(u,v))), 
       
   899          true);
       
   900     } else
       
   901       return std::make_pair
       
   902         (edge_descriptor(true, u, v, &detail::get_property(g.get_edge(u,v))),
       
   903          false);
       
   904   }
       
   905   // O(1)
       
   906   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   907   std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor, bool>
       
   908   add_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
       
   909            typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
       
   910            adjacency_matrix<D,VP,EP,GP,A>& g)
       
   911   {
       
   912     EP ep;
       
   913     return add_edge(u, v, ep, g);
       
   914   }
       
   915 
       
   916   // O(1)  
       
   917   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   918   void
       
   919   remove_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
       
   920               typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
       
   921               adjacency_matrix<D,VP,EP,GP,A>& g)
       
   922   {
       
   923     --(g.m_num_edges);
       
   924     detail::set_edge_exists(g.get_edge(u,v), false, 0);
       
   925   }
       
   926 
       
   927   // O(1)
       
   928   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   929   void
       
   930   remove_edge(typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor e,
       
   931               adjacency_matrix<D,VP,EP,GP,A>& g)
       
   932   {
       
   933     remove_edge(source(e, g), target(e, g), g);
       
   934   }
       
   935 
       
   936   
       
   937   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   938   inline typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
       
   939   add_vertex(adjacency_matrix<D,VP,EP,GP,A>& g) {
       
   940     // UNDER CONSTRUCTION
       
   941     assert(false);
       
   942     return *vertices(g).first;
       
   943   }
       
   944 
       
   945   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   946   inline typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
       
   947   add_vertex(const VP& vp, adjacency_matrix<D,VP,EP,GP,A>& g) {
       
   948     // UNDER CONSTRUCTION
       
   949     assert(false);
       
   950     return *vertices(g).first;
       
   951   }
       
   952 
       
   953   template <typename D, typename VP, typename EP, typename GP, typename A>
       
   954   inline void
       
   955   remove_vertex(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
       
   956                 adjacency_matrix<D,VP,EP,GP,A>& g)
       
   957   {
       
   958     // UNDER CONSTRUCTION
       
   959     assert(false);
       
   960   }
       
   961 
       
   962   // O(V)
       
   963   template <typename VP, typename EP, typename GP, typename A>
       
   964   void
       
   965   clear_vertex
       
   966     (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u,
       
   967      adjacency_matrix<directedS,VP,EP,GP,A>& g)
       
   968   {
       
   969     typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_iterator 
       
   970       vi, vi_end;
       
   971     for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
       
   972       remove_edge(u, *vi, g);
       
   973     for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
       
   974       remove_edge(*vi, u, g);
       
   975   }
       
   976 
       
   977   // O(V)
       
   978   template <typename VP, typename EP, typename GP, typename A>
       
   979   void
       
   980   clear_vertex
       
   981     (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u,
       
   982      adjacency_matrix<undirectedS,VP,EP,GP,A>& g)
       
   983   {
       
   984     typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_iterator
       
   985       vi, vi_end;
       
   986     for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
       
   987       remove_edge(u, *vi, g);
       
   988   }
       
   989 
       
   990   //=========================================================================
       
   991   // Vertex Property Map
       
   992   
       
   993   template <typename GraphPtr, typename Vertex, typename T, typename R, 
       
   994     typename Tag> 
       
   995   class adj_matrix_vertex_property_map 
       
   996     : public put_get_helper<R,
       
   997          adj_matrix_vertex_property_map<GraphPtr, Vertex, T, R, Tag> >
       
   998   {
       
   999   public:
       
  1000     typedef T value_type;
       
  1001     typedef R reference;
       
  1002     typedef Vertex key_type;
       
  1003     typedef boost::lvalue_property_map_tag category;
       
  1004     adj_matrix_vertex_property_map() { }
       
  1005     adj_matrix_vertex_property_map(GraphPtr g) : m_g(g) { }
       
  1006     inline reference operator[](key_type v) const {
       
  1007       return get_property_value(m_g->m_vertex_properties[v], Tag());
       
  1008     }
       
  1009     GraphPtr m_g;
       
  1010   };
       
  1011 
       
  1012   template <class Property, class Vertex>
       
  1013   struct adj_matrix_vertex_id_map
       
  1014     : public boost::put_get_helper<Vertex,
       
  1015         adj_matrix_vertex_id_map<Property, Vertex> >
       
  1016   {
       
  1017     typedef Vertex value_type;
       
  1018     typedef Vertex reference;
       
  1019     typedef Vertex key_type;
       
  1020     typedef boost::readable_property_map_tag category;
       
  1021      adj_matrix_vertex_id_map() { }
       
  1022     template <class Graph>
       
  1023     inline adj_matrix_vertex_id_map(const Graph&) { }
       
  1024     inline value_type operator[](key_type v) const { return v; }
       
  1025   };
       
  1026 
       
  1027   namespace detail {
       
  1028 
       
  1029     struct adj_matrix_any_vertex_pa {
       
  1030       template <class Tag, class Graph, class Property>
       
  1031       struct bind_ {
       
  1032         typedef typename property_value<Property,Tag>::type Value;
       
  1033         typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
       
  1034         
       
  1035         typedef adj_matrix_vertex_property_map<Graph*, Vertex, Value, Value&,
       
  1036           Tag> type;
       
  1037         typedef adj_matrix_vertex_property_map<const Graph*, Vertex, Value, 
       
  1038           const Value&, Tag> const_type;
       
  1039       };
       
  1040     };
       
  1041     struct adj_matrix_id_vertex_pa {
       
  1042       template <class Tag, class Graph, class Property>
       
  1043       struct bind_ {
       
  1044         typedef typename Graph::vertex_descriptor Vertex;
       
  1045         typedef adj_matrix_vertex_id_map<Property, Vertex> type;
       
  1046         typedef adj_matrix_vertex_id_map<Property, Vertex> const_type;
       
  1047       };
       
  1048     };
       
  1049 
       
  1050     template <class Tag>
       
  1051     struct adj_matrix_choose_vertex_pa_helper {
       
  1052       typedef adj_matrix_any_vertex_pa type;
       
  1053     };
       
  1054     template <>
       
  1055     struct adj_matrix_choose_vertex_pa_helper<vertex_index_t> {
       
  1056       typedef adj_matrix_id_vertex_pa type;
       
  1057     };
       
  1058 
       
  1059     template <class Tag, class Graph, class Property>
       
  1060     struct adj_matrix_choose_vertex_pa {
       
  1061       typedef typename adj_matrix_choose_vertex_pa_helper<Tag>::type Helper;
       
  1062       typedef typename Helper::template bind_<Tag,Graph,Property> Bind;
       
  1063       typedef typename Bind::type type;
       
  1064       typedef typename Bind::const_type const_type;
       
  1065     };
       
  1066 
       
  1067     struct adj_matrix_vertex_property_selector {
       
  1068       template <class Graph, class Property, class Tag>
       
  1069       struct bind_ {
       
  1070         typedef adj_matrix_choose_vertex_pa<Tag,Graph,Property> Choice;
       
  1071         typedef typename Choice::type type;
       
  1072         typedef typename Choice::const_type const_type;
       
  1073       };
       
  1074     };
       
  1075 
       
  1076   } // namespace detail
       
  1077 
       
  1078   template <>
       
  1079   struct vertex_property_selector<adjacency_matrix_class_tag> {
       
  1080     typedef detail::adj_matrix_vertex_property_selector type;
       
  1081   };
       
  1082   
       
  1083   //=========================================================================
       
  1084   // Edge Property Map
       
  1085 
       
  1086 
       
  1087   template <typename Directed, typename Property, typename Vertex, 
       
  1088     typename T, typename R, typename Tag> 
       
  1089   class adj_matrix_edge_property_map 
       
  1090     : public put_get_helper<R,
       
  1091          adj_matrix_edge_property_map<Directed, Property, Vertex, T, R, Tag> >
       
  1092   {
       
  1093   public:
       
  1094     typedef T value_type;
       
  1095     typedef R reference;
       
  1096     typedef detail::matrix_edge_desc_impl<Directed, Vertex> key_type;
       
  1097     typedef boost::lvalue_property_map_tag category;
       
  1098     inline reference operator[](key_type e) const {
       
  1099       Property& p = *(Property*)e.get_property();
       
  1100       return get_property_value(p, Tag());
       
  1101     }
       
  1102   };
       
  1103   struct adj_matrix_edge_property_selector {
       
  1104     template <class Graph, class Property, class Tag>
       
  1105     struct bind_ {
       
  1106       typedef typename property_value<Property,Tag>::type T;
       
  1107       typedef typename Graph::vertex_descriptor Vertex;
       
  1108       typedef adj_matrix_edge_property_map<typename Graph::directed_category,
       
  1109         Property, Vertex, T, T&, Tag> type;
       
  1110       typedef adj_matrix_edge_property_map<typename Graph::directed_category,
       
  1111         Property, Vertex, T, const T&, Tag> const_type;
       
  1112     };
       
  1113   };
       
  1114   template <>
       
  1115   struct edge_property_selector<adjacency_matrix_class_tag> {
       
  1116     typedef adj_matrix_edge_property_selector type;
       
  1117   };
       
  1118 
       
  1119   //=========================================================================
       
  1120   // Functions required by PropertyGraph
       
  1121 
       
  1122   namespace detail {
       
  1123 
       
  1124     template <typename Property, typename D, typename VP, typename EP, 
       
  1125               typename GP, typename A>
       
  1126     typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
       
  1127       Property>::type
       
  1128     get_dispatch(adjacency_matrix<D,VP,EP,GP,A>& g, Property,
       
  1129                  vertex_property_tag)
       
  1130     {
       
  1131       typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
       
  1132       typedef typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
       
  1133         Property>::type PA;
       
  1134       return PA(&g);
       
  1135     }
       
  1136     template <typename Property, typename D, typename VP, typename EP, 
       
  1137               typename GP, typename A>
       
  1138     typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
       
  1139       Property>::type
       
  1140     get_dispatch(adjacency_matrix<D,VP,EP,GP,A>&, Property,
       
  1141                  edge_property_tag)
       
  1142     {
       
  1143       typedef typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
       
  1144         Property>::type PA;
       
  1145       return PA();
       
  1146     }
       
  1147     template <typename Property, typename D, typename VP, typename EP, 
       
  1148               typename GP, typename A>
       
  1149     typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
       
  1150       Property>::const_type
       
  1151     get_dispatch(const adjacency_matrix<D,VP,EP,GP,A>& g, Property,
       
  1152                  vertex_property_tag)
       
  1153     {
       
  1154       typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
       
  1155       typedef typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
       
  1156         Property>::const_type PA;
       
  1157       return PA(&g);
       
  1158     }
       
  1159     template <typename Property, typename D, typename VP, typename EP, 
       
  1160               typename GP, typename A>
       
  1161     typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
       
  1162       Property>::const_type
       
  1163     get_dispatch(const adjacency_matrix<D,VP,EP,GP,A>&, Property,
       
  1164                  edge_property_tag)
       
  1165     {
       
  1166       typedef typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
       
  1167         Property>::const_type PA;
       
  1168       return PA();
       
  1169     }
       
  1170 
       
  1171   } // namespace detail
       
  1172 
       
  1173   template <typename Property, typename D, typename VP, typename EP, 
       
  1174             typename GP, typename A>
       
  1175   inline
       
  1176   typename property_map<adjacency_matrix<D,VP,EP,GP,A>, Property>::type
       
  1177   get(Property p, adjacency_matrix<D,VP,EP,GP,A>& g)
       
  1178   {
       
  1179     typedef typename property_kind<Property>::type Kind;
       
  1180     return detail::get_dispatch(g, p, Kind());
       
  1181   }
       
  1182 
       
  1183   template <typename Property, typename D, typename VP, typename EP, 
       
  1184             typename GP, typename A>
       
  1185   inline
       
  1186   typename property_map<adjacency_matrix<D,VP,EP,GP,A>, Property>::const_type
       
  1187   get(Property p, const adjacency_matrix<D,VP,EP,GP,A>& g)
       
  1188   {
       
  1189     typedef typename property_kind<Property>::type Kind;
       
  1190     return detail::get_dispatch(g, p, Kind());
       
  1191   }
       
  1192 
       
  1193   template <typename Property, typename D, typename VP, typename EP, 
       
  1194             typename GP, typename A, typename Key>
       
  1195   inline
       
  1196   typename property_traits<
       
  1197     typename property_map<adjacency_matrix<D,VP,EP,GP,A>, Property>::const_type
       
  1198   >::value_type
       
  1199   get(Property p, const adjacency_matrix<D,VP,EP,GP,A>& g,
       
  1200       const Key& key)
       
  1201   {
       
  1202     return get(get(p, g), key);
       
  1203   }
       
  1204 
       
  1205   template <typename Property, typename D, typename VP, typename EP, 
       
  1206             typename GP, typename A, typename Key, typename Value>
       
  1207   inline void
       
  1208   put(Property p, adjacency_matrix<D,VP,EP,GP,A>& g,
       
  1209       const Key& key, const Value& value)
       
  1210   {
       
  1211     typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
       
  1212     typedef typename boost::property_map<Graph, Property>::type Map;
       
  1213     Map pmap = get(p, g);
       
  1214     put(pmap, key, value);
       
  1215   }
       
  1216   
       
  1217   //=========================================================================
       
  1218   // Other Functions
       
  1219 
       
  1220   template <typename D, typename VP, typename EP, typename GP, typename A>  
       
  1221   typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
       
  1222   vertex(typename adjacency_matrix<D,VP,EP,GP,A>::vertices_size_type n,
       
  1223          const adjacency_matrix<D,VP,EP,GP,A>& g)
       
  1224   {
       
  1225     return n;
       
  1226   }
       
  1227 
       
  1228   // Support for bundled properties
       
  1229 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
       
  1230   template <typename Directed, typename VertexProperty, typename EdgeProperty, typename GraphProperty,
       
  1231             typename Allocator, typename T, typename Bundle>
       
  1232   inline
       
  1233   typename property_map<adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>,
       
  1234                         T Bundle::*>::type
       
  1235   get(T Bundle::* p, adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>& g)
       
  1236   {
       
  1237     typedef typename property_map<adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>,
       
  1238                                   T Bundle::*>::type
       
  1239       result_type;
       
  1240     return result_type(&g, p);
       
  1241   }
       
  1242 
       
  1243   template <typename Directed, typename VertexProperty, typename EdgeProperty, typename GraphProperty,
       
  1244             typename Allocator, typename T, typename Bundle>
       
  1245   inline
       
  1246   typename property_map<adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>,
       
  1247                         T Bundle::*>::const_type
       
  1248   get(T Bundle::* p, adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator> const & g)
       
  1249   {
       
  1250     typedef typename property_map<adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>,
       
  1251                                   T Bundle::*>::const_type
       
  1252       result_type;
       
  1253     return result_type(&g, p);
       
  1254   }
       
  1255     
       
  1256   template <typename Directed, typename VertexProperty, typename EdgeProperty, typename GraphProperty,
       
  1257             typename Allocator, typename T, typename Bundle, typename Key>
       
  1258   inline T
       
  1259   get(T Bundle::* p, adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator> const & g,
       
  1260       const Key& key)
       
  1261   {
       
  1262     return get(get(p, g), key);
       
  1263   }
       
  1264 
       
  1265   template <typename Directed, typename VertexProperty, typename EdgeProperty, typename GraphProperty,
       
  1266             typename Allocator, typename T, typename Bundle, typename Key>
       
  1267   inline void
       
  1268   put(T Bundle::* p, adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>& g,
       
  1269       const Key& key, const T& value)
       
  1270   {
       
  1271     put(get(p, g), key, value);
       
  1272   }
       
  1273 
       
  1274 #endif
       
  1275 
       
  1276 } // namespace boost
       
  1277 
       
  1278 #endif // BOOST_ADJACENCY_MATRIX_HPP