Boost logo

Boost :

Subject: [boost] [BGL] map_as_graph.hpp
From: Shaun Jackman (sjackman_at_[hidden])
Date: 2011-11-04 19:14:52


Hi,

In the spirit of vector_as_graph.hpp, I created map_as_graph.hpp. One
useful feature is that the vertex_descriptor can be any user-defined
type, such as a string or an arbitrary object. It's not in a form that's
ready to be included in Boost, but I have found it occasionally useful.
I though I'd post it in the case that someone else found it useful. If
someone found it useful enough that he or she where interested in
further developing to the point where it could be included in Boost,
please be my guest.

Cheers,
Shaun

#ifndef MAP_AS_GRAPH_HPP
#define MAP_AS_GRAPH_HPP 1

#include <boost/graph/graph_traits.hpp>
#include <cassert>
#include <map>
#include <utility> // for make_pair

namespace boost {

/**
 * A std::map is a model of a directed graph.
 * @author Shaun Jackman <sjackman_at_[hidden]>
 */
template <typename V, typename T>
struct graph_traits<std::map<V, T> > {
        // Graph
        typedef V vertex_descriptor;
        typedef boost::directed_tag directed_category;
        struct traversal_category
                : boost::adjacency_graph_tag,
                boost::vertex_list_graph_tag
                { };
        typedef boost::disallow_parallel_edge_tag edge_parallel_category;

        // IncidenceGraph
        typedef std::pair<vertex_descriptor, vertex_descriptor>
                edge_descriptor;
        typedef size_t degree_size_type;

        /** Iterate through the out edges of a vertex. */
        struct out_edge_iterator
                : std::map<V, typename T::mapped_type>::const_iterator
        {
                typedef typename std::map<V,
                                typename T::mapped_type>::const_iterator It;
                out_edge_iterator(const It& it, vertex_descriptor src)
                        : It(it), m_src(src) { }
                edge_descriptor operator*() const
                {
                        return edge_descriptor(m_src, It::operator*().first);
                }
          private:
                vertex_descriptor m_src;
        };

        // BidirectionalGraph
        typedef void in_edge_iterator;

        // AdjacencyGraph

        /** Iterate through the adjacent vertices of a vertex. */
        struct adjacency_iterator
                : std::map<V, typename T::mapped_type>::const_iterator
        {
                typedef typename std::map<V,
                                typename T::mapped_type>::const_iterator It;
                adjacency_iterator(const It& it) : It(it) { }
                const vertex_descriptor& operator*() const
                {
                        return It::operator*().first;
                }
        };

        // VertexListGraph

        /** Iterate through the vertices of this graph. */
        struct vertex_iterator : std::map<V, T>::const_iterator
        {
                typedef typename std::map<V, T>::const_iterator It;
                vertex_iterator(const It& it) : It(it) { }
                const vertex_descriptor& operator*() const
                {
                        return It::operator*().first;
                }
        };

        typedef size_t vertices_size_type;

