sl@0: // (C) Copyright David Abrahams 2000. sl@0: // Distributed under the Boost Software License, Version 1.0. (See sl@0: // accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: sl@0: #ifndef REVERSE_GRAPH_DWA092300_H_ sl@0: # define REVERSE_GRAPH_DWA092300_H_ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: namespace boost { sl@0: sl@0: struct reverse_graph_tag { }; sl@0: sl@0: namespace detail { sl@0: sl@0: template struct choose_rev_edge_iter { }; sl@0: template <> struct choose_rev_edge_iter { sl@0: template struct bind_ { sl@0: typedef typename graph_traits::edge_iterator type; sl@0: }; sl@0: }; sl@0: template <> struct choose_rev_edge_iter { sl@0: template struct bind_ { sl@0: typedef void type; sl@0: }; sl@0: }; sl@0: sl@0: } // namespace detail sl@0: sl@0: template sl@0: class reverse_graph { sl@0: typedef reverse_graph Self; sl@0: typedef graph_traits Traits; sl@0: public: sl@0: typedef BidirectionalGraph base_type; sl@0: sl@0: // Constructor sl@0: reverse_graph(GraphRef g) : m_g(g) {} sl@0: sl@0: // Graph requirements sl@0: typedef typename Traits::vertex_descriptor vertex_descriptor; sl@0: typedef typename Traits::edge_descriptor edge_descriptor; sl@0: typedef typename Traits::directed_category directed_category; sl@0: typedef typename Traits::edge_parallel_category edge_parallel_category; sl@0: typedef typename Traits::traversal_category traversal_category; sl@0: sl@0: // IncidenceGraph requirements sl@0: typedef typename Traits::in_edge_iterator out_edge_iterator; sl@0: typedef typename Traits::degree_size_type degree_size_type; sl@0: sl@0: // BidirectionalGraph requirements sl@0: typedef typename Traits::out_edge_iterator in_edge_iterator; sl@0: sl@0: // AdjacencyGraph requirements sl@0: typedef typename adjacency_iterator_generator::type adjacency_iterator; sl@0: sl@0: // VertexListGraph requirements sl@0: typedef typename Traits::vertex_iterator vertex_iterator; sl@0: sl@0: // EdgeListGraph requirements sl@0: enum { is_edge_list = is_convertible::value }; sl@0: typedef detail::choose_rev_edge_iter ChooseEdgeIter; sl@0: typedef typename ChooseEdgeIter:: sl@0: template bind_::type edge_iterator; sl@0: typedef typename Traits::vertices_size_type vertices_size_type; sl@0: typedef typename Traits::edges_size_type edges_size_type; sl@0: sl@0: // More typedefs used by detail::edge_property_map, vertex_property_map sl@0: typedef typename BidirectionalGraph::edge_property_type sl@0: edge_property_type; sl@0: typedef typename BidirectionalGraph::vertex_property_type sl@0: vertex_property_type; sl@0: typedef reverse_graph_tag graph_tag; sl@0: sl@0: #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES sl@0: // Bundled properties support sl@0: template sl@0: typename graph::detail::bundled_result::type& sl@0: operator[](Descriptor x) sl@0: { return m_g[x]; } sl@0: sl@0: template sl@0: typename graph::detail::bundled_result::type const& sl@0: operator[](Descriptor x) const sl@0: { return m_g[x]; } sl@0: #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES sl@0: sl@0: static vertex_descriptor null_vertex() sl@0: { return Traits::null_vertex(); } sl@0: sl@0: // would be private, but template friends aren't portable enough. sl@0: // private: sl@0: GraphRef m_g; sl@0: }; sl@0: sl@0: #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES sl@0: template sl@0: struct vertex_bundle_type > sl@0: : vertex_bundle_type { }; sl@0: sl@0: template sl@0: struct edge_bundle_type > sl@0: : edge_bundle_type { }; sl@0: #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES sl@0: sl@0: template sl@0: inline reverse_graph sl@0: make_reverse_graph(const BidirectionalGraph& g) sl@0: { sl@0: return reverse_graph(g); sl@0: } sl@0: sl@0: template sl@0: inline reverse_graph sl@0: make_reverse_graph(BidirectionalGraph& g) sl@0: { sl@0: return reverse_graph(g); sl@0: } sl@0: sl@0: template sl@0: std::pair::vertex_iterator, sl@0: typename reverse_graph::vertex_iterator> sl@0: vertices(const reverse_graph& g) sl@0: { sl@0: return vertices(g.m_g); sl@0: } sl@0: sl@0: template sl@0: std::pair::edge_iterator, sl@0: typename reverse_graph::edge_iterator> sl@0: edges(const reverse_graph& g) sl@0: { sl@0: return edges(g.m_g); sl@0: } sl@0: sl@0: template sl@0: inline std::pair sl@0: out_edges(const typename BidirectionalGraph::vertex_descriptor u, sl@0: const reverse_graph& g) sl@0: { sl@0: return in_edges(u, g.m_g); sl@0: } sl@0: sl@0: template sl@0: inline typename BidirectionalGraph::vertices_size_type sl@0: num_vertices(const reverse_graph& g) sl@0: { sl@0: return num_vertices(g.m_g); sl@0: } sl@0: sl@0: template sl@0: inline typename reverse_graph::edges_size_type sl@0: num_edges(const reverse_graph& g) sl@0: { sl@0: return num_edges(g.m_g); sl@0: } sl@0: sl@0: template sl@0: inline typename BidirectionalGraph::degree_size_type sl@0: out_degree(const typename BidirectionalGraph::vertex_descriptor u, sl@0: const reverse_graph& g) sl@0: { sl@0: return in_degree(u, g.m_g); sl@0: } sl@0: sl@0: template sl@0: inline std::pair sl@0: edge(const typename BidirectionalGraph::vertex_descriptor u, sl@0: const typename BidirectionalGraph::vertex_descriptor v, sl@0: const reverse_graph& g) sl@0: { sl@0: return edge(v, u, g.m_g); sl@0: } sl@0: sl@0: template sl@0: inline std::pair sl@0: in_edges(const typename BidirectionalGraph::vertex_descriptor u, sl@0: const reverse_graph& g) sl@0: { sl@0: return out_edges(u, g.m_g); sl@0: } sl@0: sl@0: template sl@0: inline std::pair::adjacency_iterator, sl@0: typename reverse_graph::adjacency_iterator> sl@0: adjacent_vertices(const typename BidirectionalGraph::vertex_descriptor u, sl@0: const reverse_graph& g) sl@0: { sl@0: typedef reverse_graph Graph; sl@0: typename Graph::out_edge_iterator first, last; sl@0: tie(first, last) = out_edges(u, g); sl@0: typedef typename Graph::adjacency_iterator adjacency_iterator; sl@0: return std::make_pair(adjacency_iterator(first, const_cast(&g)), sl@0: adjacency_iterator(last, const_cast(&g))); sl@0: } sl@0: sl@0: template sl@0: inline typename BidirectionalGraph::degree_size_type sl@0: in_degree(const typename BidirectionalGraph::vertex_descriptor u, sl@0: const reverse_graph& g) sl@0: { sl@0: return out_degree(u, g.m_g); sl@0: } sl@0: sl@0: template sl@0: inline typename graph_traits::vertex_descriptor sl@0: source(const Edge& e, const reverse_graph& g) sl@0: { sl@0: return target(e, g.m_g); sl@0: } sl@0: sl@0: template sl@0: inline typename graph_traits::vertex_descriptor sl@0: target(const Edge& e, const reverse_graph& g) sl@0: { sl@0: return source(e, g.m_g); sl@0: } sl@0: sl@0: sl@0: namespace detail { sl@0: sl@0: struct reverse_graph_vertex_property_selector { sl@0: template sl@0: struct bind_ { sl@0: typedef typename ReverseGraph::base_type Graph; sl@0: typedef property_map PMap; sl@0: typedef typename PMap::type type; sl@0: typedef typename PMap::const_type const_type; sl@0: }; sl@0: }; sl@0: sl@0: struct reverse_graph_edge_property_selector { sl@0: template sl@0: struct bind_ { sl@0: typedef typename ReverseGraph::base_type Graph; sl@0: typedef property_map PMap; sl@0: typedef typename PMap::type type; sl@0: typedef typename PMap::const_type const_type; sl@0: }; sl@0: }; sl@0: sl@0: } // namespace detail sl@0: sl@0: template <> sl@0: struct vertex_property_selector { sl@0: typedef detail::reverse_graph_vertex_property_selector type; sl@0: }; sl@0: sl@0: template <> sl@0: struct edge_property_selector { sl@0: typedef detail::reverse_graph_edge_property_selector type; sl@0: }; sl@0: sl@0: template sl@0: typename property_map::type sl@0: get(Property p, reverse_graph& g) sl@0: { sl@0: return get(p, g.m_g); sl@0: } sl@0: sl@0: template sl@0: typename property_map::const_type sl@0: get(Property p, const reverse_graph& g) sl@0: { sl@0: const BidirGraph& gref = g.m_g; // in case GRef is non-const sl@0: return get(p, gref); sl@0: } sl@0: sl@0: template sl@0: typename property_traits< sl@0: typename property_map::const_type sl@0: >::value_type sl@0: get(Property p, const reverse_graph& g, const Key& k) sl@0: { sl@0: return get(p, g.m_g, k); sl@0: } sl@0: sl@0: template sl@0: void sl@0: put(Property p, const reverse_graph& g, const Key& k, sl@0: const Value& val) sl@0: { sl@0: put(p, g.m_g, k, val); sl@0: } sl@0: sl@0: template sl@0: inline void sl@0: set_property(const reverse_graph& g, Tag tag, sl@0: const Value& value) sl@0: { sl@0: set_property(g.m_g, tag, value); sl@0: } sl@0: sl@0: template sl@0: inline sl@0: typename graph_property::type sl@0: get_property(const reverse_graph& g, Tag tag) sl@0: { sl@0: return get_property(g.m_g, tag); sl@0: } sl@0: sl@0: } // namespace boost sl@0: sl@0: #endif