Chris@16
|
1 // (C) Copyright David Abrahams 2000.
|
Chris@16
|
2 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
3 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5
|
Chris@16
|
6 #ifndef REVERSE_GRAPH_DWA092300_H_
|
Chris@16
|
7 # define REVERSE_GRAPH_DWA092300_H_
|
Chris@16
|
8
|
Chris@16
|
9 #include <boost/graph/adjacency_iterator.hpp>
|
Chris@16
|
10 #include <boost/graph/properties.hpp>
|
Chris@16
|
11 #include <boost/iterator/transform_iterator.hpp>
|
Chris@16
|
12 #include <boost/tuple/tuple.hpp>
|
Chris@16
|
13 #include <boost/type_traits.hpp>
|
Chris@16
|
14 #include <boost/mpl/if.hpp>
|
Chris@16
|
15
|
Chris@16
|
16 namespace boost {
|
Chris@16
|
17
|
Chris@16
|
18 struct reverse_graph_tag { };
|
Chris@16
|
19
|
Chris@16
|
20 namespace detail {
|
Chris@16
|
21
|
Chris@16
|
22 template <typename EdgeDesc>
|
Chris@16
|
23 class reverse_graph_edge_descriptor {
|
Chris@16
|
24 public:
|
Chris@16
|
25 EdgeDesc underlying_descx; // Odd name is because this needs to be public but shouldn't be exposed to users anymore
|
Chris@16
|
26
|
Chris@16
|
27 private:
|
Chris@16
|
28 typedef EdgeDesc base_descriptor_type;
|
Chris@16
|
29
|
Chris@16
|
30 public:
|
Chris@16
|
31 explicit reverse_graph_edge_descriptor(const EdgeDesc& underlying_descx = EdgeDesc())
|
Chris@16
|
32 : underlying_descx(underlying_descx) {}
|
Chris@16
|
33
|
Chris@16
|
34 friend bool operator==(const reverse_graph_edge_descriptor& a, const reverse_graph_edge_descriptor& b) {
|
Chris@16
|
35 return a.underlying_descx == b.underlying_descx;
|
Chris@16
|
36 }
|
Chris@16
|
37 friend bool operator!=(const reverse_graph_edge_descriptor& a, const reverse_graph_edge_descriptor& b) {
|
Chris@16
|
38 return a.underlying_descx != b.underlying_descx;
|
Chris@16
|
39 }
|
Chris@16
|
40 friend bool operator<(const reverse_graph_edge_descriptor& a, const reverse_graph_edge_descriptor& b) {
|
Chris@16
|
41 return a.underlying_descx < b.underlying_descx;
|
Chris@16
|
42 }
|
Chris@16
|
43 friend bool operator>(const reverse_graph_edge_descriptor& a, const reverse_graph_edge_descriptor& b) {
|
Chris@16
|
44 return a.underlying_descx > b.underlying_descx;
|
Chris@16
|
45 }
|
Chris@16
|
46 friend bool operator<=(const reverse_graph_edge_descriptor& a, const reverse_graph_edge_descriptor& b) {
|
Chris@16
|
47 return a.underlying_descx <= b.underlying_descx;
|
Chris@16
|
48 }
|
Chris@16
|
49 friend bool operator>=(const reverse_graph_edge_descriptor& a, const reverse_graph_edge_descriptor& b) {
|
Chris@16
|
50 return a.underlying_descx >= b.underlying_descx;
|
Chris@16
|
51 }
|
Chris@16
|
52 };
|
Chris@16
|
53
|
Chris@16
|
54 template <typename EdgeDesc>
|
Chris@16
|
55 struct reverse_graph_edge_descriptor_maker {
|
Chris@16
|
56 typedef reverse_graph_edge_descriptor<EdgeDesc> result_type;
|
Chris@16
|
57
|
Chris@16
|
58 reverse_graph_edge_descriptor<EdgeDesc> operator()(const EdgeDesc& ed) const {
|
Chris@16
|
59 return reverse_graph_edge_descriptor<EdgeDesc>(ed);
|
Chris@16
|
60 }
|
Chris@16
|
61 };
|
Chris@16
|
62
|
Chris@16
|
63 template <typename EdgeDesc, typename Iter>
|
Chris@16
|
64 std::pair<transform_iterator<reverse_graph_edge_descriptor_maker<EdgeDesc>, Iter>,
|
Chris@16
|
65 transform_iterator<reverse_graph_edge_descriptor_maker<EdgeDesc>, Iter> >
|
Chris@16
|
66 reverse_edge_iter_pair(const std::pair<Iter, Iter>& ip) {
|
Chris@16
|
67 return std::make_pair(make_transform_iterator(ip.first, reverse_graph_edge_descriptor_maker<EdgeDesc>()),
|
Chris@16
|
68 make_transform_iterator(ip.second, reverse_graph_edge_descriptor_maker<EdgeDesc>()));
|
Chris@16
|
69 }
|
Chris@16
|
70
|
Chris@16
|
71 // Get the underlying descriptor from a vertex or edge descriptor
|
Chris@16
|
72 template <typename Desc>
|
Chris@16
|
73 struct get_underlying_descriptor_from_reverse_descriptor {
|
Chris@16
|
74 typedef Desc type;
|
Chris@16
|
75 static Desc convert(const Desc& d) {return d;}
|
Chris@16
|
76 };
|
Chris@16
|
77 template <typename Desc>
|
Chris@16
|
78 struct get_underlying_descriptor_from_reverse_descriptor<reverse_graph_edge_descriptor<Desc> > {
|
Chris@16
|
79 typedef Desc type;
|
Chris@16
|
80 static Desc convert(const reverse_graph_edge_descriptor<Desc>& d) {return d.underlying_descx;}
|
Chris@16
|
81 };
|
Chris@16
|
82
|
Chris@16
|
83 template <bool isEdgeList> struct choose_rev_edge_iter { };
|
Chris@16
|
84 template <> struct choose_rev_edge_iter<true> {
|
Chris@16
|
85 template <class G> struct bind_ {
|
Chris@16
|
86 typedef transform_iterator<reverse_graph_edge_descriptor_maker<typename graph_traits<G>::edge_descriptor>, typename graph_traits<G>::edge_iterator> type;
|
Chris@16
|
87 };
|
Chris@16
|
88 };
|
Chris@16
|
89 template <> struct choose_rev_edge_iter<false> {
|
Chris@16
|
90 template <class G> struct bind_ {
|
Chris@16
|
91 typedef void type;
|
Chris@16
|
92 };
|
Chris@16
|
93 };
|
Chris@16
|
94
|
Chris@16
|
95 } // namespace detail
|
Chris@16
|
96
|
Chris@16
|
97 template <class BidirectionalGraph, class GraphRef = const BidirectionalGraph&>
|
Chris@16
|
98 class reverse_graph {
|
Chris@16
|
99 typedef reverse_graph<BidirectionalGraph, GraphRef> Self;
|
Chris@16
|
100 typedef graph_traits<BidirectionalGraph> Traits;
|
Chris@16
|
101 public:
|
Chris@16
|
102 typedef BidirectionalGraph base_type;
|
Chris@16
|
103 typedef GraphRef base_ref_type;
|
Chris@16
|
104
|
Chris@16
|
105 // Constructor
|
Chris@16
|
106 reverse_graph(GraphRef g) : m_g(g) {}
|
Chris@16
|
107 // Conversion from reverse_graph on non-const reference to one on const reference
|
Chris@16
|
108 reverse_graph(const reverse_graph<BidirectionalGraph, BidirectionalGraph&>& o): m_g(o.m_g) {}
|
Chris@16
|
109
|
Chris@16
|
110 // Graph requirements
|
Chris@16
|
111 typedef typename Traits::vertex_descriptor vertex_descriptor;
|
Chris@16
|
112 typedef detail::reverse_graph_edge_descriptor<typename Traits::edge_descriptor> edge_descriptor;
|
Chris@16
|
113 typedef typename Traits::directed_category directed_category;
|
Chris@16
|
114 typedef typename Traits::edge_parallel_category edge_parallel_category;
|
Chris@16
|
115 typedef typename Traits::traversal_category traversal_category;
|
Chris@16
|
116
|
Chris@16
|
117 // IncidenceGraph requirements
|
Chris@16
|
118 typedef transform_iterator<detail::reverse_graph_edge_descriptor_maker<typename Traits::edge_descriptor>, typename Traits::in_edge_iterator> out_edge_iterator;
|
Chris@16
|
119 typedef typename Traits::degree_size_type degree_size_type;
|
Chris@16
|
120
|
Chris@16
|
121 // BidirectionalGraph requirements
|
Chris@16
|
122 typedef transform_iterator<detail::reverse_graph_edge_descriptor_maker<typename Traits::edge_descriptor>, typename Traits::out_edge_iterator> in_edge_iterator;
|
Chris@16
|
123
|
Chris@16
|
124 // AdjacencyGraph requirements
|
Chris@16
|
125 typedef typename adjacency_iterator_generator<Self, vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
|
Chris@16
|
126
|
Chris@16
|
127 // VertexListGraph requirements
|
Chris@16
|
128 typedef typename Traits::vertex_iterator vertex_iterator;
|
Chris@16
|
129
|
Chris@16
|
130 // EdgeListGraph requirements
|
Chris@16
|
131 enum { is_edge_list = is_convertible<traversal_category,
|
Chris@16
|
132 edge_list_graph_tag>::value };
|
Chris@16
|
133 typedef detail::choose_rev_edge_iter<is_edge_list> ChooseEdgeIter;
|
Chris@16
|
134 typedef typename ChooseEdgeIter::
|
Chris@16
|
135 template bind_<BidirectionalGraph>::type edge_iterator;
|
Chris@16
|
136 typedef typename Traits::vertices_size_type vertices_size_type;
|
Chris@16
|
137 typedef typename Traits::edges_size_type edges_size_type;
|
Chris@16
|
138
|
Chris@16
|
139 typedef reverse_graph_tag graph_tag;
|
Chris@16
|
140
|
Chris@16
|
141 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
|
Chris@16
|
142 // Bundled properties support
|
Chris@16
|
143 template<typename Descriptor>
|
Chris@16
|
144 typename graph::detail::bundled_result<
|
Chris@16
|
145 BidirectionalGraph,
|
Chris@16
|
146 typename detail::get_underlying_descriptor_from_reverse_descriptor<Descriptor>::type
|
Chris@16
|
147 >::type&
|
Chris@16
|
148 operator[](Descriptor x)
|
Chris@16
|
149 { return m_g[detail::get_underlying_descriptor_from_reverse_descriptor<Descriptor>::convert(x)]; }
|
Chris@16
|
150
|
Chris@16
|
151 template<typename Descriptor>
|
Chris@16
|
152 typename graph::detail::bundled_result<
|
Chris@16
|
153 BidirectionalGraph,
|
Chris@16
|
154 typename detail::get_underlying_descriptor_from_reverse_descriptor<Descriptor>::type
|
Chris@16
|
155 >::type const&
|
Chris@16
|
156 operator[](Descriptor x) const
|
Chris@16
|
157 { return m_g[detail::get_underlying_descriptor_from_reverse_descriptor<Descriptor>::convert(x)]; }
|
Chris@16
|
158 #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
|
Chris@16
|
159
|
Chris@16
|
160 static vertex_descriptor null_vertex()
|
Chris@16
|
161 { return Traits::null_vertex(); }
|
Chris@16
|
162
|
Chris@16
|
163 // would be private, but template friends aren't portable enough.
|
Chris@16
|
164 // private:
|
Chris@16
|
165 GraphRef m_g;
|
Chris@16
|
166 };
|
Chris@16
|
167
|
Chris@16
|
168
|
Chris@16
|
169 // These are separate so they are not instantiated unless used (see bug 1021)
|
Chris@16
|
170 template <class BidirectionalGraph, class GraphRef>
|
Chris@16
|
171 struct vertex_property_type<reverse_graph<BidirectionalGraph, GraphRef> > {
|
Chris@16
|
172 typedef typename boost::vertex_property_type<BidirectionalGraph>::type type;
|
Chris@16
|
173 };
|
Chris@16
|
174
|
Chris@16
|
175 template <class BidirectionalGraph, class GraphRef>
|
Chris@16
|
176 struct edge_property_type<reverse_graph<BidirectionalGraph, GraphRef> > {
|
Chris@16
|
177 typedef typename boost::edge_property_type<BidirectionalGraph>::type type;
|
Chris@16
|
178 };
|
Chris@16
|
179
|
Chris@16
|
180 template <class BidirectionalGraph, class GraphRef>
|
Chris@16
|
181 struct graph_property_type<reverse_graph<BidirectionalGraph, GraphRef> > {
|
Chris@16
|
182 typedef typename boost::graph_property_type<BidirectionalGraph>::type type;
|
Chris@16
|
183 };
|
Chris@16
|
184
|
Chris@16
|
185 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
|
Chris@16
|
186 template<typename Graph, typename GraphRef>
|
Chris@16
|
187 struct vertex_bundle_type<reverse_graph<Graph, GraphRef> >
|
Chris@16
|
188 : vertex_bundle_type<Graph> { };
|
Chris@16
|
189
|
Chris@16
|
190 template<typename Graph, typename GraphRef>
|
Chris@16
|
191 struct edge_bundle_type<reverse_graph<Graph, GraphRef> >
|
Chris@16
|
192 : edge_bundle_type<Graph> { };
|
Chris@16
|
193
|
Chris@16
|
194 template<typename Graph, typename GraphRef>
|
Chris@16
|
195 struct graph_bundle_type<reverse_graph<Graph, GraphRef> >
|
Chris@16
|
196 : graph_bundle_type<Graph> { };
|
Chris@16
|
197 #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
|
Chris@16
|
198
|
Chris@16
|
199 template <class BidirectionalGraph>
|
Chris@16
|
200 inline reverse_graph<BidirectionalGraph>
|
Chris@16
|
201 make_reverse_graph(const BidirectionalGraph& g)
|
Chris@16
|
202 {
|
Chris@16
|
203 return reverse_graph<BidirectionalGraph>(g);
|
Chris@16
|
204 }
|
Chris@16
|
205
|
Chris@16
|
206 template <class BidirectionalGraph>
|
Chris@16
|
207 inline reverse_graph<BidirectionalGraph, BidirectionalGraph&>
|
Chris@16
|
208 make_reverse_graph(BidirectionalGraph& g)
|
Chris@16
|
209 {
|
Chris@16
|
210 return reverse_graph<BidirectionalGraph, BidirectionalGraph&>(g);
|
Chris@16
|
211 }
|
Chris@16
|
212
|
Chris@16
|
213 template <class BidirectionalGraph, class GRef>
|
Chris@16
|
214 std::pair<typename reverse_graph<BidirectionalGraph>::vertex_iterator,
|
Chris@16
|
215 typename reverse_graph<BidirectionalGraph>::vertex_iterator>
|
Chris@16
|
216 vertices(const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
217 {
|
Chris@16
|
218 return vertices(g.m_g);
|
Chris@16
|
219 }
|
Chris@16
|
220
|
Chris@16
|
221 template <class BidirectionalGraph, class GRef>
|
Chris@16
|
222 std::pair<typename reverse_graph<BidirectionalGraph>::edge_iterator,
|
Chris@16
|
223 typename reverse_graph<BidirectionalGraph>::edge_iterator>
|
Chris@16
|
224 edges(const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
225 {
|
Chris@16
|
226 return detail::reverse_edge_iter_pair<typename graph_traits<BidirectionalGraph>::edge_descriptor>(edges(g.m_g));
|
Chris@16
|
227 }
|
Chris@16
|
228
|
Chris@16
|
229 template <class BidirectionalGraph, class GRef>
|
Chris@16
|
230 inline std::pair<typename reverse_graph<BidirectionalGraph>::out_edge_iterator,
|
Chris@16
|
231 typename reverse_graph<BidirectionalGraph>::out_edge_iterator>
|
Chris@16
|
232 out_edges(const typename graph_traits<BidirectionalGraph>::vertex_descriptor u,
|
Chris@16
|
233 const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
234 {
|
Chris@16
|
235 return detail::reverse_edge_iter_pair<typename graph_traits<BidirectionalGraph>::edge_descriptor>(in_edges(u, g.m_g));
|
Chris@16
|
236 }
|
Chris@16
|
237
|
Chris@16
|
238 template <class BidirectionalGraph, class GRef>
|
Chris@16
|
239 inline typename graph_traits<BidirectionalGraph>::vertices_size_type
|
Chris@16
|
240 num_vertices(const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
241 {
|
Chris@16
|
242 return num_vertices(g.m_g);
|
Chris@16
|
243 }
|
Chris@16
|
244
|
Chris@16
|
245 template <class BidirectionalGraph, class GRef>
|
Chris@16
|
246 inline typename reverse_graph<BidirectionalGraph>::edges_size_type
|
Chris@16
|
247 num_edges(const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
248 {
|
Chris@16
|
249 return num_edges(g.m_g);
|
Chris@16
|
250 }
|
Chris@16
|
251
|
Chris@16
|
252 template <class BidirectionalGraph, class GRef>
|
Chris@16
|
253 inline typename graph_traits<BidirectionalGraph>::degree_size_type
|
Chris@16
|
254 out_degree(const typename graph_traits<BidirectionalGraph>::vertex_descriptor u,
|
Chris@16
|
255 const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
256 {
|
Chris@16
|
257 return in_degree(u, g.m_g);
|
Chris@16
|
258 }
|
Chris@16
|
259
|
Chris@16
|
260 template <class BidirectionalGraph, class GRef>
|
Chris@16
|
261 inline typename graph_traits<BidirectionalGraph>::vertex_descriptor
|
Chris@16
|
262 vertex(const typename graph_traits<BidirectionalGraph>::vertices_size_type v,
|
Chris@16
|
263 const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
264 {
|
Chris@16
|
265 return vertex(v, g.m_g);
|
Chris@16
|
266 }
|
Chris@16
|
267
|
Chris@16
|
268 template <class BidirectionalGraph, class GRef>
|
Chris@16
|
269 inline std::pair< typename graph_traits<reverse_graph<BidirectionalGraph,GRef> >::edge_descriptor,
|
Chris@16
|
270 bool>
|
Chris@16
|
271 edge(const typename graph_traits<BidirectionalGraph>::vertex_descriptor u,
|
Chris@16
|
272 const typename graph_traits<BidirectionalGraph>::vertex_descriptor v,
|
Chris@16
|
273 const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
274 {
|
Chris@16
|
275 typedef typename graph_traits<BidirectionalGraph>::edge_descriptor underlying_edge_descriptor;
|
Chris@16
|
276 std::pair<underlying_edge_descriptor, bool> e = edge(v, u, g.m_g);
|
Chris@16
|
277 return std::make_pair(detail::reverse_graph_edge_descriptor<underlying_edge_descriptor>(e.first), e.second);
|
Chris@16
|
278 }
|
Chris@16
|
279
|
Chris@16
|
280 template <class BidirectionalGraph, class GRef>
|
Chris@16
|
281 inline std::pair<typename reverse_graph<BidirectionalGraph>::in_edge_iterator,
|
Chris@16
|
282 typename reverse_graph<BidirectionalGraph>::in_edge_iterator>
|
Chris@16
|
283 in_edges(const typename graph_traits<BidirectionalGraph>::vertex_descriptor u,
|
Chris@16
|
284 const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
285 {
|
Chris@16
|
286 return detail::reverse_edge_iter_pair<typename graph_traits<BidirectionalGraph>::edge_descriptor>(out_edges(u, g.m_g));
|
Chris@16
|
287 }
|
Chris@16
|
288
|
Chris@16
|
289 template <class BidirectionalGraph, class GRef>
|
Chris@16
|
290 inline std::pair<typename reverse_graph<BidirectionalGraph,GRef>::adjacency_iterator,
|
Chris@16
|
291 typename reverse_graph<BidirectionalGraph,GRef>::adjacency_iterator>
|
Chris@16
|
292 adjacent_vertices(typename graph_traits<BidirectionalGraph>::vertex_descriptor u,
|
Chris@16
|
293 const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
294 {
|
Chris@16
|
295 typedef reverse_graph<BidirectionalGraph,GRef> Graph;
|
Chris@16
|
296 typename graph_traits<Graph>::out_edge_iterator first, last;
|
Chris@16
|
297 boost::tie(first, last) = out_edges(u, g);
|
Chris@16
|
298 typedef typename graph_traits<Graph>::adjacency_iterator adjacency_iterator;
|
Chris@16
|
299 return std::make_pair(adjacency_iterator(first, const_cast<Graph*>(&g)),
|
Chris@16
|
300 adjacency_iterator(last, const_cast<Graph*>(&g)));
|
Chris@16
|
301 }
|
Chris@16
|
302
|
Chris@16
|
303 template <class BidirectionalGraph, class GRef>
|
Chris@16
|
304 inline typename graph_traits<BidirectionalGraph>::degree_size_type
|
Chris@16
|
305 in_degree(const typename graph_traits<BidirectionalGraph>::vertex_descriptor u,
|
Chris@16
|
306 const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
307 {
|
Chris@16
|
308 return out_degree(u, g.m_g);
|
Chris@16
|
309 }
|
Chris@16
|
310
|
Chris@16
|
311 template <class Edge, class BidirectionalGraph, class GRef>
|
Chris@16
|
312 inline typename graph_traits<BidirectionalGraph>::vertex_descriptor
|
Chris@16
|
313 source(const detail::reverse_graph_edge_descriptor<Edge>& e, const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
314 {
|
Chris@16
|
315 return target(e.underlying_descx, g.m_g);
|
Chris@16
|
316 }
|
Chris@16
|
317
|
Chris@16
|
318 template <class Edge, class BidirectionalGraph, class GRef>
|
Chris@16
|
319 inline typename graph_traits<BidirectionalGraph>::vertex_descriptor
|
Chris@16
|
320 target(const detail::reverse_graph_edge_descriptor<Edge>& e, const reverse_graph<BidirectionalGraph,GRef>& g)
|
Chris@16
|
321 {
|
Chris@16
|
322 return source(e.underlying_descx, g.m_g);
|
Chris@16
|
323 }
|
Chris@16
|
324
|
Chris@16
|
325
|
Chris@16
|
326 namespace detail {
|
Chris@16
|
327
|
Chris@16
|
328 template <typename PM>
|
Chris@16
|
329 struct reverse_graph_edge_property_map {
|
Chris@16
|
330 private:
|
Chris@16
|
331 PM underlying_pm;
|
Chris@16
|
332
|
Chris@16
|
333 public:
|
Chris@16
|
334 typedef reverse_graph_edge_descriptor<typename property_traits<PM>::key_type> key_type;
|
Chris@16
|
335 typedef typename property_traits<PM>::value_type value_type;
|
Chris@16
|
336 typedef typename property_traits<PM>::reference reference;
|
Chris@16
|
337 typedef typename property_traits<PM>::category category;
|
Chris@16
|
338
|
Chris@16
|
339 explicit reverse_graph_edge_property_map(const PM& pm): underlying_pm(pm) {}
|
Chris@16
|
340
|
Chris@16
|
341 friend reference
|
Chris@16
|
342 get(const reverse_graph_edge_property_map& m,
|
Chris@16
|
343 const key_type& e) {
|
Chris@16
|
344 return get(m.underlying_pm, e.underlying_descx);
|
Chris@16
|
345 }
|
Chris@16
|
346
|
Chris@16
|
347 friend void
|
Chris@16
|
348 put(const reverse_graph_edge_property_map& m,
|
Chris@16
|
349 const key_type& e,
|
Chris@16
|
350 const value_type& v) {
|
Chris@16
|
351 put(m.underlying_pm, e.underlying_descx, v);
|
Chris@16
|
352 }
|
Chris@16
|
353
|
Chris@16
|
354 reference operator[](const key_type& k) const {
|
Chris@16
|
355 return (this->underlying_pm)[k.underlying_descx];
|
Chris@16
|
356 }
|
Chris@16
|
357 };
|
Chris@16
|
358
|
Chris@16
|
359 } // namespace detail
|
Chris@16
|
360
|
Chris@16
|
361 template <class BidirGraph, class GRef, class Property>
|
Chris@16
|
362 struct property_map<reverse_graph<BidirGraph, GRef>, Property> {
|
Chris@16
|
363 typedef boost::is_same<typename detail::property_kind_from_graph<BidirGraph, Property>::type, edge_property_tag> is_edge_prop;
|
Chris@16
|
364 typedef boost::is_const<typename boost::remove_reference<GRef>::type> is_ref_const;
|
Chris@16
|
365 typedef typename boost::mpl::if_<
|
Chris@16
|
366 is_ref_const,
|
Chris@16
|
367 typename property_map<BidirGraph, Property>::const_type,
|
Chris@16
|
368 typename property_map<BidirGraph, Property>::type>::type
|
Chris@16
|
369 orig_type;
|
Chris@16
|
370 typedef typename property_map<BidirGraph, Property>::const_type orig_const_type;
|
Chris@16
|
371 typedef typename boost::mpl::if_<is_edge_prop, detail::reverse_graph_edge_property_map<orig_type>, orig_type>::type type;
|
Chris@16
|
372 typedef typename boost::mpl::if_<is_edge_prop, detail::reverse_graph_edge_property_map<orig_const_type>, orig_const_type>::type const_type;
|
Chris@16
|
373 };
|
Chris@16
|
374
|
Chris@16
|
375 template <class BidirGraph, class GRef, class Property>
|
Chris@16
|
376 struct property_map<const reverse_graph<BidirGraph, GRef>, Property> {
|
Chris@16
|
377 typedef boost::is_same<typename detail::property_kind_from_graph<BidirGraph, Property>::type, edge_property_tag> is_edge_prop;
|
Chris@16
|
378 typedef typename property_map<BidirGraph, Property>::const_type orig_const_type;
|
Chris@16
|
379 typedef typename boost::mpl::if_<is_edge_prop, detail::reverse_graph_edge_property_map<orig_const_type>, orig_const_type>::type const_type;
|
Chris@16
|
380 typedef const_type type;
|
Chris@16
|
381 };
|
Chris@16
|
382
|
Chris@16
|
383 template <class BidirGraph, class GRef, class Property>
|
Chris@16
|
384 typename disable_if<
|
Chris@16
|
385 is_same<Property, edge_underlying_t>,
|
Chris@16
|
386 typename property_map<reverse_graph<BidirGraph,GRef>, Property>::type>::type
|
Chris@16
|
387 get(Property p, reverse_graph<BidirGraph,GRef>& g)
|
Chris@16
|
388 {
|
Chris@16
|
389 return typename property_map<reverse_graph<BidirGraph,GRef>, Property>::type(get(p, g.m_g));
|
Chris@16
|
390 }
|
Chris@16
|
391
|
Chris@16
|
392 template <class BidirGraph, class GRef, class Property>
|
Chris@16
|
393 typename disable_if<
|
Chris@16
|
394 is_same<Property, edge_underlying_t>,
|
Chris@16
|
395 typename property_map<reverse_graph<BidirGraph,GRef>, Property>::const_type>::type
|
Chris@16
|
396 get(Property p, const reverse_graph<BidirGraph,GRef>& g)
|
Chris@16
|
397 {
|
Chris@16
|
398 const BidirGraph& gref = g.m_g; // in case GRef is non-const
|
Chris@16
|
399 return typename property_map<reverse_graph<BidirGraph,GRef>, Property>::const_type(get(p, gref));
|
Chris@16
|
400 }
|
Chris@16
|
401
|
Chris@16
|
402 template <class BidirectionalGraph, class GRef, class Property, class Key>
|
Chris@16
|
403 typename disable_if<
|
Chris@16
|
404 is_same<Property, edge_underlying_t>,
|
Chris@16
|
405 typename property_traits<
|
Chris@16
|
406 typename property_map<reverse_graph<BidirectionalGraph, GRef>, Property>::const_type
|
Chris@16
|
407 >::value_type>::type
|
Chris@16
|
408 get(Property p, const reverse_graph<BidirectionalGraph,GRef>& g, const Key& k)
|
Chris@16
|
409 {
|
Chris@16
|
410 return get(get(p, g), k);
|
Chris@16
|
411 }
|
Chris@16
|
412
|
Chris@16
|
413 template <class BidirectionalGraph, class GRef, class Property, class Key, class Value>
|
Chris@16
|
414 void
|
Chris@16
|
415 put(Property p, reverse_graph<BidirectionalGraph,GRef>& g, const Key& k,
|
Chris@16
|
416 const Value& val)
|
Chris@16
|
417 {
|
Chris@16
|
418 put(get(p, g), k, val);
|
Chris@16
|
419 }
|
Chris@16
|
420
|
Chris@16
|
421 // Get the underlying descriptor from a reverse_graph's wrapped edge descriptor
|
Chris@16
|
422
|
Chris@16
|
423 namespace detail {
|
Chris@16
|
424 template <class E>
|
Chris@16
|
425 struct underlying_edge_desc_map_type {
|
Chris@16
|
426 E operator[](const reverse_graph_edge_descriptor<E>& k) const {
|
Chris@16
|
427 return k.underlying_descx;
|
Chris@16
|
428 }
|
Chris@16
|
429 };
|
Chris@16
|
430
|
Chris@16
|
431 template <class E>
|
Chris@16
|
432 E
|
Chris@16
|
433 get(underlying_edge_desc_map_type<E> m,
|
Chris@16
|
434 const reverse_graph_edge_descriptor<E>& k)
|
Chris@16
|
435 {
|
Chris@16
|
436 return m[k];
|
Chris@16
|
437 }
|
Chris@16
|
438 }
|
Chris@16
|
439
|
Chris@16
|
440 template <class E>
|
Chris@16
|
441 struct property_traits<detail::underlying_edge_desc_map_type<E> > {
|
Chris@16
|
442 typedef detail::reverse_graph_edge_descriptor<E> key_type;
|
Chris@16
|
443 typedef E value_type;
|
Chris@16
|
444 typedef const E& reference;
|
Chris@16
|
445 typedef readable_property_map_tag category;
|
Chris@16
|
446 };
|
Chris@16
|
447
|
Chris@16
|
448 template <class Graph, class GRef>
|
Chris@16
|
449 struct property_map<reverse_graph<Graph, GRef>, edge_underlying_t> {
|
Chris@16
|
450 private:
|
Chris@16
|
451 typedef typename graph_traits<Graph>::edge_descriptor ed;
|
Chris@16
|
452
|
Chris@16
|
453 public:
|
Chris@16
|
454 typedef detail::underlying_edge_desc_map_type<ed> type;
|
Chris@16
|
455 typedef detail::underlying_edge_desc_map_type<ed> const_type;
|
Chris@16
|
456 };
|
Chris@16
|
457
|
Chris@16
|
458 template <typename T> struct is_reverse_graph: boost::mpl::false_ {};
|
Chris@16
|
459 template <typename G, typename R> struct is_reverse_graph<reverse_graph<G, R> >: boost::mpl::true_ {};
|
Chris@16
|
460
|
Chris@16
|
461 template <class G>
|
Chris@16
|
462 typename enable_if<is_reverse_graph<G>,
|
Chris@16
|
463 detail::underlying_edge_desc_map_type<typename graph_traits<typename G::base_type>::edge_descriptor> >::type
|
Chris@16
|
464 get(edge_underlying_t,
|
Chris@16
|
465 G&)
|
Chris@16
|
466 {
|
Chris@16
|
467 return detail::underlying_edge_desc_map_type<typename graph_traits<typename G::base_type>::edge_descriptor>();
|
Chris@16
|
468 }
|
Chris@16
|
469
|
Chris@16
|
470 template <class G>
|
Chris@16
|
471 typename enable_if<is_reverse_graph<G>, typename graph_traits<typename G::base_type>::edge_descriptor>::type
|
Chris@16
|
472 get(edge_underlying_t,
|
Chris@16
|
473 G&,
|
Chris@16
|
474 const typename graph_traits<G>::edge_descriptor& k)
|
Chris@16
|
475 {
|
Chris@16
|
476 return k.underlying_descx;
|
Chris@16
|
477 }
|
Chris@16
|
478
|
Chris@16
|
479 template <class G>
|
Chris@16
|
480 typename enable_if<is_reverse_graph<G>, detail::underlying_edge_desc_map_type<typename graph_traits<typename G::base_type>::edge_descriptor> >::type
|
Chris@16
|
481 get(edge_underlying_t,
|
Chris@16
|
482 const G&)
|
Chris@16
|
483 {
|
Chris@16
|
484 return detail::underlying_edge_desc_map_type<typename graph_traits<typename G::base_type>::edge_descriptor>();
|
Chris@16
|
485 }
|
Chris@16
|
486
|
Chris@16
|
487 template <class G>
|
Chris@16
|
488 typename enable_if<is_reverse_graph<G>, typename graph_traits<typename G::base_type>::edge_descriptor>::type
|
Chris@16
|
489 get(edge_underlying_t,
|
Chris@16
|
490 const G&,
|
Chris@16
|
491 const typename graph_traits<G>::edge_descriptor& k)
|
Chris@16
|
492 {
|
Chris@16
|
493 return k.underlying_descx;
|
Chris@16
|
494 }
|
Chris@16
|
495
|
Chris@16
|
496 // Access to wrapped graph's graph properties
|
Chris@16
|
497
|
Chris@16
|
498 template<typename BidirectionalGraph, typename GRef, typename Tag,
|
Chris@16
|
499 typename Value>
|
Chris@16
|
500 inline void
|
Chris@16
|
501 set_property(const reverse_graph<BidirectionalGraph,GRef>& g, Tag tag,
|
Chris@16
|
502 const Value& value)
|
Chris@16
|
503 {
|
Chris@16
|
504 set_property(g.m_g, tag, value);
|
Chris@16
|
505 }
|
Chris@16
|
506
|
Chris@16
|
507 template<typename BidirectionalGraph, typename GRef, typename Tag>
|
Chris@16
|
508 inline
|
Chris@16
|
509 typename boost::mpl::if_<
|
Chris@16
|
510 boost::is_const<typename boost::remove_reference<GRef>::type>,
|
Chris@16
|
511 const typename graph_property<BidirectionalGraph, Tag>::type&,
|
Chris@16
|
512 typename graph_property<BidirectionalGraph, Tag>::type& >::type
|
Chris@16
|
513 get_property(const reverse_graph<BidirectionalGraph,GRef>& g, Tag tag)
|
Chris@16
|
514 {
|
Chris@16
|
515 return get_property(g.m_g, tag);
|
Chris@16
|
516 }
|
Chris@16
|
517
|
Chris@16
|
518 } // namespace boost
|
Chris@16
|
519
|
Chris@16
|
520 #endif
|