//======================================================================= | |
// 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 <boost/assert.hpp> | |
#include <boost/limits.hpp> | |
#include <boost/iterator.hpp> | |
#include <boost/graph/graph_traits.hpp> | |
#include <boost/graph/graph_mutability_traits.hpp> | |
#include <boost/graph/graph_selectors.hpp> | |
#include <boost/mpl/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/range/irange.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(); } | |
}; | |
// Note to self... The int for get_edge_exists and set_edge exist helps | |
// make these calls unambiguous. | |
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 | |
} | |
// NOTE: These functions collide with the get_property function for | |
// accessing bundled graph properties. Be excplicit when using them. | |
template <typename EdgeProperty> | |
const EdgeProperty& | |
get_edge_property(const std::pair<bool, EdgeProperty>& stored_edge) { | |
return stored_edge.second; | |
} | |
template <typename EdgeProperty> | |
EdgeProperty& | |
get_edge_property(std::pair<bool, EdgeProperty>& stored_edge) { | |
return stored_edge.second; | |
} | |
template <typename StoredEdgeProperty, typename EdgeProperty> | |
inline void | |
set_edge_property(std::pair<bool, StoredEdgeProperty>& stored_edge, | |
const EdgeProperty& ep, int) { | |
stored_edge.second = ep; | |
} | |
inline const no_property& get_edge_property(const char&) { | |
static no_property s_prop; | |
return s_prop; | |
} | |
inline no_property& get_edge_property(char&) { | |
static no_property s_prop; | |
return s_prop; | |
} | |
template <typename EdgeProxy, typename EdgeProperty> | |
inline void set_edge_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_edge_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_edge_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_edge_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_edge_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_edge_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 mpl::if_<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 | |
#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES) | |
typedef typename graph_detail::graph_prop<GraphProperty>::property graph_property_type; | |
typedef typename graph_detail::graph_prop<GraphProperty>::bundle graph_bundled; | |
typedef typename graph_detail::vertex_prop<VertexProperty>::property vertex_property_type; | |
typedef typename graph_detail::vertex_prop<VertexProperty>::bundle vertex_bundled; | |
typedef typename graph_detail::edge_prop<EdgeProperty>::property edge_property_type; | |
typedef typename graph_detail::edge_prop<EdgeProperty>::bundle edge_bundled; | |
#else | |
typedef GraphProperty graph_property_type; | |
typedef no_graph_bundle graph_bundled; | |
typedef VertexProperty vertex_property_type; | |
typedef no_vertex_bundle vertex_bundled; | |
typedef EdgeProperty edge_property_type; | |
typedef no_edge_bundle edge_bundled; | |
#endif | |
public: // should be private | |
typedef typename mpl::if_<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 mpl::if_< | |
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 mpl::if_< | |
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, | |
const GraphProperty& p = GraphProperty()) | |
: 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), | |
m_property(p) { } | |
template <typename EdgeIterator> | |
adjacency_matrix(EdgeIterator first, | |
EdgeIterator last, | |
vertices_size_type n_vertices, | |
const GraphProperty& p = GraphProperty()) | |
: 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), | |
m_property(p) | |
{ | |
for (; first != last; ++first) { | |
add_edge(first->first, first->second, *this); | |
} | |
} | |
template <typename EdgeIterator, typename EdgePropertyIterator> | |
adjacency_matrix(EdgeIterator first, | |
EdgeIterator last, | |
EdgePropertyIterator ep_iter, | |
vertices_size_type n_vertices, | |
const GraphProperty& p = GraphProperty()) | |
: 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), | |
m_property(p) | |
{ | |
for (; first != last; ++first, ++ep_iter) { | |
add_edge(first->first, first->second, *ep_iter, *this); | |
} | |
} | |
#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]; } | |
graph_bundled& operator[](graph_bundle_t) | |
{ return get_property(*this); } | |
const graph_bundled& operator[](graph_bundle_t) const | |
{ return get_property(*this); } | |
#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; | |
graph_property_type m_property; | |
}; | |
//========================================================================= | |
// 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_edge_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 (boost::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 (boost::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, | |
typename EP2> | |
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 EP2& 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_edge_property(g.get_edge(u,v), EP(ep), 0); | |
detail::set_edge_exists(g.get_edge(u,v), true, 0); | |
return std::make_pair | |
(edge_descriptor(true, u, v, &detail::get_edge_property(g.get_edge(u,v))), | |
true); | |
} else | |
return std::make_pair | |
(edge_descriptor(true, u, v, &detail::get_edge_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) | |
{ | |
// Don'remove the edge unless it already exists. | |
if(detail::get_edge_exists(g.get_edge(u,v), 0)) { | |
--(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 | |
BOOST_ASSERT(false); | |
return *vertices(g).first; | |
} | |
template <typename D, typename VP, typename EP, typename GP, typename A, | |
typename VP2> | |
inline typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor | |
add_vertex(const VP2& /*vp*/, adjacency_matrix<D,VP,EP,GP,A>& g) { | |
// UNDER CONSTRUCTION | |
BOOST_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 | |
BOOST_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 (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) | |
remove_edge(u, *vi, g); | |
for (boost::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 (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) | |
remove_edge(u, *vi, g); | |
} | |
//========================================================================= | |
// Functions required by the PropertyGraph concept | |
// O(1) | |
template <typename D, typename VP, typename EP, typename GP, typename A, | |
typename Tag, typename Value> | |
inline void | |
set_property(adjacency_matrix<D,VP,EP,GP,A>& g, Tag, const Value& value) | |
{ | |
get_property_value(g.m_property, Tag()) = value; | |
} | |
template <typename D, typename VP, typename EP, typename GP, typename A, | |
typename Tag> | |
inline typename graph_property<adjacency_matrix<D,VP,EP,GP,A>, Tag>::type& | |
get_property(adjacency_matrix<D,VP,EP,GP,A>& g, Tag) | |
{ | |
return get_property_value(g.m_property, Tag()); | |
} | |
template <typename D, typename VP, typename EP, typename GP, typename A, | |
typename Tag> | |
inline const typename graph_property<adjacency_matrix<D,VP,EP,GP,A>, Tag>::type& | |
get_property(const adjacency_matrix<D,VP,EP,GP,A>& g, Tag) | |
{ | |
return get_property_value(g.m_property, Tag()); | |
} | |
//========================================================================= | |
// 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>&) | |
{ | |
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 | |
#define ADJMAT_PARAMS \ | |
typename D, typename VP, typename EP, typename GP, typename A | |
#define ADJMAT adjacency_matrix<D,VP,EP,GP,A> | |
template <ADJMAT_PARAMS> | |
struct graph_mutability_traits<ADJMAT> { | |
typedef mutable_edge_property_graph_tag category; | |
}; | |
#undef ADJMAT_PARAMS | |
#undef ADJMAT | |
} // namespace boost | |
#endif // BOOST_ADJACENCY_MATRIX_HPP |