#ifndef MAP_AS_GRAPH_HPP #define MAP_AS_GRAPH_HPP 1 #include #include #include #include // for make_pair namespace boost { /** * A std::map is a model of a directed graph. * @author Shaun Jackman */ template struct graph_traits > { // 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 edge_descriptor; typedef size_t degree_size_type; /** Iterate through the out edges of a vertex. */ struct out_edge_iterator : std::map::const_iterator { typedef typename std::map::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::const_iterator { typedef typename std::map::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::const_iterator { typedef typename std::map::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 // IncidenceGraph template std::pair< typename graph_traits >::out_edge_iterator, typename graph_traits >::out_edge_iterator> out_edges( typename graph_traits >::vertex_descriptor u, const std::map& g) { typedef typename graph_traits >::out_edge_iterator out_edge_iterator; typename std::map::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 graph_traits >::degree_size_type out_degree( typename graph_traits >::vertex_descriptor u, const std::map& g) { typename std::map::const_iterator it = g.find(u); assert(it != g.end()); return it->second.size(); } // AdjacencyGraph template std::pair >::adjacency_iterator, typename graph_traits >::adjacency_iterator> adjacent_vertices( typename graph_traits >::vertex_descriptor u, const std::map& g) { typename std::map::const_iterator it = g.find(u); assert(it != g.end()); return make_pair(it->second.begin(), it->second.end()); } // VertexListGraph template std::pair >::vertex_iterator, typename graph_traits >::vertex_iterator> vertices(const std::map& g) { return make_pair(g.begin(), g.end()); } // AdjacencyMatrix template std::pair< typename graph_traits >::edge_descriptor, bool> edge( typename graph_traits >::vertex_descriptor u, typename graph_traits >::vertex_descriptor v, std::map& g) { typename std::map::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 void remove_vertex( typename graph_traits >::vertex_descriptor u, std::map& g) { size_t n = g.erase(u); assert(n == 1); (void)n; } // EdgeMutableGraph template void clear_out_edges( typename graph_traits >::vertex_descriptor u, std::map& g) { typename std::map::iterator it = g.find(u); assert(it != g.end()); it->second.clear(); } template std::pair< typename graph_traits >::edge_descriptor, bool> add_edge( typename graph_traits >::vertex_descriptor u, typename graph_traits >::vertex_descriptor v, std::map& g) { typename edge_property >::type ep; return make_pair(std::make_pair(u, v), g[u].insert(make_pair(v, ep)).second); } template void remove_edge( typename graph_traits >::vertex_descriptor u, typename graph_traits >::vertex_descriptor v, std::map& g) { size_t n = g[u].erase(v); assert(n == 1); (void)n; } // PropertyGraph template no_property get(vertex_bundle_t, const std::map&, typename graph_traits >::vertex_descriptor) { return no_property(); } template const typename T::mapped_type& get(edge_bundle_t, const std::map& g, typename graph_traits >::edge_descriptor e) { typename std::map::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 class vertex_property > { public: typedef no_property type; }; template class edge_property > { public: typedef typename T::mapped_type type; }; } template std::pair< typename graph_traits >::edge_descriptor, bool> add_edge( typename graph_traits >::vertex_descriptor u, typename graph_traits >::vertex_descriptor v, typename edge_property >::type ep, std::map& g) { return make_pair(std::make_pair(u, v), g[u].insert(std::make_pair(v, ep)).second); } } // namespace boost #endif