        // EdgeListGraph
        typedef void edge_iterator;
        typedef void edges_size_type;
}; // graph_traits<std::map>

// IncidenceGraph

template <typename V, typename T>
std::pair<
        typename graph_traits<std::map<V, T> >::out_edge_iterator,
        typename graph_traits<std::map<V, T> >::out_edge_iterator>
out_edges(
                typename graph_traits<std::map<V, T> >::vertex_descriptor u,
                const std::map<V, T>& g)
{
        typedef typename graph_traits<std::map<V, T> >::out_edge_iterator
                out_edge_iterator;
        typename std::map<V, T>::const_iterator it = g.find(u);
        assert(it != g.end());
        return make_pair(
                out_edge_iterator(it->second.begin(), u),
                out_edge_iterator(it->second.end(), u));
}

template <typename V, typename T>
typename graph_traits<std::map<V, T> >::degree_size_type
out_degree(
                typename graph_traits<std::map<V, T> >::vertex_descriptor u,
                const std::map<V, T>& g)
{
        typename std::map<V, T>::const_iterator it = g.find(u);
        assert(it != g.end());
        return it->second.size();
}

// AdjacencyGraph

template <typename V, typename T>
std::pair<typename graph_traits<std::map<V, T> >::adjacency_iterator,
        typename graph_traits<std::map<V, T> >::adjacency_iterator>
adjacent_vertices(
                typename graph_traits<std::map<V, T> >::vertex_descriptor u,
                const std::map<V, T>& g)
{
        typename std::map<V, T>::const_iterator it = g.find(u);
        assert(it != g.end());
        return make_pair(it->second.begin(), it->second.end());
}

// VertexListGraph

template <typename V, typename T>
std::pair<typename graph_traits<std::map<V, T> >::vertex_iterator,
        typename graph_traits<std::map<V, T> >::vertex_iterator>
vertices(const std::map<V, T>& g)
{
        return make_pair(g.begin(), g.end());
}

// AdjacencyMatrix

template <typename V, typename T>
std::pair<
        typename graph_traits<std::map<V, T> >::edge_descriptor, bool>
edge(
                typename graph_traits<std::map<V, T> >::vertex_descriptor u,
                typename graph_traits<std::map<V, T> >::vertex_descriptor v,
                std::map<V, T>& g)
{
        typename std::map<V, T>::const_iterator it = g.find(u);
        return std::make_pair(make_pair(u, v),
                        it == g.end() ? false : it->second.count(v) > 0);
}

// VertexMutableGraph

template <typename V, typename T>
void remove_vertex(
                typename graph_traits<std::map<V, T> >::vertex_descriptor u,
                std::map<V, T>& g)
{
        size_t n = g.erase(u);
        assert(n == 1);
        (void)n;
}

// EdgeMutableGraph

template <typename V, typename T>
void clear_out_edges(
                typename graph_traits<std::map<V, T> >::vertex_descriptor u,
                std::map<V, T>& g)
{
        typename std::map<V, T>::iterator it = g.find(u);
        assert(it != g.end());
        it->second.clear();
}

template <typename V, typename T>
std::pair<
        typename graph_traits<std::map<V, T> >::edge_descriptor, bool>
add_edge(
                typename graph_traits<std::map<V, T> >::vertex_descriptor u,
                typename graph_traits<std::map<V, T> >::vertex_descriptor v,
                std::map<V, T>& g)
{
        typename edge_property<std::map<V, T> >::type ep;
        return make_pair(std::make_pair(u, v),
                        g[u].insert(make_pair(v, ep)).second);
}

template <typename V, typename T>
void remove_edge(
                typename graph_traits<std::map<V, T> >::vertex_descriptor u,
                typename graph_traits<std::map<V, T> >::vertex_descriptor v,
                std::map<V, T>& g)
{
        size_t n = g[u].erase(v);
        assert(n == 1);
        (void)n;
}

// PropertyGraph

template <typename V, typename T>
no_property get(vertex_bundle_t, const std::map<V, T>&,
                typename graph_traits<std::map<V, T> >::vertex_descriptor)
{
        return no_property();
}

template <typename V, typename T>
const typename T::mapped_type&
get(edge_bundle_t, const std::map<V, T>& g,
                typename graph_traits<std::map<V, T> >::edge_descriptor e)
{
        typename std::map<V, T>::const_iterator u = g.find(source(e, g));
        assert(u != g.end());
        typename T::const_iterator v = u->second.find(target(e, g));
        assert(v != u->second.end());
        return v->second;
}

// MutablePropertyGraph

namespace boost {

template <typename V, typename T>
class vertex_property<std::map<V, T> > {
  public:
        typedef no_property type;
};

template <typename V, typename T>
class edge_property<std::map<V, T> > {
  public:
        typedef typename T::mapped_type type;
};

}

template <typename V, typename T>
std::pair<
        typename graph_traits<std::map<V, T> >::edge_descriptor, bool>
add_edge(
                typename graph_traits<std::map<V, T> >::vertex_descriptor u,
                typename graph_traits<std::map<V, T> >::vertex_descriptor v,
                typename edge_property<std::map<V, T> >::type ep,
                std::map<V, T>& g)
{
        return make_pair(std::make_pair(u, v),
                        g[u].insert(std::make_pair(v, ep)).second);
}

} // namespace boost

#endif




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk