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