http://www.ousob.com --- Legacy Redefined OuSob - File: /wwwroot/clipx/usr/include/boost/graph/adjacency_matrix.hpp

//======================================================================= // Copyright 2001 University of Notre Dame. // Author: Jeremy G. Siek // // 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> 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; }; //======================================================================= // 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; }; //======================================================================= // 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_bidir_t is_bidir; typedef typename Directed::is_directed_t is_directed; public: typedef typename boost::ct_if_t<is_bidir, bidirectional_tag, typename boost::ct_if_t<is_directed, directed_tag, undirected_tag >::type >::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: #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::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 void 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; // EdgeListGrpah 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 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