Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:37:22

0001 //=======================================================================
0002 // Copyright 2001 University of Notre Dame.
0003 // Copyright 2006 Trustees of Indiana University
0004 // Authors: Jeremy G. Siek and Douglas Gregor <dgregor@cs.indiana.edu>
0005 //
0006 // Distributed under the Boost Software License, Version 1.0. (See
0007 // accompanying file LICENSE_1_0.txt or copy at
0008 // http://www.boost.org/LICENSE_1_0.txt)
0009 //=======================================================================
0010 
0011 #ifndef BOOST_ADJACENCY_MATRIX_HPP
0012 #define BOOST_ADJACENCY_MATRIX_HPP
0013 
0014 #include <boost/config.hpp>
0015 #include <vector>
0016 #include <memory>
0017 #include <iterator>
0018 #include <boost/assert.hpp>
0019 #include <boost/limits.hpp>
0020 #include <boost/graph/graph_traits.hpp>
0021 #include <boost/graph/graph_mutability_traits.hpp>
0022 #include <boost/graph/graph_selectors.hpp>
0023 #include <boost/mpl/if.hpp>
0024 #include <boost/mpl/bool.hpp>
0025 #include <boost/graph/adjacency_iterator.hpp>
0026 #include <boost/graph/detail/edge.hpp>
0027 #include <boost/iterator/iterator_adaptor.hpp>
0028 #include <boost/iterator/filter_iterator.hpp>
0029 #include <boost/range/irange.hpp>
0030 #include <boost/graph/properties.hpp>
0031 #include <boost/tuple/tuple.hpp>
0032 #include <boost/static_assert.hpp>
0033 #include <boost/type_traits.hpp>
0034 #include <boost/property_map/property_map.hpp>
0035 #include <boost/property_map/transform_value_property_map.hpp>
0036 #include <boost/property_map/function_property_map.hpp>
0037 
0038 namespace boost
0039 {
0040 
0041 namespace detail
0042 {
0043 
0044     template < class Directed, class Vertex >
0045     class matrix_edge_desc_impl : public edge_desc_impl< Directed, Vertex >
0046     {
0047         typedef edge_desc_impl< Directed, Vertex > Base;
0048 
0049     public:
0050         matrix_edge_desc_impl() {}
0051         matrix_edge_desc_impl(
0052             bool exists, Vertex s, Vertex d, const void* ep = 0)
0053         : Base(s, d, ep), m_exists(exists)
0054         {
0055         }
0056         bool exists() const { return m_exists; }
0057 
0058     private:
0059         bool m_exists;
0060     };
0061 
0062     struct does_edge_exist
0063     {
0064         template < class Edge > bool operator()(const Edge& e) const
0065         {
0066             return e.exists();
0067         }
0068     };
0069 
0070     // Note to self... The int for get_edge_exists and set_edge exist helps
0071     // make these calls unambiguous.
0072     template < typename EdgeProperty >
0073     bool get_edge_exists(
0074         const std::pair< bool, EdgeProperty >& stored_edge, int)
0075     {
0076         return stored_edge.first;
0077     }
0078     template < typename EdgeProperty >
0079     void set_edge_exists(
0080         std::pair< bool, EdgeProperty >& stored_edge, bool flag, int)
0081     {
0082         stored_edge.first = flag;
0083     }
0084 
0085     template < typename EdgeProxy >
0086     bool get_edge_exists(const EdgeProxy& edge_proxy, ...)
0087     {
0088         return edge_proxy;
0089     }
0090     template < typename EdgeProxy >
0091     EdgeProxy& set_edge_exists(EdgeProxy& edge_proxy, bool flag, ...)
0092     {
0093         edge_proxy = flag;
0094         return edge_proxy; // just to avoid never used warning
0095     }
0096 
0097     // NOTE: These functions collide with the get_property function for
0098     // accessing bundled graph properties. Be excplicit when using them.
0099     template < typename EdgeProperty >
0100     const EdgeProperty& get_edge_property(
0101         const std::pair< bool, EdgeProperty >& stored_edge)
0102     {
0103         return stored_edge.second;
0104     }
0105     template < typename EdgeProperty >
0106     EdgeProperty& get_edge_property(
0107         std::pair< bool, EdgeProperty >& stored_edge)
0108     {
0109         return stored_edge.second;
0110     }
0111 
0112     template < typename StoredEdgeProperty, typename EdgeProperty >
0113     inline void set_edge_property(
0114         std::pair< bool, StoredEdgeProperty >& stored_edge,
0115         const EdgeProperty& ep, int)
0116     {
0117         stored_edge.second = ep;
0118     }
0119 
0120     inline const no_property& get_edge_property(const char&)
0121     {
0122         static no_property s_prop;
0123         return s_prop;
0124     }
0125     inline no_property& get_edge_property(char&)
0126     {
0127         static no_property s_prop;
0128         return s_prop;
0129     }
0130     template < typename EdgeProxy, typename EdgeProperty >
0131     inline void set_edge_property(EdgeProxy, const EdgeProperty&, ...)
0132     {
0133     }
0134 
0135     //=======================================================================
0136     // Directed Out Edge Iterator
0137 
0138     template < typename VertexDescriptor, typename MatrixIter,
0139         typename VerticesSizeType, typename EdgeDescriptor >
0140     struct dir_adj_matrix_out_edge_iter
0141     : iterator_adaptor< dir_adj_matrix_out_edge_iter< VertexDescriptor,
0142                             MatrixIter, VerticesSizeType, EdgeDescriptor >,
0143           MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
0144           std::ptrdiff_t >
0145     {
0146         typedef iterator_adaptor<
0147             dir_adj_matrix_out_edge_iter< VertexDescriptor, MatrixIter,
0148                 VerticesSizeType, EdgeDescriptor >,
0149             MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
0150             std::ptrdiff_t >
0151             super_t;
0152 
0153         dir_adj_matrix_out_edge_iter() {}
0154 
0155         dir_adj_matrix_out_edge_iter(const MatrixIter& i,
0156             const VertexDescriptor& src, const VerticesSizeType& n)
0157         : super_t(i), m_src(src), m_targ(0), m_n(n)
0158         {
0159         }
0160 
0161         void increment()
0162         {
0163             ++this->base_reference();
0164             ++m_targ;
0165         }
0166 
0167         inline EdgeDescriptor dereference() const
0168         {
0169             return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src,
0170                 m_targ, &get_edge_property(*this->base()));
0171         }
0172         VertexDescriptor m_src, m_targ;
0173         VerticesSizeType m_n;
0174     };
0175 
0176     //=======================================================================
0177     // Directed In Edge Iterator
0178 
0179     template < typename VertexDescriptor, typename MatrixIter,
0180         typename VerticesSizeType, typename EdgeDescriptor >
0181     struct dir_adj_matrix_in_edge_iter
0182     : iterator_adaptor< dir_adj_matrix_in_edge_iter< VertexDescriptor,
0183                             MatrixIter, VerticesSizeType, EdgeDescriptor >,
0184           MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
0185           std::ptrdiff_t >
0186     {
0187         typedef iterator_adaptor<
0188             dir_adj_matrix_in_edge_iter< VertexDescriptor, MatrixIter,
0189                 VerticesSizeType, EdgeDescriptor >,
0190             MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
0191             std::ptrdiff_t >
0192             super_t;
0193 
0194         dir_adj_matrix_in_edge_iter() {}
0195 
0196         dir_adj_matrix_in_edge_iter(const MatrixIter& i, const MatrixIter& last,
0197             const VertexDescriptor& tgt, const VerticesSizeType& n)
0198         : super_t(i), m_last(last), m_src(0), m_targ(tgt), m_n(n)
0199         {
0200         }
0201 
0202         void increment()
0203         {
0204             if (VerticesSizeType(m_last - this->base_reference()) >= m_n)
0205             {
0206                 this->base_reference() += m_n;
0207                 ++m_src;
0208             }
0209             else
0210             {
0211                 this->base_reference() = m_last;
0212             }
0213         }
0214 
0215         inline EdgeDescriptor dereference() const
0216         {
0217             return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src,
0218                 m_targ, &get_edge_property(*this->base()));
0219         }
0220         MatrixIter m_last;
0221         VertexDescriptor m_src, m_targ;
0222         VerticesSizeType m_n;
0223     };
0224 
0225     //=======================================================================
0226     // Undirected Out Edge Iterator
0227 
0228     template < typename VertexDescriptor, typename MatrixIter,
0229         typename VerticesSizeType, typename EdgeDescriptor >
0230     struct undir_adj_matrix_out_edge_iter
0231     : iterator_adaptor< undir_adj_matrix_out_edge_iter< VertexDescriptor,
0232                             MatrixIter, VerticesSizeType, EdgeDescriptor >,
0233           MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
0234           std::ptrdiff_t >
0235     {
0236         typedef iterator_adaptor<
0237             undir_adj_matrix_out_edge_iter< VertexDescriptor, MatrixIter,
0238                 VerticesSizeType, EdgeDescriptor >,
0239             MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
0240             std::ptrdiff_t >
0241             super_t;
0242 
0243         undir_adj_matrix_out_edge_iter() {}
0244 
0245         undir_adj_matrix_out_edge_iter(const MatrixIter& i,
0246             const VertexDescriptor& src, const VerticesSizeType& n)
0247         : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n)
0248         {
0249         }
0250 
0251         void increment()
0252         {
0253             if (m_targ < m_src) // first half
0254             {
0255                 ++this->base_reference();
0256             }
0257             else if (m_targ < m_n - 1)
0258             { // second half
0259                 ++m_inc;
0260                 this->base_reference() += m_inc;
0261             }
0262             else
0263             { // past-the-end
0264                 this->base_reference() += m_n - m_src;
0265             }
0266             ++m_targ;
0267         }
0268 
0269         inline EdgeDescriptor dereference() const
0270         {
0271             return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src,
0272                 m_targ, &get_edge_property(*this->base()));
0273         }
0274 
0275         VertexDescriptor m_src, m_inc, m_targ;
0276         VerticesSizeType m_n;
0277     };
0278 
0279     //=======================================================================
0280     // Undirected In Edge Iterator
0281 
0282     template < typename VertexDescriptor, typename MatrixIter,
0283         typename VerticesSizeType, typename EdgeDescriptor >
0284     struct undir_adj_matrix_in_edge_iter
0285     : iterator_adaptor< undir_adj_matrix_in_edge_iter< VertexDescriptor,
0286                             MatrixIter, VerticesSizeType, EdgeDescriptor >,
0287           MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
0288           std::ptrdiff_t >
0289     {
0290         typedef iterator_adaptor<
0291             undir_adj_matrix_in_edge_iter< VertexDescriptor, MatrixIter,
0292                 VerticesSizeType, EdgeDescriptor >,
0293             MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
0294             std::ptrdiff_t >
0295             super_t;
0296 
0297         undir_adj_matrix_in_edge_iter() {}
0298 
0299         undir_adj_matrix_in_edge_iter(const MatrixIter& i,
0300             const VertexDescriptor& src, const VerticesSizeType& n)
0301         : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n)
0302         {
0303         }
0304 
0305         void increment()
0306         {
0307             if (m_targ < m_src) // first half
0308             {
0309                 ++this->base_reference();
0310             }
0311             else if (m_targ < m_n - 1)
0312             { // second half
0313                 ++m_inc;
0314                 this->base_reference() += m_inc;
0315             }
0316             else
0317             { // past-the-end
0318                 this->base_reference() += m_n - m_src;
0319             }
0320             ++m_targ;
0321         }
0322 
0323         inline EdgeDescriptor dereference() const
0324         {
0325             return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_targ,
0326                 m_src, &get_edge_property(*this->base()));
0327         }
0328 
0329         VertexDescriptor m_src, m_inc, m_targ;
0330         VerticesSizeType m_n;
0331     };
0332 
0333     //=======================================================================
0334     // Edge Iterator
0335 
0336     template < typename Directed, typename MatrixIter,
0337         typename VerticesSizeType, typename EdgeDescriptor >
0338     struct adj_matrix_edge_iter
0339     : iterator_adaptor< adj_matrix_edge_iter< Directed, MatrixIter,
0340                             VerticesSizeType, EdgeDescriptor >,
0341           MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
0342           std::ptrdiff_t >
0343     {
0344         typedef iterator_adaptor< adj_matrix_edge_iter< Directed, MatrixIter,
0345                                       VerticesSizeType, EdgeDescriptor >,
0346             MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
0347             std::ptrdiff_t >
0348             super_t;
0349 
0350         adj_matrix_edge_iter() {}
0351 
0352         adj_matrix_edge_iter(const MatrixIter& i, const MatrixIter& start,
0353             const VerticesSizeType& n)
0354         : super_t(i), m_start(start), m_src(0), m_targ(0), m_n(n)
0355         {
0356         }
0357 
0358         void increment()
0359         {
0360             increment_dispatch(this->base_reference(), Directed());
0361         }
0362 
0363         void increment_dispatch(MatrixIter& i, directedS)
0364         {
0365             ++i;
0366             if (m_targ == m_n - 1)
0367             {
0368                 m_targ = 0;
0369                 ++m_src;
0370             }
0371             else
0372             {
0373                 ++m_targ;
0374             }
0375         }
0376 
0377         void increment_dispatch(MatrixIter& i, undirectedS)
0378         {
0379             ++i;
0380             if (m_targ == m_src)
0381             {
0382                 m_targ = 0;
0383                 ++m_src;
0384             }
0385             else
0386             {
0387                 ++m_targ;
0388             }
0389         }
0390 
0391         inline EdgeDescriptor dereference() const
0392         {
0393             return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src,
0394                 m_targ, &get_edge_property(*this->base()));
0395         }
0396 
0397         MatrixIter m_start;
0398         VerticesSizeType m_src, m_targ, m_n;
0399     };
0400 
0401 } // namespace detail
0402 
0403 //=========================================================================
0404 // Adjacency Matrix Traits
0405 template < typename Directed = directedS > class adjacency_matrix_traits
0406 {
0407     typedef typename Directed::is_directed_t is_directed;
0408 
0409 public:
0410     // The bidirectionalS tag is not allowed with the adjacency_matrix
0411     // graph type. Instead, use directedS, which also provides the
0412     // functionality required for a Bidirectional Graph (in_edges,
0413     // in_degree, etc.).
0414     BOOST_STATIC_ASSERT(!(is_same< Directed, bidirectionalS >::value));
0415 
0416     typedef typename mpl::if_< is_directed, bidirectional_tag,
0417         undirected_tag >::type directed_category;
0418 
0419     typedef disallow_parallel_edge_tag edge_parallel_category;
0420 
0421     typedef std::size_t vertex_descriptor;
0422 
0423     typedef detail::matrix_edge_desc_impl< directed_category,
0424         vertex_descriptor >
0425         edge_descriptor;
0426 };
0427 
0428 struct adjacency_matrix_class_tag
0429 {
0430 };
0431 
0432 struct adj_matrix_traversal_tag : public virtual adjacency_matrix_tag,
0433                                   public virtual vertex_list_graph_tag,
0434                                   public virtual incidence_graph_tag,
0435                                   public virtual adjacency_graph_tag,
0436                                   public virtual edge_list_graph_tag
0437 {
0438 };
0439 
0440 //=========================================================================
0441 // Adjacency Matrix Class
0442 template < typename Directed = directedS, typename VertexProperty = no_property,
0443     typename EdgeProperty = no_property, typename GraphProperty = no_property,
0444     typename Allocator = std::allocator< bool > >
0445 class adjacency_matrix
0446 {
0447     typedef adjacency_matrix self;
0448     typedef adjacency_matrix_traits< Directed > Traits;
0449 
0450 public:
0451     // The bidirectionalS tag is not allowed with the adjacency_matrix
0452     // graph type. Instead, use directedS, which also provides the
0453     // functionality required for a Bidirectional Graph (in_edges,
0454     // in_degree, etc.).
0455     BOOST_STATIC_ASSERT(!(is_same< Directed, bidirectionalS >::value));
0456 
0457     typedef GraphProperty graph_property_type;
0458     typedef typename lookup_one_property< GraphProperty, graph_bundle_t >::type
0459         graph_bundled;
0460 
0461     typedef VertexProperty vertex_property_type;
0462     typedef
0463         typename lookup_one_property< VertexProperty, vertex_bundle_t >::type
0464             vertex_bundled;
0465 
0466     typedef EdgeProperty edge_property_type;
0467     typedef typename lookup_one_property< EdgeProperty, edge_bundle_t >::type
0468         edge_bundled;
0469 
0470 public: // should be private
0471     typedef
0472         typename mpl::if_< typename has_property< edge_property_type >::type,
0473             std::pair< bool, edge_property_type >, char >::type StoredEdge;
0474 #if defined(BOOST_NO_STD_ALLOCATOR)
0475     typedef std::vector< StoredEdge > Matrix;
0476 #else
0477 #if defined(BOOST_NO_CXX11_ALLOCATOR)
0478     typedef typename Allocator::template rebind< StoredEdge >::other Alloc;
0479 #else
0480     typedef typename std::allocator_traits< Allocator >::template rebind_alloc<
0481         StoredEdge >
0482         Alloc;
0483 #endif
0484     typedef std::vector< StoredEdge, Alloc > Matrix;
0485 #endif
0486     typedef typename Matrix::iterator MatrixIter;
0487     typedef typename Matrix::size_type size_type;
0488 
0489 public:
0490     // Graph concept required types
0491     typedef typename Traits::vertex_descriptor vertex_descriptor;
0492     typedef typename Traits::edge_descriptor edge_descriptor;
0493     typedef typename Traits::directed_category directed_category;
0494     typedef typename Traits::edge_parallel_category edge_parallel_category;
0495     typedef adj_matrix_traversal_tag traversal_category;
0496 
0497     static vertex_descriptor null_vertex()
0498     {
0499         return (std::numeric_limits< vertex_descriptor >::max)();
0500     }
0501 
0502     // private: if friends worked, these would be private
0503 
0504     typedef detail::dir_adj_matrix_out_edge_iter< vertex_descriptor, MatrixIter,
0505         size_type, edge_descriptor >
0506         DirOutEdgeIter;
0507 
0508     typedef detail::undir_adj_matrix_out_edge_iter< vertex_descriptor,
0509         MatrixIter, size_type, edge_descriptor >
0510         UnDirOutEdgeIter;
0511 
0512     typedef typename mpl::if_< typename Directed::is_directed_t, DirOutEdgeIter,
0513         UnDirOutEdgeIter >::type unfiltered_out_edge_iter;
0514 
0515     typedef detail::dir_adj_matrix_in_edge_iter< vertex_descriptor, MatrixIter,
0516         size_type, edge_descriptor >
0517         DirInEdgeIter;
0518 
0519     typedef detail::undir_adj_matrix_in_edge_iter< vertex_descriptor,
0520         MatrixIter, size_type, edge_descriptor >
0521         UnDirInEdgeIter;
0522 
0523     typedef typename mpl::if_< typename Directed::is_directed_t, DirInEdgeIter,
0524         UnDirInEdgeIter >::type unfiltered_in_edge_iter;
0525 
0526     typedef detail::adj_matrix_edge_iter< Directed, MatrixIter, size_type,
0527         edge_descriptor >
0528         unfiltered_edge_iter;
0529 
0530 public:
0531     // IncidenceGraph concept required types
0532     typedef filter_iterator< detail::does_edge_exist, unfiltered_out_edge_iter >
0533         out_edge_iterator;
0534 
0535     typedef size_type degree_size_type;
0536 
0537     // BidirectionalGraph required types
0538     typedef filter_iterator< detail::does_edge_exist, unfiltered_in_edge_iter >
0539         in_edge_iterator;
0540 
0541     // AdjacencyGraph required types
0542     typedef typename adjacency_iterator_generator< self, vertex_descriptor,
0543         out_edge_iterator >::type adjacency_iterator;
0544 
0545     // VertexListGraph required types
0546     typedef size_type vertices_size_type;
0547     typedef integer_range< vertex_descriptor > VertexList;
0548     typedef typename VertexList::iterator vertex_iterator;
0549 
0550     // EdgeListGraph required types
0551     typedef size_type edges_size_type;
0552     typedef filter_iterator< detail::does_edge_exist, unfiltered_edge_iter >
0553         edge_iterator;
0554 
0555     // PropertyGraph required types
0556     typedef adjacency_matrix_class_tag graph_tag;
0557 
0558     // Constructor required by MutableGraph
0559     adjacency_matrix(
0560         vertices_size_type n_vertices, const GraphProperty& p = GraphProperty())
0561     : m_matrix(Directed::is_directed ? (n_vertices * n_vertices)
0562                                      : (n_vertices * (n_vertices + 1) / 2))
0563     , m_vertex_set(0, n_vertices)
0564     , m_vertex_properties(n_vertices)
0565     , m_num_edges(0)
0566     , m_property(p)
0567     {
0568     }
0569 
0570     template < typename EdgeIterator >
0571     adjacency_matrix(EdgeIterator first, EdgeIterator last,
0572         vertices_size_type n_vertices, const GraphProperty& p = GraphProperty())
0573     : m_matrix(Directed::is_directed ? (n_vertices * n_vertices)
0574                                      : (n_vertices * (n_vertices + 1) / 2))
0575     , m_vertex_set(0, n_vertices)
0576     , m_vertex_properties(n_vertices)
0577     , m_num_edges(0)
0578     , m_property(p)
0579     {
0580         for (; first != last; ++first)
0581         {
0582             add_edge(first->first, first->second, *this);
0583         }
0584     }
0585 
0586     template < typename EdgeIterator, typename EdgePropertyIterator >
0587     adjacency_matrix(EdgeIterator first, EdgeIterator last,
0588         EdgePropertyIterator ep_iter, vertices_size_type n_vertices,
0589         const GraphProperty& p = GraphProperty())
0590     : m_matrix(Directed::is_directed ? (n_vertices * n_vertices)
0591                                      : (n_vertices * (n_vertices + 1) / 2))
0592     , m_vertex_set(0, n_vertices)
0593     , m_vertex_properties(n_vertices)
0594     , m_num_edges(0)
0595     , m_property(p)
0596     {
0597         for (; first != last; ++first, ++ep_iter)
0598         {
0599             add_edge(first->first, first->second, *ep_iter, *this);
0600         }
0601     }
0602 
0603 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
0604     // Directly access a vertex or edge bundle
0605     vertex_bundled& operator[](vertex_descriptor v)
0606     {
0607         return get(vertex_bundle, *this, v);
0608     }
0609 
0610     const vertex_bundled& operator[](vertex_descriptor v) const
0611     {
0612         return get(vertex_bundle, *this, v);
0613     }
0614 
0615     edge_bundled& operator[](edge_descriptor e)
0616     {
0617         return get(edge_bundle, *this, e);
0618     }
0619 
0620     const edge_bundled& operator[](edge_descriptor e) const
0621     {
0622         return get(edge_bundle, *this, e);
0623     }
0624 
0625     graph_bundled& operator[](graph_bundle_t) { return get_property(*this); }
0626 
0627     const graph_bundled& operator[](graph_bundle_t) const
0628     {
0629         return get_property(*this);
0630     }
0631 #endif
0632 
0633     // private: if friends worked, these would be private
0634 
0635     typename Matrix::const_reference get_edge(
0636         vertex_descriptor u, vertex_descriptor v) const
0637     {
0638         if (Directed::is_directed)
0639             return m_matrix[u * m_vertex_set.size() + v];
0640         else
0641         {
0642             if (v > u)
0643                 std::swap(u, v);
0644             return m_matrix[u * (u + 1) / 2 + v];
0645         }
0646     }
0647     typename Matrix::reference get_edge(
0648         vertex_descriptor u, vertex_descriptor v)
0649     {
0650         if (Directed::is_directed)
0651             return m_matrix[u * m_vertex_set.size() + v];
0652         else
0653         {
0654             if (v > u)
0655                 std::swap(u, v);
0656             return m_matrix[u * (u + 1) / 2 + v];
0657         }
0658     }
0659 
0660     Matrix m_matrix;
0661     VertexList m_vertex_set;
0662     std::vector< vertex_property_type > m_vertex_properties;
0663     size_type m_num_edges;
0664     graph_property_type m_property;
0665 };
0666 
0667 //=========================================================================
0668 // Functions required by the AdjacencyMatrix concept
0669 
0670 template < typename D, typename VP, typename EP, typename GP, typename A >
0671 std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor,
0672     bool >
0673 edge(typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
0674     typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v,
0675     const adjacency_matrix< D, VP, EP, GP, A >& g)
0676 {
0677     bool exists = detail::get_edge_exists(g.get_edge(u, v), 0);
0678     typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor e(
0679         exists, u, v, &detail::get_edge_property(g.get_edge(u, v)));
0680     return std::make_pair(e, exists);
0681 }
0682 
0683 //=========================================================================
0684 // Functions required by the IncidenceGraph concept
0685 
0686 // O(1)
0687 template < typename VP, typename EP, typename GP, typename A >
0688 std::pair<
0689     typename adjacency_matrix< directedS, VP, EP, GP, A >::out_edge_iterator,
0690     typename adjacency_matrix< directedS, VP, EP, GP, A >::out_edge_iterator >
0691 out_edges(
0692     typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_descriptor u,
0693     const adjacency_matrix< directedS, VP, EP, GP, A >& g_)
0694 {
0695     typedef adjacency_matrix< directedS, VP, EP, GP, A > Graph;
0696     Graph& g = const_cast< Graph& >(g_);
0697     typename Graph::vertices_size_type offset = u * g.m_vertex_set.size();
0698     typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
0699     typename Graph::MatrixIter l = f + g.m_vertex_set.size();
0700     typename Graph::unfiltered_out_edge_iter first(f, u, g.m_vertex_set.size()),
0701         last(l, u, g.m_vertex_set.size());
0702     detail::does_edge_exist pred;
0703     typedef typename Graph::out_edge_iterator out_edge_iterator;
0704     return std::make_pair(out_edge_iterator(pred, first, last),
0705         out_edge_iterator(pred, last, last));
0706 }
0707 
0708 // O(1)
0709 template < typename VP, typename EP, typename GP, typename A >
0710 std::pair<
0711     typename adjacency_matrix< undirectedS, VP, EP, GP, A >::out_edge_iterator,
0712     typename adjacency_matrix< undirectedS, VP, EP, GP, A >::out_edge_iterator >
0713 out_edges(
0714     typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_descriptor
0715         u,
0716     const adjacency_matrix< undirectedS, VP, EP, GP, A >& g_)
0717 {
0718     typedef adjacency_matrix< undirectedS, VP, EP, GP, A > Graph;
0719     Graph& g = const_cast< Graph& >(g_);
0720     typename Graph::vertices_size_type offset = u * (u + 1) / 2;
0721     typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
0722     typename Graph::MatrixIter l = g.m_matrix.end();
0723 
0724     typename Graph::unfiltered_out_edge_iter first(f, u, g.m_vertex_set.size()),
0725         last(l, u, g.m_vertex_set.size());
0726 
0727     detail::does_edge_exist pred;
0728     typedef typename Graph::out_edge_iterator out_edge_iterator;
0729     return std::make_pair(out_edge_iterator(pred, first, last),
0730         out_edge_iterator(pred, last, last));
0731 }
0732 
0733 // O(N)
0734 template < typename D, typename VP, typename EP, typename GP, typename A >
0735 typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type out_degree(
0736     typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
0737     const adjacency_matrix< D, VP, EP, GP, A >& g)
0738 {
0739     typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type n = 0;
0740     typename adjacency_matrix< D, VP, EP, GP, A >::out_edge_iterator f, l;
0741     for (boost::tie(f, l) = out_edges(u, g); f != l; ++f)
0742         ++n;
0743     return n;
0744 }
0745 
0746 // O(1)
0747 template < typename D, typename VP, typename EP, typename GP, typename A,
0748     typename Dir, typename Vertex >
0749 typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor source(
0750     const detail::matrix_edge_desc_impl< Dir, Vertex >& e,
0751     const adjacency_matrix< D, VP, EP, GP, A >&)
0752 {
0753     return e.m_source;
0754 }
0755 
0756 // O(1)
0757 template < typename D, typename VP, typename EP, typename GP, typename A,
0758     typename Dir, typename Vertex >
0759 typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor target(
0760     const detail::matrix_edge_desc_impl< Dir, Vertex >& e,
0761     const adjacency_matrix< D, VP, EP, GP, A >&)
0762 {
0763     return e.m_target;
0764 }
0765 
0766 //=========================================================================
0767 // Functions required by the BidirectionalGraph concept
0768 
0769 // O(1)
0770 template < typename VP, typename EP, typename GP, typename A >
0771 std::pair<
0772     typename adjacency_matrix< directedS, VP, EP, GP, A >::in_edge_iterator,
0773     typename adjacency_matrix< directedS, VP, EP, GP, A >::in_edge_iterator >
0774 in_edges(
0775     typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_descriptor u,
0776     const adjacency_matrix< directedS, VP, EP, GP, A >& g_)
0777 {
0778     typedef adjacency_matrix< directedS, VP, EP, GP, A > Graph;
0779     Graph& g = const_cast< Graph& >(g_);
0780     typename Graph::MatrixIter f = g.m_matrix.begin() + u;
0781     typename Graph::MatrixIter l = g.m_matrix.end();
0782     typename Graph::unfiltered_in_edge_iter first(
0783         f, l, u, g.m_vertex_set.size()),
0784         last(l, l, u, g.m_vertex_set.size());
0785     detail::does_edge_exist pred;
0786     typedef typename Graph::in_edge_iterator in_edge_iterator;
0787     return std::make_pair(in_edge_iterator(pred, first, last),
0788         in_edge_iterator(pred, last, last));
0789 }
0790 
0791 // O(1)
0792 template < typename VP, typename EP, typename GP, typename A >
0793 std::pair<
0794     typename adjacency_matrix< undirectedS, VP, EP, GP, A >::in_edge_iterator,
0795     typename adjacency_matrix< undirectedS, VP, EP, GP, A >::in_edge_iterator >
0796 in_edges(
0797     typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_descriptor
0798         u,
0799     const adjacency_matrix< undirectedS, VP, EP, GP, A >& g_)
0800 {
0801     typedef adjacency_matrix< undirectedS, VP, EP, GP, A > Graph;
0802     Graph& g = const_cast< Graph& >(g_);
0803     typename Graph::vertices_size_type offset = u * (u + 1) / 2;
0804     typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
0805     typename Graph::MatrixIter l = g.m_matrix.end();
0806 
0807     typename Graph::unfiltered_in_edge_iter first(f, u, g.m_vertex_set.size()),
0808         last(l, u, g.m_vertex_set.size());
0809 
0810     detail::does_edge_exist pred;
0811     typedef typename Graph::in_edge_iterator in_edge_iterator;
0812     return std::make_pair(in_edge_iterator(pred, first, last),
0813         in_edge_iterator(pred, last, last));
0814 }
0815 
0816 // O(N)
0817 template < typename D, typename VP, typename EP, typename GP, typename A >
0818 typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type in_degree(
0819     typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
0820     const adjacency_matrix< D, VP, EP, GP, A >& g)
0821 {
0822     typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type n = 0;
0823     typename adjacency_matrix< D, VP, EP, GP, A >::in_edge_iterator f, l;
0824     for (boost::tie(f, l) = in_edges(u, g); f != l; ++f)
0825         ++n;
0826     return n;
0827 }
0828 
0829 //=========================================================================
0830 // Functions required by the AdjacencyGraph concept
0831 
0832 template < typename D, typename VP, typename EP, typename GP, typename A >
0833 std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::adjacency_iterator,
0834     typename adjacency_matrix< D, VP, EP, GP, A >::adjacency_iterator >
0835 adjacent_vertices(
0836     typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
0837     const adjacency_matrix< D, VP, EP, GP, A >& g_)
0838 {
0839     typedef adjacency_matrix< D, VP, EP, GP, A > Graph;
0840     const Graph& cg = static_cast< const Graph& >(g_);
0841     Graph& g = const_cast< Graph& >(cg);
0842     typedef typename Graph::adjacency_iterator adjacency_iterator;
0843     typename Graph::out_edge_iterator first, last;
0844     boost::tie(first, last) = out_edges(u, g);
0845     return std::make_pair(
0846         adjacency_iterator(first, &g), adjacency_iterator(last, &g));
0847 }
0848 
0849 //=========================================================================
0850 // Functions required by the VertexListGraph concept
0851 
0852 template < typename D, typename VP, typename EP, typename GP, typename A >
0853 std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::vertex_iterator,
0854     typename adjacency_matrix< D, VP, EP, GP, A >::vertex_iterator >
0855 vertices(const adjacency_matrix< D, VP, EP, GP, A >& g_)
0856 {
0857     typedef adjacency_matrix< D, VP, EP, GP, A > Graph;
0858     Graph& g = const_cast< Graph& >(g_);
0859     return std::make_pair(g.m_vertex_set.begin(), g.m_vertex_set.end());
0860 }
0861 
0862 template < typename D, typename VP, typename EP, typename GP, typename A >
0863 typename adjacency_matrix< D, VP, EP, GP, A >::vertices_size_type num_vertices(
0864     const adjacency_matrix< D, VP, EP, GP, A >& g)
0865 {
0866     return g.m_vertex_set.size();
0867 }
0868 
0869 //=========================================================================
0870 // Functions required by the EdgeListGraph concept
0871 
0872 template < typename D, typename VP, typename EP, typename GP, typename A >
0873 std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_iterator,
0874     typename adjacency_matrix< D, VP, EP, GP, A >::edge_iterator >
0875 edges(const adjacency_matrix< D, VP, EP, GP, A >& g_)
0876 {
0877     typedef adjacency_matrix< D, VP, EP, GP, A > Graph;
0878     Graph& g = const_cast< Graph& >(g_);
0879 
0880     typename Graph::unfiltered_edge_iter first(
0881         g.m_matrix.begin(), g.m_matrix.begin(), g.m_vertex_set.size()),
0882         last(g.m_matrix.end(), g.m_matrix.begin(), g.m_vertex_set.size());
0883     detail::does_edge_exist pred;
0884     typedef typename Graph::edge_iterator edge_iterator;
0885     return std::make_pair(
0886         edge_iterator(pred, first, last), edge_iterator(pred, last, last));
0887 }
0888 
0889 // O(1)
0890 template < typename D, typename VP, typename EP, typename GP, typename A >
0891 typename adjacency_matrix< D, VP, EP, GP, A >::edges_size_type num_edges(
0892     const adjacency_matrix< D, VP, EP, GP, A >& g)
0893 {
0894     return g.m_num_edges;
0895 }
0896 
0897 //=========================================================================
0898 // Functions required by the MutableGraph concept
0899 
0900 // O(1)
0901 template < typename D, typename VP, typename EP, typename GP, typename A,
0902     typename EP2 >
0903 std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor,
0904     bool >
0905 add_edge(typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
0906     typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v,
0907     const EP2& ep, adjacency_matrix< D, VP, EP, GP, A >& g)
0908 {
0909     typedef typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor
0910         edge_descriptor;
0911     if (detail::get_edge_exists(g.get_edge(u, v), 0) == false)
0912     {
0913         ++(g.m_num_edges);
0914         detail::set_edge_property(g.get_edge(u, v), EP(ep), 0);
0915         detail::set_edge_exists(g.get_edge(u, v), true, 0);
0916         return std::make_pair(edge_descriptor(true, u, v,
0917                                   &detail::get_edge_property(g.get_edge(u, v))),
0918             true);
0919     }
0920     else
0921         return std::make_pair(edge_descriptor(true, u, v,
0922                                   &detail::get_edge_property(g.get_edge(u, v))),
0923             false);
0924 }
0925 // O(1)
0926 template < typename D, typename VP, typename EP, typename GP, typename A >
0927 std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor,
0928     bool >
0929 add_edge(typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
0930     typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v,
0931     adjacency_matrix< D, VP, EP, GP, A >& g)
0932 {
0933     EP ep;
0934     return add_edge(u, v, ep, g);
0935 }
0936 
0937 // O(1)
0938 template < typename D, typename VP, typename EP, typename GP, typename A >
0939 void remove_edge(
0940     typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
0941     typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v,
0942     adjacency_matrix< D, VP, EP, GP, A >& g)
0943 {
0944     // Don'remove the edge unless it already exists.
0945     if (detail::get_edge_exists(g.get_edge(u, v), 0))
0946     {
0947         --(g.m_num_edges);
0948         detail::set_edge_exists(g.get_edge(u, v), false, 0);
0949     }
0950 }
0951 
0952 // O(1)
0953 template < typename D, typename VP, typename EP, typename GP, typename A >
0954 void remove_edge(
0955     typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor e,
0956     adjacency_matrix< D, VP, EP, GP, A >& g)
0957 {
0958     remove_edge(source(e, g), target(e, g), g);
0959 }
0960 
0961 template < typename D, typename VP, typename EP, typename GP, typename A >
0962 inline typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor
0963 add_vertex(adjacency_matrix< D, VP, EP, GP, A >& g)
0964 {
0965     // UNDER CONSTRUCTION
0966     BOOST_ASSERT(false);
0967     return *vertices(g).first;
0968 }
0969 
0970 template < typename D, typename VP, typename EP, typename GP, typename A,
0971     typename VP2 >
0972 inline typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor
0973 add_vertex(const VP2& /*vp*/, adjacency_matrix< D, VP, EP, GP, A >& g)
0974 {
0975     // UNDER CONSTRUCTION
0976     BOOST_ASSERT(false);
0977     return *vertices(g).first;
0978 }
0979 
0980 template < typename D, typename VP, typename EP, typename GP, typename A >
0981 inline void remove_vertex(
0982     typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor /*u*/,
0983     adjacency_matrix< D, VP, EP, GP, A >& /*g*/)
0984 {
0985     // UNDER CONSTRUCTION
0986     BOOST_ASSERT(false);
0987 }
0988 
0989 // O(V)
0990 template < typename VP, typename EP, typename GP, typename A >
0991 void clear_vertex(
0992     typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_descriptor u,
0993     adjacency_matrix< directedS, VP, EP, GP, A >& g)
0994 {
0995     typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_iterator vi,
0996         vi_end;
0997     for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
0998         remove_edge(u, *vi, g);
0999     for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
1000         remove_edge(*vi, u, g);
1001 }
1002 
1003 // O(V)
1004 template < typename VP, typename EP, typename GP, typename A >
1005 void clear_vertex(
1006     typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_descriptor
1007         u,
1008     adjacency_matrix< undirectedS, VP, EP, GP, A >& g)
1009 {
1010     typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_iterator vi,
1011         vi_end;
1012     for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
1013         remove_edge(u, *vi, g);
1014 }
1015 
1016 //=========================================================================
1017 // Functions required by the PropertyGraph concept
1018 
1019 template < typename D, typename VP, typename EP, typename GP, typename A,
1020     typename Prop, typename Kind >
1021 struct adj_mat_pm_helper;
1022 
1023 template < typename D, typename VP, typename EP, typename GP, typename A,
1024     typename Prop >
1025 struct adj_mat_pm_helper< D, VP, EP, GP, A, Prop, vertex_property_tag >
1026 {
1027     typedef typename graph_traits<
1028         adjacency_matrix< D, VP, EP, GP, A > >::vertex_descriptor arg_type;
1029     typedef typed_identity_property_map< arg_type > vi_map_type;
1030     typedef iterator_property_map< typename std::vector< VP >::iterator,
1031         vi_map_type >
1032         all_map_type;
1033     typedef iterator_property_map< typename std::vector< VP >::const_iterator,
1034         vi_map_type >
1035         all_map_const_type;
1036     typedef transform_value_property_map<
1037         detail::lookup_one_property_f< VP, Prop >, all_map_type >
1038         type;
1039     typedef transform_value_property_map<
1040         detail::lookup_one_property_f< const VP, Prop >, all_map_const_type >
1041         const_type;
1042     typedef typename property_traits< type >::reference single_nonconst_type;
1043     typedef typename property_traits< const_type >::reference single_const_type;
1044 
1045     static type get_nonconst(adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop)
1046     {
1047         return type(
1048             prop, all_map_type(g.m_vertex_properties.begin(), vi_map_type()));
1049     }
1050 
1051     static const_type get_const(
1052         const adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop)
1053     {
1054         return const_type(prop,
1055             all_map_const_type(g.m_vertex_properties.begin(), vi_map_type()));
1056     }
1057 
1058     static single_nonconst_type get_nonconst_one(
1059         adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop, arg_type v)
1060     {
1061         return lookup_one_property< VP, Prop >::lookup(
1062             g.m_vertex_properties[v], prop);
1063     }
1064 
1065     static single_const_type get_const_one(
1066         const adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop, arg_type v)
1067     {
1068         return lookup_one_property< const VP, Prop >::lookup(
1069             g.m_vertex_properties[v], prop);
1070     }
1071 };
1072 
1073 template < typename D, typename VP, typename EP, typename GP, typename A,
1074     typename Tag >
1075 struct adj_mat_pm_helper< D, VP, EP, GP, A, Tag, edge_property_tag >
1076 {
1077     typedef typename graph_traits<
1078         adjacency_matrix< D, VP, EP, GP, A > >::edge_descriptor edge_descriptor;
1079 
1080     template < typename IsConst > struct lookup_property_from_edge
1081     {
1082         Tag tag;
1083         lookup_property_from_edge(Tag tag) : tag(tag) {}
1084         typedef typename boost::mpl::if_< IsConst, const EP, EP >::type
1085             ep_type_nonref;
1086         typedef ep_type_nonref& ep_type;
1087         typedef typename lookup_one_property< ep_type_nonref, Tag >::type&
1088             result_type;
1089         result_type operator()(edge_descriptor e) const
1090         {
1091             return lookup_one_property< ep_type_nonref, Tag >::lookup(
1092                 *static_cast< ep_type_nonref* >(e.get_property()), tag);
1093         }
1094     };
1095 
1096     typedef function_property_map<
1097         lookup_property_from_edge< boost::mpl::false_ >,
1098         typename graph_traits<
1099             adjacency_matrix< D, VP, EP, GP, A > >::edge_descriptor >
1100         type;
1101     typedef function_property_map<
1102         lookup_property_from_edge< boost::mpl::true_ >,
1103         typename graph_traits<
1104             adjacency_matrix< D, VP, EP, GP, A > >::edge_descriptor >
1105         const_type;
1106     typedef edge_descriptor arg_type;
1107     typedef
1108         typename lookup_property_from_edge< boost::mpl::false_ >::result_type
1109             single_nonconst_type;
1110     typedef typename lookup_property_from_edge< boost::mpl::true_ >::result_type
1111         single_const_type;
1112 
1113     static type get_nonconst(adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag)
1114     {
1115         return type(tag);
1116     }
1117 
1118     static const_type get_const(
1119         const adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag)
1120     {
1121         return const_type(tag);
1122     }
1123 
1124     static single_nonconst_type get_nonconst_one(
1125         adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag, edge_descriptor e)
1126     {
1127         return lookup_one_property< EP, Tag >::lookup(
1128             *static_cast< EP* >(e.get_property()), tag);
1129     }
1130 
1131     static single_const_type get_const_one(
1132         const adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag,
1133         edge_descriptor e)
1134     {
1135         return lookup_one_property< const EP, Tag >::lookup(
1136             *static_cast< const EP* >(e.get_property()), tag);
1137     }
1138 };
1139 
1140 template < typename D, typename VP, typename EP, typename GP, typename A,
1141     typename Tag >
1142 struct property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >
1143 : adj_mat_pm_helper< D, VP, EP, GP, A, Tag,
1144       typename detail::property_kind_from_graph<
1145           adjacency_matrix< D, VP, EP, GP, A >, Tag >::type >
1146 {
1147 };
1148 
1149 template < typename D, typename VP, typename EP, typename GP, typename A,
1150     typename Tag >
1151 typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::type get(
1152     Tag tag, adjacency_matrix< D, VP, EP, GP, A >& g)
1153 {
1154     return property_map< adjacency_matrix< D, VP, EP, GP, A >,
1155         Tag >::get_nonconst(g, tag);
1156 }
1157 
1158 template < typename D, typename VP, typename EP, typename GP, typename A,
1159     typename Tag >
1160 typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::const_type
1161 get(Tag tag, const adjacency_matrix< D, VP, EP, GP, A >& g)
1162 {
1163     return property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::get_const(
1164         g, tag);
1165 }
1166 
1167 template < typename D, typename VP, typename EP, typename GP, typename A,
1168     typename Tag >
1169 typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
1170     Tag >::single_nonconst_type
1171 get(Tag tag, adjacency_matrix< D, VP, EP, GP, A >& g,
1172     typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::arg_type
1173         a)
1174 {
1175     return property_map< adjacency_matrix< D, VP, EP, GP, A >,
1176         Tag >::get_nonconst_one(g, tag, a);
1177 }
1178 
1179 template < typename D, typename VP, typename EP, typename GP, typename A,
1180     typename Tag >
1181 typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
1182     Tag >::single_const_type
1183 get(Tag tag, const adjacency_matrix< D, VP, EP, GP, A >& g,
1184     typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::arg_type
1185         a)
1186 {
1187     return property_map< adjacency_matrix< D, VP, EP, GP, A >,
1188         Tag >::get_const_one(g, tag, a);
1189 }
1190 
1191 template < typename D, typename VP, typename EP, typename GP, typename A,
1192     typename Tag >
1193 void put(Tag tag, adjacency_matrix< D, VP, EP, GP, A >& g,
1194     typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::arg_type
1195         a,
1196     typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
1197         Tag >::single_const_type val)
1198 {
1199     property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::get_nonconst_one(
1200         g, tag, a)
1201         = val;
1202 }
1203 
1204 // O(1)
1205 template < typename D, typename VP, typename EP, typename GP, typename A,
1206     typename Tag, typename Value >
1207 inline void set_property(
1208     adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag, const Value& value)
1209 {
1210     get_property_value(g.m_property, tag) = value;
1211 }
1212 
1213 template < typename D, typename VP, typename EP, typename GP, typename A,
1214     typename Tag >
1215 inline
1216     typename graph_property< adjacency_matrix< D, VP, EP, GP, A >, Tag >::type&
1217     get_property(adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag)
1218 {
1219     return get_property_value(g.m_property, tag);
1220 }
1221 
1222 template < typename D, typename VP, typename EP, typename GP, typename A,
1223     typename Tag >
1224 inline const typename graph_property< adjacency_matrix< D, VP, EP, GP, A >,
1225     Tag >::type&
1226 get_property(const adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag)
1227 {
1228     return get_property_value(g.m_property, tag);
1229 }
1230 
1231 //=========================================================================
1232 // Vertex Property Map
1233 
1234 template < typename D, typename VP, typename EP, typename GP, typename A >
1235 struct property_map< adjacency_matrix< D, VP, EP, GP, A >, vertex_index_t >
1236 {
1237     typedef
1238         typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor Vertex;
1239     typedef typed_identity_property_map< Vertex > type;
1240     typedef type const_type;
1241 };
1242 
1243 template < typename D, typename VP, typename EP, typename GP, typename A >
1244 typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
1245     vertex_index_t >::const_type
1246 get(vertex_index_t, adjacency_matrix< D, VP, EP, GP, A >&)
1247 {
1248     return typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
1249         vertex_index_t >::const_type();
1250 }
1251 
1252 template < typename D, typename VP, typename EP, typename GP, typename A >
1253 typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor get(
1254     vertex_index_t, adjacency_matrix< D, VP, EP, GP, A >&,
1255     typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v)
1256 {
1257     return v;
1258 }
1259 
1260 template < typename D, typename VP, typename EP, typename GP, typename A >
1261 typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
1262     vertex_index_t >::const_type
1263 get(vertex_index_t, const adjacency_matrix< D, VP, EP, GP, A >&)
1264 {
1265     return typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
1266         vertex_index_t >::const_type();
1267 }
1268 
1269 template < typename D, typename VP, typename EP, typename GP, typename A >
1270 typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor get(
1271     vertex_index_t, const adjacency_matrix< D, VP, EP, GP, A >&,
1272     typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v)
1273 {
1274     return v;
1275 }
1276 
1277 //=========================================================================
1278 // Other Functions
1279 
1280 template < typename D, typename VP, typename EP, typename GP, typename A >
1281 typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor vertex(
1282     typename adjacency_matrix< D, VP, EP, GP, A >::vertices_size_type n,
1283     const adjacency_matrix< D, VP, EP, GP, A >&)
1284 {
1285     return n;
1286 }
1287 
1288 template < typename D, typename VP, typename EP, typename GP, typename A >
1289 struct graph_mutability_traits< adjacency_matrix< D, VP, EP, GP, A > >
1290 {
1291     typedef mutable_edge_property_graph_tag category;
1292 };
1293 
1294 } // namespace boost
1295 
1296 #endif // BOOST_ADJACENCY_MATRIX_HPP