ossrv_pub/boost_apis/boost/graph/adjacency_matrix.hpp
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ossrv_pub/boost_apis/boost/graph/adjacency_matrix.hpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,1278 @@
+//=======================================================================
+// Copyright 2001 University of Notre Dame.
+// Copyright 2006 Trustees of Indiana University
+// Authors: Jeremy G. Siek and Douglas Gregor <dgregor@cs.indiana.edu>
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_ADJACENCY_MATRIX_HPP
+#define BOOST_ADJACENCY_MATRIX_HPP
+
+#include <boost/config.hpp>
+#include <vector>
+#include <memory>
+#include <cassert>
+#include <boost/limits.hpp>
+#include <boost/iterator.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_selectors.hpp>
+#include <boost/pending/ct_if.hpp>
+#include <boost/graph/adjacency_iterator.hpp>
+#include <boost/graph/detail/edge.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/filter_iterator.hpp>
+#include <boost/pending/integer_range.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/ice.hpp>
+
+namespace boost {
+  
+  namespace detail {
+
+    template <class Directed, class Vertex>
+    class matrix_edge_desc_impl : public edge_desc_impl<Directed,Vertex>
+    {
+      typedef edge_desc_impl<Directed,Vertex> Base;
+    public:
+      matrix_edge_desc_impl() { }
+      matrix_edge_desc_impl(bool exists, Vertex s, Vertex d, 
+                            const void* ep = 0)
+        : Base(s, d, ep), m_exists(exists) { }
+      bool exists() const { return m_exists; }
+    private:
+      bool m_exists;
+    };
+
+    struct does_edge_exist {
+      template <class Edge>
+      bool operator()(const Edge& e) const { return e.exists(); }
+    };
+
+    template <typename EdgeProperty>
+    bool get_edge_exists(const std::pair<bool, EdgeProperty>& stored_edge, int) {
+      return stored_edge.first;
+    }
+    template <typename EdgeProperty>
+    void set_edge_exists(
+        std::pair<bool, EdgeProperty>& stored_edge, 
+        bool flag,
+        int
+        ) {
+      stored_edge.first = flag;
+    }
+
+    template <typename EdgeProxy>
+    bool get_edge_exists(const EdgeProxy& edge_proxy, ...) {
+      return edge_proxy;
+    }
+    template <typename EdgeProxy>
+    EdgeProxy& set_edge_exists(EdgeProxy& edge_proxy, bool flag, ...) {
+      edge_proxy = flag;
+      return edge_proxy; // just to avoid never used warning
+    }
+
+
+
+    template <typename EdgeProperty>
+    const EdgeProperty&
+    get_property(const std::pair<bool, EdgeProperty>& stored_edge) {
+      return stored_edge.second;
+    }
+    template <typename EdgeProperty>
+    EdgeProperty&
+    get_property(std::pair<bool, EdgeProperty>& stored_edge) {
+      return stored_edge.second;
+    }
+
+    template <typename StoredEdgeProperty, typename EdgeProperty>
+    inline void
+    set_property(std::pair<bool, StoredEdgeProperty>& stored_edge, 
+                 const EdgeProperty& ep, int) {
+      stored_edge.second = ep;
+    }
+
+    inline const no_property& get_property(const char&) {
+      static no_property s_prop;
+      return s_prop;
+    }
+    inline no_property& get_property(char&) {
+      static no_property s_prop;
+      return s_prop;
+    }
+    template <typename EdgeProxy, typename EdgeProperty>
+    inline void
+    set_property(EdgeProxy, const EdgeProperty&, ...) {}
+    
+    //=======================================================================
+    // Directed Out Edge Iterator
+
+    template <
+        typename VertexDescriptor, typename MatrixIter
+      , typename VerticesSizeType, typename EdgeDescriptor
+    >
+    struct dir_adj_matrix_out_edge_iter
+      : iterator_adaptor<
+            dir_adj_matrix_out_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
+          , MatrixIter
+          , EdgeDescriptor
+          , use_default
+          , EdgeDescriptor
+          , std::ptrdiff_t
+        >
+    {
+        typedef iterator_adaptor<
+            dir_adj_matrix_out_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
+          , MatrixIter
+          , EdgeDescriptor
+          , use_default
+          , EdgeDescriptor
+          , std::ptrdiff_t
+        > super_t;
+        
+        dir_adj_matrix_out_edge_iter() { }
+        
+        dir_adj_matrix_out_edge_iter(
+            const MatrixIter& i
+          , const VertexDescriptor& src
+          , const VerticesSizeType& n
+           )
+            : super_t(i), m_src(src), m_targ(0), m_n(n)
+        { }
+
+        void increment() {
+            ++this->base_reference();
+            ++m_targ;
+        }
+        
+        inline EdgeDescriptor
+        dereference() const 
+        {
+            return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, m_targ, 
+                                  &get_property(*this->base()));
+        }
+        VertexDescriptor m_src, m_targ;
+        VerticesSizeType m_n;
+    };
+
+    //=======================================================================
+    // Directed In Edge Iterator
+
+    template <
+        typename VertexDescriptor, typename MatrixIter
+      , typename VerticesSizeType, typename EdgeDescriptor
+    >
+    struct dir_adj_matrix_in_edge_iter
+      : iterator_adaptor<
+            dir_adj_matrix_in_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
+          , MatrixIter
+          , EdgeDescriptor
+          , use_default
+          , EdgeDescriptor
+          , std::ptrdiff_t
+        >
+    {
+        typedef iterator_adaptor<
+            dir_adj_matrix_in_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
+          , MatrixIter
+          , EdgeDescriptor
+          , use_default
+          , EdgeDescriptor
+          , std::ptrdiff_t
+        > super_t;
+        
+        dir_adj_matrix_in_edge_iter() { }
+        
+        dir_adj_matrix_in_edge_iter(
+            const MatrixIter& i
+          , const MatrixIter& last
+          , const VertexDescriptor& tgt
+          , const VerticesSizeType& n
+           )
+          : super_t(i), m_last(last), m_src(0), m_targ(tgt), m_n(n)
+        { }
+
+        void increment() {
+          if (VerticesSizeType(m_last - this->base_reference()) >= m_n) {
+            this->base_reference() += m_n;
+            ++m_src;
+          } else {
+            this->base_reference() = m_last;
+          }
+        }
+        
+        inline EdgeDescriptor
+        dereference() const 
+        {
+            return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, m_targ, 
+                                  &get_property(*this->base()));
+        }
+        MatrixIter m_last;
+        VertexDescriptor m_src, m_targ;
+        VerticesSizeType m_n;
+    };
+
+    //=======================================================================
+    // Undirected Out Edge Iterator
+
+    template <
+        typename VertexDescriptor, typename MatrixIter
+      , typename VerticesSizeType, typename EdgeDescriptor
+    >
+    struct undir_adj_matrix_out_edge_iter 
+      : iterator_adaptor<
+            undir_adj_matrix_out_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
+          , MatrixIter
+          , EdgeDescriptor
+          , use_default
+          , EdgeDescriptor
+          , std::ptrdiff_t
+        >
+    {
+        typedef iterator_adaptor<
+            undir_adj_matrix_out_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
+          , MatrixIter
+          , EdgeDescriptor
+          , use_default
+          , EdgeDescriptor
+          , std::ptrdiff_t
+        > super_t;
+        
+        undir_adj_matrix_out_edge_iter() { }
+        
+        undir_adj_matrix_out_edge_iter(
+            const MatrixIter& i
+          , const VertexDescriptor& src
+          , const VerticesSizeType& n
+        )
+          : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n)
+        {}
+
+        void increment()
+        {
+            if (m_targ < m_src)     // first half
+            {
+                ++this->base_reference();
+            }
+            else if (m_targ < m_n - 1)
+            {                  // second half
+                ++m_inc;
+                this->base_reference() += m_inc;
+            }
+            else
+            {                  // past-the-end
+                this->base_reference() += m_n - m_src;
+            }
+            ++m_targ;
+        }
+        
+        inline EdgeDescriptor
+        dereference() const 
+        {
+            return EdgeDescriptor(
+                get_edge_exists(*this->base(), 0), m_src, m_targ
+              , &get_property(*this->base())
+            );
+        }
+        
+        VertexDescriptor m_src, m_inc, m_targ;
+        VerticesSizeType m_n;
+    };
+
+    //=======================================================================
+    // Undirected In Edge Iterator
+
+    template <
+        typename VertexDescriptor, typename MatrixIter
+      , typename VerticesSizeType, typename EdgeDescriptor
+    >
+    struct undir_adj_matrix_in_edge_iter 
+      : iterator_adaptor<
+            undir_adj_matrix_in_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
+          , MatrixIter
+          , EdgeDescriptor
+          , use_default
+          , EdgeDescriptor
+          , std::ptrdiff_t
+        >
+    {
+        typedef iterator_adaptor<
+            undir_adj_matrix_in_edge_iter<VertexDescriptor, MatrixIter,  VerticesSizeType, EdgeDescriptor>
+          , MatrixIter
+          , EdgeDescriptor
+          , use_default
+          , EdgeDescriptor
+          , std::ptrdiff_t
+        > super_t;
+        
+        undir_adj_matrix_in_edge_iter() { }
+        
+        undir_adj_matrix_in_edge_iter(
+            const MatrixIter& i
+          , const VertexDescriptor& src
+          , const VerticesSizeType& n
+        )
+          : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n)
+        {}
+
+        void increment()
+        {
+            if (m_targ < m_src)     // first half
+            {
+                ++this->base_reference();
+            }
+            else if (m_targ < m_n - 1)
+            {                  // second half
+                ++m_inc;
+                this->base_reference() += m_inc;
+            }
+            else
+            {                  // past-the-end
+                this->base_reference() += m_n - m_src;
+            }
+            ++m_targ;
+        }
+        
+        inline EdgeDescriptor
+        dereference() const 
+        {
+            return EdgeDescriptor(
+                     get_edge_exists(*this->base(), 0), m_targ, m_src
+              , &get_property(*this->base())
+            );
+        }
+        
+        VertexDescriptor m_src, m_inc, m_targ;
+        VerticesSizeType m_n;
+    };
+
+    //=======================================================================
+    // Edge Iterator
+
+    template <typename Directed, typename MatrixIter, 
+              typename VerticesSizeType, typename EdgeDescriptor>
+    struct adj_matrix_edge_iter
+      : iterator_adaptor<
+            adj_matrix_edge_iter<Directed, MatrixIter,  VerticesSizeType, EdgeDescriptor>
+          , MatrixIter
+          , EdgeDescriptor
+          , use_default
+          , EdgeDescriptor
+          , std::ptrdiff_t
+        >
+    {
+        typedef iterator_adaptor<
+            adj_matrix_edge_iter<Directed, MatrixIter,  VerticesSizeType, EdgeDescriptor>
+          , MatrixIter
+          , EdgeDescriptor
+          , use_default
+          , EdgeDescriptor
+          , std::ptrdiff_t
+        > super_t;
+        
+        adj_matrix_edge_iter() { }
+        
+        adj_matrix_edge_iter(const MatrixIter& i, const MatrixIter& start, const VerticesSizeType& n) 
+            : super_t(i), m_start(start), m_src(0), m_targ(0), m_n(n) { }
+
+        void increment()
+        {
+            increment_dispatch(this->base_reference(), Directed());
+        }
+        
+        void increment_dispatch(MatrixIter& i, directedS)
+        {
+            ++i;
+            if (m_targ == m_n - 1)
+            {
+                m_targ = 0;
+                ++m_src;
+            }
+            else
+            {
+                ++m_targ;
+            }
+        }
+        
+        void increment_dispatch(MatrixIter& i, undirectedS)
+        {
+            ++i;
+            if (m_targ == m_src)
+            {
+                m_targ = 0;
+                ++m_src;
+            }
+            else
+            {
+                ++m_targ;
+            }
+        }
+
+        inline EdgeDescriptor
+        dereference() const 
+        {
+            return EdgeDescriptor(
+                get_edge_exists(
+                    *this->base(), 0), m_src, m_targ, &get_property(*this->base())
+            );
+        }
+      
+        MatrixIter m_start;
+        VerticesSizeType m_src, m_targ, m_n;
+    };
+
+  } // namespace detail
+
+  //=========================================================================
+  // Adjacency Matrix Traits
+  template <typename Directed = directedS>
+  class adjacency_matrix_traits {
+    typedef typename Directed::is_directed_t is_directed;
+  public:
+    // The bidirectionalS tag is not allowed with the adjacency_matrix
+    // graph type. Instead, use directedS, which also provides the
+    // functionality required for a Bidirectional Graph (in_edges,
+    // in_degree, etc.).
+#if !defined(_MSC_VER) || _MSC_VER > 1300
+    BOOST_STATIC_ASSERT(type_traits::ice_not<(is_same<Directed, bidirectionalS>::value)>::value);
+#endif
+
+    typedef typename boost::ct_if_t<is_directed,
+                                    bidirectional_tag, undirected_tag>::type
+      directed_category;
+    
+    typedef disallow_parallel_edge_tag edge_parallel_category;
+    
+    typedef std::size_t vertex_descriptor;
+
+    typedef detail::matrix_edge_desc_impl<directed_category,
+      vertex_descriptor> edge_descriptor;
+  };
+
+  struct adjacency_matrix_class_tag { };
+
+  struct adj_matrix_traversal_tag :
+    public virtual adjacency_matrix_tag,
+    public virtual vertex_list_graph_tag,
+    public virtual incidence_graph_tag,
+    public virtual adjacency_graph_tag,
+    public virtual edge_list_graph_tag { };
+  
+  //=========================================================================
+  // Adjacency Matrix Class
+  template <typename Directed = directedS,
+            typename VertexProperty = no_property,
+            typename EdgeProperty = no_property,
+            typename GraphProperty = no_property,
+            typename Allocator = std::allocator<bool> >
+  class adjacency_matrix {
+    typedef adjacency_matrix self;
+    typedef adjacency_matrix_traits<Directed> Traits;
+    
+  public:
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
+    // The bidirectionalS tag is not allowed with the adjacency_matrix
+    // graph type. Instead, use directedS, which also provides the
+    // functionality required for a Bidirectional Graph (in_edges,
+    // in_degree, etc.).
+    BOOST_STATIC_ASSERT(!(is_same<Directed, bidirectionalS>::value));
+#endif
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+    typedef typename detail::retag_property_list<vertex_bundle_t, VertexProperty>::type
+      vertex_property_type;
+    typedef typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::type
+      edge_property_type;
+      
+  private:
+    typedef typename detail::retag_property_list<vertex_bundle_t, VertexProperty>::retagged
+      maybe_vertex_bundled;
+
+    typedef typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::retagged
+      maybe_edge_bundled;
+    
+  public:
+    // The types that are actually bundled
+    typedef typename ct_if<(is_same<maybe_vertex_bundled, no_property>::value),
+                           no_vertex_bundle,
+                           maybe_vertex_bundled>::type vertex_bundled;
+    typedef typename ct_if<(is_same<maybe_edge_bundled, no_property>::value),
+                           no_edge_bundle,
+                           maybe_edge_bundled>::type edge_bundled;
+#else
+    typedef EdgeProperty     edge_property_type;
+    typedef VertexProperty   vertex_property_type;
+    typedef no_vertex_bundle vertex_bundled;
+    typedef no_edge_bundle   edge_bundled;
+#endif
+
+  public: // should be private
+    typedef typename ct_if_t<typename has_property<edge_property_type>::type,
+      std::pair<bool, edge_property_type>, char>::type StoredEdge;
+#if (defined(BOOST_MSVC) && BOOST_MSVC <= 1300) || defined(BOOST_NO_STD_ALLOCATOR)
+    typedef std::vector<StoredEdge> Matrix;
+#else
+    // This causes internal compiler error for MSVC
+    typedef typename Allocator::template rebind<StoredEdge>::other Alloc;
+    typedef std::vector<StoredEdge, Alloc> Matrix;
+#endif
+    typedef typename Matrix::iterator MatrixIter;
+    typedef typename Matrix::size_type size_type;
+  public:
+    // Graph concept required types
+    typedef typename Traits::vertex_descriptor vertex_descriptor;
+    typedef typename Traits::edge_descriptor edge_descriptor;
+    typedef typename Traits::directed_category directed_category;
+    typedef typename Traits::edge_parallel_category edge_parallel_category;
+    typedef adj_matrix_traversal_tag traversal_category;
+
+    static vertex_descriptor null_vertex()
+    {
+      return (std::numeric_limits<vertex_descriptor>::max)();
+    }
+      
+    //private: if friends worked, these would be private
+
+    typedef detail::dir_adj_matrix_out_edge_iter<
+        vertex_descriptor, MatrixIter, size_type, edge_descriptor
+    > DirOutEdgeIter;
+
+    typedef detail::undir_adj_matrix_out_edge_iter<
+        vertex_descriptor, MatrixIter, size_type, edge_descriptor
+    > UnDirOutEdgeIter;
+
+    typedef typename ct_if_t<
+        typename Directed::is_directed_t, DirOutEdgeIter, UnDirOutEdgeIter
+    >::type unfiltered_out_edge_iter;
+
+    typedef detail::dir_adj_matrix_in_edge_iter<
+        vertex_descriptor, MatrixIter, size_type, edge_descriptor
+    > DirInEdgeIter;
+
+    typedef detail::undir_adj_matrix_in_edge_iter<
+        vertex_descriptor, MatrixIter, size_type, edge_descriptor
+    > UnDirInEdgeIter;
+
+    typedef typename ct_if_t<
+        typename Directed::is_directed_t, DirInEdgeIter, UnDirInEdgeIter
+    >::type unfiltered_in_edge_iter;
+    
+    typedef detail::adj_matrix_edge_iter<
+        Directed, MatrixIter, size_type, edge_descriptor
+    > unfiltered_edge_iter;
+    
+  public:
+
+    // IncidenceGraph concept required types
+    typedef filter_iterator<detail::does_edge_exist, unfiltered_out_edge_iter>
+      out_edge_iterator;
+
+    typedef size_type degree_size_type;
+
+    // BidirectionalGraph required types
+    typedef filter_iterator<detail::does_edge_exist, unfiltered_in_edge_iter>
+      in_edge_iterator;
+
+    // AdjacencyGraph required types
+     typedef typename adjacency_iterator_generator<self,
+       vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
+
+    // VertexListGraph required types
+    typedef size_type vertices_size_type;
+    typedef integer_range<vertex_descriptor> VertexList;
+    typedef typename VertexList::iterator vertex_iterator;
+
+    // EdgeListGraph required types
+    typedef size_type edges_size_type;
+    typedef filter_iterator<
+        detail::does_edge_exist, unfiltered_edge_iter
+    > edge_iterator;
+
+    // PropertyGraph required types
+    typedef adjacency_matrix_class_tag graph_tag;
+
+    // Constructor required by MutableGraph
+    adjacency_matrix(vertices_size_type n_vertices) 
+      : m_matrix(Directed::is_directed ? 
+                 (n_vertices * n_vertices)
+                 : (n_vertices * (n_vertices + 1) / 2)),
+      m_vertex_set(0, n_vertices),
+      m_vertex_properties(n_vertices),
+      m_num_edges(0) { }
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+    // Directly access a vertex or edge bundle
+    vertex_bundled& operator[](vertex_descriptor v)
+    { return get(vertex_bundle, *this)[v]; }
+
+    const vertex_bundled& operator[](vertex_descriptor v) const
+    { return get(vertex_bundle, *this)[v]; }
+
+    edge_bundled& operator[](edge_descriptor e)
+    { return get(edge_bundle, *this)[e]; }
+
+    const edge_bundled& operator[](edge_descriptor e) const
+    { return get(edge_bundle, *this)[e]; }
+#endif
+    
+    //private: if friends worked, these would be private
+
+    typename Matrix::const_reference
+    get_edge(vertex_descriptor u, vertex_descriptor v) const {
+      if (Directed::is_directed)
+        return m_matrix[u * m_vertex_set.size() + v];
+      else {
+        if (v > u)
+          std::swap(u, v);
+        return m_matrix[u * (u + 1)/2 + v];
+      }
+    }
+    typename Matrix::reference
+    get_edge(vertex_descriptor u, vertex_descriptor v) {
+      if (Directed::is_directed)
+        return m_matrix[u * m_vertex_set.size() + v];
+      else {
+        if (v > u)
+          std::swap(u, v);
+        return m_matrix[u * (u + 1)/2 + v];
+      }
+    }
+
+    Matrix m_matrix;
+    VertexList m_vertex_set;
+    std::vector<vertex_property_type> m_vertex_properties;
+    size_type m_num_edges;
+  };
+  
+  //=========================================================================
+  // Functions required by the AdjacencyMatrix concept 
+
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor,
+            bool>
+  edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+       typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
+       const adjacency_matrix<D,VP,EP,GP,A>& g)
+  {
+    bool exists = detail::get_edge_exists(g.get_edge(u,v), 0);
+    typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor
+      e(exists, u, v, &detail::get_property(g.get_edge(u,v)));
+    return std::make_pair(e, exists);
+  }
+
+  //=========================================================================
+  // Functions required by the IncidenceGraph concept 
+
+  // O(1)
+  template <typename VP, typename EP, typename GP, typename A>
+  std::pair<typename adjacency_matrix<directedS,VP,EP,GP,A>::out_edge_iterator,
+            typename adjacency_matrix<directedS,VP,EP,GP,A>::out_edge_iterator>
+  out_edges
+    (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u,
+     const adjacency_matrix<directedS,VP,EP,GP,A>& g_)
+  {
+    typedef adjacency_matrix<directedS,VP,EP,GP,A> Graph;
+    Graph& g = const_cast<Graph&>(g_);
+    typename Graph::vertices_size_type offset = u * g.m_vertex_set.size();
+    typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
+    typename Graph::MatrixIter l = f + g.m_vertex_set.size();
+    typename Graph::unfiltered_out_edge_iter
+          first(f, u, g.m_vertex_set.size())
+        , last(l, u, g.m_vertex_set.size());
+    detail::does_edge_exist pred;
+    typedef typename Graph::out_edge_iterator out_edge_iterator;
+    return std::make_pair(out_edge_iterator(pred, first, last), 
+                          out_edge_iterator(pred, last, last));
+  }
+
+  // O(1)
+  template <typename VP, typename EP, typename GP, typename A>
+  std::pair<
+    typename adjacency_matrix<undirectedS,VP,EP,GP,A>::out_edge_iterator,
+    typename adjacency_matrix<undirectedS,VP,EP,GP,A>::out_edge_iterator>
+  out_edges
+    (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u,
+     const adjacency_matrix<undirectedS,VP,EP,GP,A>& g_)
+  {
+    typedef adjacency_matrix<undirectedS,VP,EP,GP,A> Graph;
+    Graph& g = const_cast<Graph&>(g_);
+    typename Graph::vertices_size_type offset = u * (u + 1) / 2;
+    typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
+    typename Graph::MatrixIter l = g.m_matrix.end();
+
+    typename Graph::unfiltered_out_edge_iter
+        first(f, u, g.m_vertex_set.size())
+      , last(l, u, g.m_vertex_set.size());
+    
+    detail::does_edge_exist pred;
+    typedef typename Graph::out_edge_iterator out_edge_iterator;
+    return std::make_pair(out_edge_iterator(pred, first, last), 
+                          out_edge_iterator(pred, last, last));
+  }
+  
+  // O(N)
+  template <typename D, typename VP, typename EP, typename GP, typename A>  
+  typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type
+  out_degree(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+             const adjacency_matrix<D,VP,EP,GP,A>& g)
+  {
+    typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type n = 0;
+    typename adjacency_matrix<D,VP,EP,GP,A>::out_edge_iterator f, l;
+    for (tie(f, l) = out_edges(u, g); f != l; ++f)
+      ++n;
+    return n;
+  }
+
+  // O(1)
+  template <typename D, typename VP, typename EP, typename GP, typename A,
+    typename Dir, typename Vertex>  
+  typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
+  source(const detail::matrix_edge_desc_impl<Dir,Vertex>& e,
+         const adjacency_matrix<D,VP,EP,GP,A>&)
+  {
+    return e.m_source;
+  }
+
+  // O(1)
+  template <typename D, typename VP, typename EP, typename GP, typename A,
+    typename Dir, typename Vertex>  
+  typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
+  target(const detail::matrix_edge_desc_impl<Dir,Vertex>& e,
+         const adjacency_matrix<D,VP,EP,GP,A>&)
+  {
+    return e.m_target;
+  }
+
+  //=========================================================================
+  // Functions required by the BidirectionalGraph concept 
+
+  // O(1)
+  template <typename VP, typename EP, typename GP, typename A>
+  std::pair<typename adjacency_matrix<directedS,VP,EP,GP,A>::in_edge_iterator,
+            typename adjacency_matrix<directedS,VP,EP,GP,A>::in_edge_iterator>
+  in_edges
+    (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u,
+     const adjacency_matrix<directedS,VP,EP,GP,A>& g_)
+  {
+    typedef adjacency_matrix<directedS,VP,EP,GP,A> Graph;
+    Graph& g = const_cast<Graph&>(g_);
+    typename Graph::MatrixIter f = g.m_matrix.begin() + u;
+    typename Graph::MatrixIter l = g.m_matrix.end();
+    typename Graph::unfiltered_in_edge_iter
+        first(f, l, u, g.m_vertex_set.size())
+      , last(l, l, u, g.m_vertex_set.size());
+    detail::does_edge_exist pred;
+    typedef typename Graph::in_edge_iterator in_edge_iterator;
+    return std::make_pair(in_edge_iterator(pred, first, last), 
+                          in_edge_iterator(pred, last, last));
+  }
+
+  // O(1)
+  template <typename VP, typename EP, typename GP, typename A>
+  std::pair<
+    typename adjacency_matrix<undirectedS,VP,EP,GP,A>::in_edge_iterator,
+    typename adjacency_matrix<undirectedS,VP,EP,GP,A>::in_edge_iterator>
+  in_edges
+    (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u,
+     const adjacency_matrix<undirectedS,VP,EP,GP,A>& g_)
+  {
+    typedef adjacency_matrix<undirectedS,VP,EP,GP,A> Graph;
+    Graph& g = const_cast<Graph&>(g_);
+    typename Graph::vertices_size_type offset = u * (u + 1) / 2;
+    typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
+    typename Graph::MatrixIter l = g.m_matrix.end();
+
+    typename Graph::unfiltered_in_edge_iter
+        first(f, u, g.m_vertex_set.size())
+      , last(l, u, g.m_vertex_set.size());
+    
+    detail::does_edge_exist pred;
+    typedef typename Graph::in_edge_iterator in_edge_iterator;
+    return std::make_pair(in_edge_iterator(pred, first, last), 
+                          in_edge_iterator(pred, last, last));
+  }
+  
+  // O(N)
+  template <typename D, typename VP, typename EP, typename GP, typename A>  
+  typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type
+  in_degree(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+             const adjacency_matrix<D,VP,EP,GP,A>& g)
+  {
+    typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type n = 0;
+    typename adjacency_matrix<D,VP,EP,GP,A>::in_edge_iterator f, l;
+    for (tie(f, l) = in_edges(u, g); f != l; ++f)
+      ++n;
+    return n;
+  }
+
+  //=========================================================================
+  // Functions required by the AdjacencyGraph concept 
+
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::adjacency_iterator,
+            typename adjacency_matrix<D,VP,EP,GP,A>::adjacency_iterator>
+  adjacent_vertices
+    (typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+     const adjacency_matrix<D,VP,EP,GP,A>& g_)
+  {
+      typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
+      const Graph& cg = static_cast<const Graph&>(g_);
+      Graph& g = const_cast<Graph&>(cg);
+      typedef typename Graph::adjacency_iterator adjacency_iterator;
+      typename Graph::out_edge_iterator first, last;
+      boost::tie(first, last) = out_edges(u, g);
+      return std::make_pair(adjacency_iterator(first, &g),
+                            adjacency_iterator(last, &g));
+  }
+
+  //=========================================================================
+  // Functions required by the VertexListGraph concept 
+
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::vertex_iterator,
+            typename adjacency_matrix<D,VP,EP,GP,A>::vertex_iterator>
+  vertices(const adjacency_matrix<D,VP,EP,GP,A>& g_) {
+    typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
+    Graph& g = const_cast<Graph&>(g_);
+    return std::make_pair(g.m_vertex_set.begin(), g.m_vertex_set.end());
+  }
+
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  typename adjacency_matrix<D,VP,EP,GP,A>::vertices_size_type
+  num_vertices(const adjacency_matrix<D,VP,EP,GP,A>& g) {
+    return g.m_vertex_set.size();
+  }
+  
+  //=========================================================================
+  // Functions required by the EdgeListGraph concept 
+  
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_iterator,
+            typename adjacency_matrix<D,VP,EP,GP,A>::edge_iterator>
+  edges(const adjacency_matrix<D,VP,EP,GP,A>& g_)
+  {
+    typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
+    Graph& g = const_cast<Graph&>(g_);
+    
+    typename Graph::unfiltered_edge_iter
+      first(g.m_matrix.begin(), g.m_matrix.begin(), 
+                                    g.m_vertex_set.size()),
+      last(g.m_matrix.end(), g.m_matrix.begin(), 
+                                    g.m_vertex_set.size());
+    detail::does_edge_exist pred;
+    typedef typename Graph::edge_iterator edge_iterator;
+    return std::make_pair(edge_iterator(pred, first, last),
+                          edge_iterator(pred, last, last));
+  }
+
+  // O(1)
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  typename adjacency_matrix<D,VP,EP,GP,A>::edges_size_type
+  num_edges(const adjacency_matrix<D,VP,EP,GP,A>& g)
+  {
+    return g.m_num_edges;
+  }
+  
+  //=========================================================================
+  // Functions required by the MutableGraph concept 
+
+  // O(1)
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor, bool>
+  add_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+           typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
+           const EP& ep,
+           adjacency_matrix<D,VP,EP,GP,A>& g)
+  {
+    typedef typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor 
+      edge_descriptor;
+    if (detail::get_edge_exists(g.get_edge(u,v), 0) == false) {
+      ++(g.m_num_edges);
+      detail::set_property(g.get_edge(u,v), ep, 0);
+      detail::set_edge_exists(g.get_edge(u,v), true, 0);
+      return std::make_pair
+        (edge_descriptor(true, u, v, &detail::get_property(g.get_edge(u,v))), 
+         true);
+    } else
+      return std::make_pair
+        (edge_descriptor(true, u, v, &detail::get_property(g.get_edge(u,v))),
+         false);
+  }
+  // O(1)
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor, bool>
+  add_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+           typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
+           adjacency_matrix<D,VP,EP,GP,A>& g)
+  {
+    EP ep;
+    return add_edge(u, v, ep, g);
+  }
+
+  // O(1)  
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  void
+  remove_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+              typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
+              adjacency_matrix<D,VP,EP,GP,A>& g)
+  {
+    --(g.m_num_edges);
+    detail::set_edge_exists(g.get_edge(u,v), false, 0);
+  }
+
+  // O(1)
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  void
+  remove_edge(typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor e,
+              adjacency_matrix<D,VP,EP,GP,A>& g)
+  {
+    remove_edge(source(e, g), target(e, g), g);
+  }
+
+  
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  inline typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
+  add_vertex(adjacency_matrix<D,VP,EP,GP,A>& g) {
+    // UNDER CONSTRUCTION
+    assert(false);
+    return *vertices(g).first;
+  }
+
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  inline typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
+  add_vertex(const VP& vp, adjacency_matrix<D,VP,EP,GP,A>& g) {
+    // UNDER CONSTRUCTION
+    assert(false);
+    return *vertices(g).first;
+  }
+
+  template <typename D, typename VP, typename EP, typename GP, typename A>
+  inline void
+  remove_vertex(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+                adjacency_matrix<D,VP,EP,GP,A>& g)
+  {
+    // UNDER CONSTRUCTION
+    assert(false);
+  }
+
+  // O(V)
+  template <typename VP, typename EP, typename GP, typename A>
+  void
+  clear_vertex
+    (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u,
+     adjacency_matrix<directedS,VP,EP,GP,A>& g)
+  {
+    typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_iterator 
+      vi, vi_end;
+    for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+      remove_edge(u, *vi, g);
+    for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+      remove_edge(*vi, u, g);
+  }
+
+  // O(V)
+  template <typename VP, typename EP, typename GP, typename A>
+  void
+  clear_vertex
+    (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u,
+     adjacency_matrix<undirectedS,VP,EP,GP,A>& g)
+  {
+    typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_iterator
+      vi, vi_end;
+    for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+      remove_edge(u, *vi, g);
+  }
+
+  //=========================================================================
+  // Vertex Property Map
+  
+  template <typename GraphPtr, typename Vertex, typename T, typename R, 
+    typename Tag> 
+  class adj_matrix_vertex_property_map 
+    : public put_get_helper<R,
+         adj_matrix_vertex_property_map<GraphPtr, Vertex, T, R, Tag> >
+  {
+  public:
+    typedef T value_type;
+    typedef R reference;
+    typedef Vertex key_type;
+    typedef boost::lvalue_property_map_tag category;
+    adj_matrix_vertex_property_map() { }
+    adj_matrix_vertex_property_map(GraphPtr g) : m_g(g) { }
+    inline reference operator[](key_type v) const {
+      return get_property_value(m_g->m_vertex_properties[v], Tag());
+    }
+    GraphPtr m_g;
+  };
+
+  template <class Property, class Vertex>
+  struct adj_matrix_vertex_id_map
+    : public boost::put_get_helper<Vertex,
+        adj_matrix_vertex_id_map<Property, Vertex> >
+  {
+    typedef Vertex value_type;
+    typedef Vertex reference;
+    typedef Vertex key_type;
+    typedef boost::readable_property_map_tag category;
+     adj_matrix_vertex_id_map() { }
+    template <class Graph>
+    inline adj_matrix_vertex_id_map(const Graph&) { }
+    inline value_type operator[](key_type v) const { return v; }
+  };
+
+  namespace detail {
+
+    struct adj_matrix_any_vertex_pa {
+      template <class Tag, class Graph, class Property>
+      struct bind_ {
+        typedef typename property_value<Property,Tag>::type Value;
+        typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
+        
+        typedef adj_matrix_vertex_property_map<Graph*, Vertex, Value, Value&,
+          Tag> type;
+        typedef adj_matrix_vertex_property_map<const Graph*, Vertex, Value, 
+          const Value&, Tag> const_type;
+      };
+    };
+    struct adj_matrix_id_vertex_pa {
+      template <class Tag, class Graph, class Property>
+      struct bind_ {
+        typedef typename Graph::vertex_descriptor Vertex;
+        typedef adj_matrix_vertex_id_map<Property, Vertex> type;
+        typedef adj_matrix_vertex_id_map<Property, Vertex> const_type;
+      };
+    };
+
+    template <class Tag>
+    struct adj_matrix_choose_vertex_pa_helper {
+      typedef adj_matrix_any_vertex_pa type;
+    };
+    template <>
+    struct adj_matrix_choose_vertex_pa_helper<vertex_index_t> {
+      typedef adj_matrix_id_vertex_pa type;
+    };
+
+    template <class Tag, class Graph, class Property>
+    struct adj_matrix_choose_vertex_pa {
+      typedef typename adj_matrix_choose_vertex_pa_helper<Tag>::type Helper;
+      typedef typename Helper::template bind_<Tag,Graph,Property> Bind;
+      typedef typename Bind::type type;
+      typedef typename Bind::const_type const_type;
+    };
+
+    struct adj_matrix_vertex_property_selector {
+      template <class Graph, class Property, class Tag>
+      struct bind_ {
+        typedef adj_matrix_choose_vertex_pa<Tag,Graph,Property> Choice;
+        typedef typename Choice::type type;
+        typedef typename Choice::const_type const_type;
+      };
+    };
+
+  } // namespace detail
+
+  template <>
+  struct vertex_property_selector<adjacency_matrix_class_tag> {
+    typedef detail::adj_matrix_vertex_property_selector type;
+  };
+  
+  //=========================================================================
+  // Edge Property Map
+
+
+  template <typename Directed, typename Property, typename Vertex, 
+    typename T, typename R, typename Tag> 
+  class adj_matrix_edge_property_map 
+    : public put_get_helper<R,
+         adj_matrix_edge_property_map<Directed, Property, Vertex, T, R, Tag> >
+  {
+  public:
+    typedef T value_type;
+    typedef R reference;
+    typedef detail::matrix_edge_desc_impl<Directed, Vertex> key_type;
+    typedef boost::lvalue_property_map_tag category;
+    inline reference operator[](key_type e) const {
+      Property& p = *(Property*)e.get_property();
+      return get_property_value(p, Tag());
+    }
+  };
+  struct adj_matrix_edge_property_selector {
+    template <class Graph, class Property, class Tag>
+    struct bind_ {
+      typedef typename property_value<Property,Tag>::type T;
+      typedef typename Graph::vertex_descriptor Vertex;
+      typedef adj_matrix_edge_property_map<typename Graph::directed_category,
+        Property, Vertex, T, T&, Tag> type;
+      typedef adj_matrix_edge_property_map<typename Graph::directed_category,
+        Property, Vertex, T, const T&, Tag> const_type;
+    };
+  };
+  template <>
+  struct edge_property_selector<adjacency_matrix_class_tag> {
+    typedef adj_matrix_edge_property_selector type;
+  };
+
+  //=========================================================================
+  // Functions required by PropertyGraph
+
+  namespace detail {
+
+    template <typename Property, typename D, typename VP, typename EP, 
+              typename GP, typename A>
+    typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
+      Property>::type
+    get_dispatch(adjacency_matrix<D,VP,EP,GP,A>& g, Property,
+                 vertex_property_tag)
+    {
+      typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
+      typedef typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
+        Property>::type PA;
+      return PA(&g);
+    }
+    template <typename Property, typename D, typename VP, typename EP, 
+              typename GP, typename A>
+    typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
+      Property>::type
+    get_dispatch(adjacency_matrix<D,VP,EP,GP,A>&, Property,
+                 edge_property_tag)
+    {
+      typedef typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
+        Property>::type PA;
+      return PA();
+    }
+    template <typename Property, typename D, typename VP, typename EP, 
+              typename GP, typename A>
+    typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
+      Property>::const_type
+    get_dispatch(const adjacency_matrix<D,VP,EP,GP,A>& g, Property,
+                 vertex_property_tag)
+    {
+      typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
+      typedef typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
+        Property>::const_type PA;
+      return PA(&g);
+    }
+    template <typename Property, typename D, typename VP, typename EP, 
+              typename GP, typename A>
+    typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
+      Property>::const_type
+    get_dispatch(const adjacency_matrix<D,VP,EP,GP,A>&, Property,
+                 edge_property_tag)
+    {
+      typedef typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>, 
+        Property>::const_type PA;
+      return PA();
+    }
+
+  } // namespace detail
+
+  template <typename Property, typename D, typename VP, typename EP, 
+            typename GP, typename A>
+  inline
+  typename property_map<adjacency_matrix<D,VP,EP,GP,A>, Property>::type
+  get(Property p, adjacency_matrix<D,VP,EP,GP,A>& g)
+  {
+    typedef typename property_kind<Property>::type Kind;
+    return detail::get_dispatch(g, p, Kind());
+  }
+
+  template <typename Property, typename D, typename VP, typename EP, 
+            typename GP, typename A>
+  inline
+  typename property_map<adjacency_matrix<D,VP,EP,GP,A>, Property>::const_type
+  get(Property p, const adjacency_matrix<D,VP,EP,GP,A>& g)
+  {
+    typedef typename property_kind<Property>::type Kind;
+    return detail::get_dispatch(g, p, Kind());
+  }
+
+  template <typename Property, typename D, typename VP, typename EP, 
+            typename GP, typename A, typename Key>
+  inline
+  typename property_traits<
+    typename property_map<adjacency_matrix<D,VP,EP,GP,A>, Property>::const_type
+  >::value_type
+  get(Property p, const adjacency_matrix<D,VP,EP,GP,A>& g,
+      const Key& key)
+  {
+    return get(get(p, g), key);
+  }
+
+  template <typename Property, typename D, typename VP, typename EP, 
+            typename GP, typename A, typename Key, typename Value>
+  inline void
+  put(Property p, adjacency_matrix<D,VP,EP,GP,A>& g,
+      const Key& key, const Value& value)
+  {
+    typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
+    typedef typename boost::property_map<Graph, Property>::type Map;
+    Map pmap = get(p, g);
+    put(pmap, key, value);
+  }
+  
+  //=========================================================================
+  // Other Functions
+
+  template <typename D, typename VP, typename EP, typename GP, typename A>  
+  typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
+  vertex(typename adjacency_matrix<D,VP,EP,GP,A>::vertices_size_type n,
+         const adjacency_matrix<D,VP,EP,GP,A>& g)
+  {
+    return n;
+  }
+
+  // Support for bundled properties
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+  template <typename Directed, typename VertexProperty, typename EdgeProperty, typename GraphProperty,
+            typename Allocator, typename T, typename Bundle>
+  inline
+  typename property_map<adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>,
+                        T Bundle::*>::type
+  get(T Bundle::* p, adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>& g)
+  {
+    typedef typename property_map<adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>,
+                                  T Bundle::*>::type
+      result_type;
+    return result_type(&g, p);
+  }
+
+  template <typename Directed, typename VertexProperty, typename EdgeProperty, typename GraphProperty,
+            typename Allocator, typename T, typename Bundle>
+  inline
+  typename property_map<adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>,
+                        T Bundle::*>::const_type
+  get(T Bundle::* p, adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator> const & g)
+  {
+    typedef typename property_map<adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>,
+                                  T Bundle::*>::const_type
+      result_type;
+    return result_type(&g, p);
+  }
+    
+  template <typename Directed, typename VertexProperty, typename EdgeProperty, typename GraphProperty,
+            typename Allocator, typename T, typename Bundle, typename Key>
+  inline T
+  get(T Bundle::* p, adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator> const & g,
+      const Key& key)
+  {
+    return get(get(p, g), key);
+  }
+
+  template <typename Directed, typename VertexProperty, typename EdgeProperty, typename GraphProperty,
+            typename Allocator, typename T, typename Bundle, typename Key>
+  inline void
+  put(T Bundle::* p, adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>& g,
+      const Key& key, const T& value)
+  {
+    put(get(p, g), key, value);
+  }
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_ADJACENCY_MATRIX_HPP