1 // (C) Copyright David Abrahams 2000.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef REVERSE_GRAPH_DWA092300_H_
7 # define REVERSE_GRAPH_DWA092300_H_
9 #include <boost/graph/adjacency_iterator.hpp>
10 #include <boost/graph/properties.hpp>
11 #include <boost/tuple/tuple.hpp>
13 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
14 // Stay out of the way of the concept checking class
15 # define BidirectionalGraph BidirectionalGraph_
20 struct reverse_graph_tag
{ };
24 template <bool isEdgeList
> struct choose_rev_edge_iter
{ };
25 template <> struct choose_rev_edge_iter
<true> {
26 template <class G
> struct bind_
{
27 typedef typename graph_traits
<G
>::edge_iterator type
;
30 template <> struct choose_rev_edge_iter
<false> {
31 template <class G
> struct bind_
{
38 template <class BidirectionalGraph
, class GraphRef
= const BidirectionalGraph
&>
40 typedef reverse_graph
<BidirectionalGraph
, GraphRef
> Self
;
41 typedef graph_traits
<BidirectionalGraph
> Traits
;
43 typedef BidirectionalGraph base_type
;
46 reverse_graph(GraphRef g
) : m_g(g
) {}
49 typedef typename
Traits::vertex_descriptor vertex_descriptor
;
50 typedef typename
Traits::edge_descriptor edge_descriptor
;
51 typedef typename
Traits::directed_category directed_category
;
52 typedef typename
Traits::edge_parallel_category edge_parallel_category
;
53 typedef typename
Traits::traversal_category traversal_category
;
55 // IncidenceGraph requirements
56 typedef typename
Traits::in_edge_iterator out_edge_iterator
;
57 typedef typename
Traits::degree_size_type degree_size_type
;
59 // BidirectionalGraph requirements
60 typedef typename
Traits::out_edge_iterator in_edge_iterator
;
62 // AdjacencyGraph requirements
63 typedef typename adjacency_iterator_generator
<Self
,
64 vertex_descriptor
, out_edge_iterator
>::type adjacency_iterator
;
66 // VertexListGraph requirements
67 typedef typename
Traits::vertex_iterator vertex_iterator
;
69 // EdgeListGraph requirements
70 enum { is_edge_list
= is_convertible
<traversal_category
,
71 edge_list_graph_tag
>::value
};
72 typedef detail::choose_rev_edge_iter
<is_edge_list
> ChooseEdgeIter
;
73 typedef typename
ChooseEdgeIter::
74 template bind_
<BidirectionalGraph
>::type edge_iterator
;
75 typedef typename
Traits::vertices_size_type vertices_size_type
;
76 typedef typename
Traits::edges_size_type edges_size_type
;
78 // More typedefs used by detail::edge_property_map, vertex_property_map
79 typedef typename
boost::edge_property_type
<BidirectionalGraph
>::type
81 typedef typename
boost::vertex_property_type
<BidirectionalGraph
>::type
83 typedef reverse_graph_tag graph_tag
;
85 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
86 // Bundled properties support
87 template<typename Descriptor
>
88 typename
graph::detail::bundled_result
<BidirectionalGraph
,
90 operator[](Descriptor x
)
93 template<typename Descriptor
>
94 typename
graph::detail::bundled_result
<BidirectionalGraph
,
95 Descriptor
>::type
const&
96 operator[](Descriptor x
) const
98 #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
100 static vertex_descriptor
null_vertex()
101 { return Traits::null_vertex(); }
103 // would be private, but template friends aren't portable enough.
108 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
109 template<typename Graph
, typename GraphRef
>
110 struct vertex_bundle_type
<reverse_graph
<Graph
, GraphRef
> >
111 : vertex_bundle_type
<Graph
> { };
113 template<typename Graph
, typename GraphRef
>
114 struct edge_bundle_type
<reverse_graph
<Graph
, GraphRef
> >
115 : edge_bundle_type
<Graph
> { };
116 #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
118 template <class BidirectionalGraph
>
119 inline reverse_graph
<BidirectionalGraph
>
120 make_reverse_graph(const BidirectionalGraph
& g
)
122 return reverse_graph
<BidirectionalGraph
>(g
);
125 template <class BidirectionalGraph
>
126 inline reverse_graph
<BidirectionalGraph
, BidirectionalGraph
&>
127 make_reverse_graph(BidirectionalGraph
& g
)
129 return reverse_graph
<BidirectionalGraph
, BidirectionalGraph
&>(g
);
132 template <class BidirectionalGraph
, class GRef
>
133 std::pair
<typename reverse_graph
<BidirectionalGraph
>::vertex_iterator
,
134 typename reverse_graph
<BidirectionalGraph
>::vertex_iterator
>
135 vertices(const reverse_graph
<BidirectionalGraph
,GRef
>& g
)
137 return vertices(g
.m_g
);
140 template <class BidirectionalGraph
, class GRef
>
141 std::pair
<typename reverse_graph
<BidirectionalGraph
>::edge_iterator
,
142 typename reverse_graph
<BidirectionalGraph
>::edge_iterator
>
143 edges(const reverse_graph
<BidirectionalGraph
,GRef
>& g
)
148 template <class BidirectionalGraph
, class GRef
>
149 inline std::pair
<typename graph_traits
<BidirectionalGraph
>::in_edge_iterator
,
150 typename graph_traits
<BidirectionalGraph
>::in_edge_iterator
>
151 out_edges(const typename graph_traits
<BidirectionalGraph
>::vertex_descriptor u
,
152 const reverse_graph
<BidirectionalGraph
,GRef
>& g
)
154 return in_edges(u
, g
.m_g
);
157 template <class BidirectionalGraph
, class GRef
>
158 inline typename graph_traits
<BidirectionalGraph
>::vertices_size_type
159 num_vertices(const reverse_graph
<BidirectionalGraph
,GRef
>& g
)
161 return num_vertices(g
.m_g
);
164 template <class BidirectionalGraph
, class GRef
>
165 inline typename reverse_graph
<BidirectionalGraph
>::edges_size_type
166 num_edges(const reverse_graph
<BidirectionalGraph
,GRef
>& g
)
168 return num_edges(g
.m_g
);
171 template <class BidirectionalGraph
, class GRef
>
172 inline typename graph_traits
<BidirectionalGraph
>::degree_size_type
173 out_degree(const typename graph_traits
<BidirectionalGraph
>::vertex_descriptor u
,
174 const reverse_graph
<BidirectionalGraph
,GRef
>& g
)
176 return in_degree(u
, g
.m_g
);
179 template <class BidirectionalGraph
, class GRef
>
180 inline std::pair
<typename graph_traits
<BidirectionalGraph
>::edge_descriptor
,
182 edge(const typename graph_traits
<BidirectionalGraph
>::vertex_descriptor u
,
183 const typename graph_traits
<BidirectionalGraph
>::vertex_descriptor v
,
184 const reverse_graph
<BidirectionalGraph
,GRef
>& g
)
186 return edge(v
, u
, g
.m_g
);
189 template <class BidirectionalGraph
, class GRef
>
190 inline std::pair
<typename graph_traits
<BidirectionalGraph
>::out_edge_iterator
,
191 typename graph_traits
<BidirectionalGraph
>::out_edge_iterator
>
192 in_edges(const typename graph_traits
<BidirectionalGraph
>::vertex_descriptor u
,
193 const reverse_graph
<BidirectionalGraph
,GRef
>& g
)
195 return out_edges(u
, g
.m_g
);
198 template <class BidirectionalGraph
, class GRef
>
199 inline std::pair
<typename reverse_graph
<BidirectionalGraph
,GRef
>::adjacency_iterator
,
200 typename reverse_graph
<BidirectionalGraph
,GRef
>::adjacency_iterator
>
201 adjacent_vertices(typename graph_traits
<BidirectionalGraph
>::vertex_descriptor u
,
202 const reverse_graph
<BidirectionalGraph
,GRef
>& g
)
204 typedef reverse_graph
<BidirectionalGraph
,GRef
> Graph
;
205 typename graph_traits
<Graph
>::out_edge_iterator first
, last
;
206 tie(first
, last
) = out_edges(u
, g
);
207 typedef typename graph_traits
<Graph
>::adjacency_iterator adjacency_iterator
;
208 return std::make_pair(adjacency_iterator(first
, const_cast<Graph
*>(&g
)),
209 adjacency_iterator(last
, const_cast<Graph
*>(&g
)));
212 template <class BidirectionalGraph
, class GRef
>
213 inline typename graph_traits
<BidirectionalGraph
>::degree_size_type
214 in_degree(const typename graph_traits
<BidirectionalGraph
>::vertex_descriptor u
,
215 const reverse_graph
<BidirectionalGraph
,GRef
>& g
)
217 return out_degree(u
, g
.m_g
);
220 template <class Edge
, class BidirectionalGraph
, class GRef
>
221 inline typename graph_traits
<BidirectionalGraph
>::vertex_descriptor
222 source(const Edge
& e
, const reverse_graph
<BidirectionalGraph
,GRef
>& g
)
224 return target(e
, g
.m_g
);
227 template <class Edge
, class BidirectionalGraph
, class GRef
>
228 inline typename graph_traits
<BidirectionalGraph
>::vertex_descriptor
229 target(const Edge
& e
, const reverse_graph
<BidirectionalGraph
,GRef
>& g
)
231 return source(e
, g
.m_g
);
237 struct reverse_graph_vertex_property_selector
{
238 template <class ReverseGraph
, class Property
, class Tag
>
240 typedef typename
ReverseGraph::base_type Graph
;
241 typedef property_map
<Graph
, Tag
> PMap
;
242 typedef typename
PMap::type type
;
243 typedef typename
PMap::const_type const_type
;
247 struct reverse_graph_edge_property_selector
{
248 template <class ReverseGraph
, class Property
, class Tag
>
250 typedef typename
ReverseGraph::base_type Graph
;
251 typedef property_map
<Graph
, Tag
> PMap
;
252 typedef typename
PMap::type type
;
253 typedef typename
PMap::const_type const_type
;
257 } // namespace detail
260 struct vertex_property_selector
<reverse_graph_tag
> {
261 typedef detail::reverse_graph_vertex_property_selector type
;
265 struct edge_property_selector
<reverse_graph_tag
> {
266 typedef detail::reverse_graph_edge_property_selector type
;
269 template <class BidirGraph
, class GRef
, class Property
>
270 typename property_map
<BidirGraph
, Property
>::type
271 get(Property p
, reverse_graph
<BidirGraph
,GRef
>& g
)
273 return get(p
, g
.m_g
);
276 template <class BidirGraph
, class GRef
, class Property
>
277 typename property_map
<BidirGraph
, Property
>::const_type
278 get(Property p
, const reverse_graph
<BidirGraph
,GRef
>& g
)
280 const BidirGraph
& gref
= g
.m_g
; // in case GRef is non-const
284 template <class BidirectionalGraph
, class GRef
, class Property
, class Key
>
285 typename property_traits
<
286 typename property_map
<BidirectionalGraph
, Property
>::const_type
288 get(Property p
, const reverse_graph
<BidirectionalGraph
,GRef
>& g
, const Key
& k
)
290 return get(p
, g
.m_g
, k
);
293 template <class BidirectionalGraph
, class GRef
, class Property
, class Key
, class Value
>
295 put(Property p
, const reverse_graph
<BidirectionalGraph
,GRef
>& g
, const Key
& k
,
298 put(p
, g
.m_g
, k
, val
);
301 template<typename BidirectionalGraph
, typename GRef
, typename Tag
,
304 set_property(const reverse_graph
<BidirectionalGraph
,GRef
>& g
, Tag tag
,
307 set_property(g
.m_g
, tag
, value
);
310 template<typename BidirectionalGraph
, typename GRef
, typename Tag
>
312 typename graph_property
<BidirectionalGraph
, Tag
>::type
313 get_property(const reverse_graph
<BidirectionalGraph
,GRef
>& g
, Tag tag
)
315 return get_property(g
.m_g
, tag
);
320 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
321 // Stay out of the way of the concept checking class
322 # undef BidirectionalGraph