Util--  1.1
undirected_graph.hh
Go to the documentation of this file.
1 // (C) Copyright Sylvain Joyeux 2006
2 //
3 // Original code from reverse_graph adaptor
4 // (C) Copyright David Abrahams 2000.
5 //
6 // Distributed under the Boost Software License, Version 1.0. (See
7 // accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 
10 #ifndef UNDIRECTED_GRAPH_HPP
11 #define UNDIRECTED_GRAPH_HPP
12 
13 #include <boost/graph/adjacency_iterator.hpp>
14 #include <boost/graph/properties.hpp>
15 #include <boost/static_assert.hpp>
16 #include "iterator_sequence.hh"
17 #include <boost/iterator/transform_iterator.hpp>
18 
19 #include <boost/type_traits.hpp>
20 
21 namespace utilmm {
23 
27  template <class BidirectionalGraph, class GraphRef = const BidirectionalGraph&>
30  typedef boost::graph_traits<BidirectionalGraph> Traits;
31 
32  BOOST_STATIC_ASSERT(( boost::is_same<boost::bidirectional_tag, typename BidirectionalGraph::directed_category>::value ));
33 
34  public:
35  typedef BidirectionalGraph base_type;
36 
37  // Constructor
38  undirected_graph(GraphRef g) : m_g(g) {}
39 
40  // Graph requirements
41  typedef typename Traits::vertex_descriptor vertex_descriptor;
42  typedef boost::undirected_tag directed_category;
43  typedef typename Traits::edge_parallel_category edge_parallel_category;
44  typedef typename Traits::traversal_category traversal_category;
45 
46  // Add a 'reverse' flag to edge descriptors, so that source() and target() know what
47  // needs to be done
48  typedef std::pair<typename Traits::edge_descriptor, bool> edge_descriptor;
49  typedef edge_descriptor (*make_undirected_edge_descriptor)(typename Traits::edge_descriptor);
50 
51  // Out edges do not need to be swapped
52  static edge_descriptor make_out_edge_descriptor(typename Traits::edge_descriptor e)
53  { return std::make_pair(e, false); }
55  public boost::transform_iterator<make_undirected_edge_descriptor, typename Traits::out_edge_iterator>
56  {
57  typedef boost::transform_iterator<make_undirected_edge_descriptor, typename Traits::out_edge_iterator>
58  base_type;
59 
60  public:
62  base_out_edge_iterator(typename Traits::out_edge_iterator e)
63  : base_type(e, make_out_edge_descriptor) {}
64  };
65 
66  static edge_descriptor make_in_edge_descriptor(typename Traits::edge_descriptor e)
67  { return std::make_pair(e, true); }
69  public boost::transform_iterator<make_undirected_edge_descriptor, typename Traits::in_edge_iterator>
70  {
71  typedef boost::transform_iterator<make_undirected_edge_descriptor, typename Traits::in_edge_iterator>
72  base_type;
73 
74  public:
76  base_in_edge_iterator(typename Traits::in_edge_iterator e)
77  : base_type(e, make_in_edge_descriptor) {}
78  };
79 
80  // Do not swap plain edge iterators
81  class edge_iterator :
82  public boost::transform_iterator<make_undirected_edge_descriptor, typename Traits::edge_iterator>
83  {
84  typedef boost::transform_iterator<make_undirected_edge_descriptor, typename Traits::edge_iterator>
85  base_type;
86  public:
88  edge_iterator(typename Traits::edge_iterator e)
89  : base_type(e, make_out_edge_descriptor) {}
90  };
91 
92  // IncidenceGraph requirements
93  typedef typename Traits::degree_size_type degree_size_type;
94  typedef iterator_sequence
99 
100  // AdjacencyGraph requirements
101  typedef iterator_sequence
102  < typename Traits::adjacency_iterator
103  , typename BidirectionalGraph::inv_adjacency_iterator
106 
107  // VertexListGraph requirements
108  typedef typename Traits::vertex_iterator vertex_iterator;
109 
110  // EdgeListGraph requirements
111  typedef typename Traits::edge_iterator traits_edge_iterator;
112  typedef typename Traits::vertices_size_type vertices_size_type;
113  typedef typename Traits::edges_size_type edges_size_type;
114 
115  // More typedefs used by detail::edge_property_map, vertex_property_map
116  typedef typename BidirectionalGraph::edge_property_type
118  typedef typename BidirectionalGraph::vertex_property_type
121 
123  { return Traits::null_vertex(); }
124 
125  // Bundled properties support
126  typename boost::graph::detail::bundled_result<BidirectionalGraph,
127  edge_descriptor>::type&
129  { return m_g[x.first]; }
130 
131  typename boost::graph::detail::bundled_result<BidirectionalGraph,
132  edge_descriptor>::type const&
134  { return m_g[x.first]; }
135 
136 
137 
138  typename boost::graph::detail::bundled_result<BidirectionalGraph,
139  vertex_descriptor>::type&
141  { return m_g[x]; }
142 
143  typename boost::graph::detail::bundled_result<BidirectionalGraph,
144  vertex_descriptor>::type const&
146  { return m_g[x]; }
147 
148 
149  // would be private, but template friends aren't portable enough.
150  // private:
151  GraphRef m_g;
152  };
153 
154  template <class BidirectionalGraph>
156  make_undirected_graph(const BidirectionalGraph& g)
157  {
159  }
160 
161  template <class BidirectionalGraph>
162  inline undirected_graph<BidirectionalGraph, BidirectionalGraph&>
163  make_undirected_graph(BidirectionalGraph& g)
164  {
166  }
167 
168  template <class BidirectionalGraph, class GRef>
169  std::pair<typename undirected_graph<BidirectionalGraph>::vertex_iterator,
170  typename undirected_graph<BidirectionalGraph>::vertex_iterator>
172  {
173  return vertices(g.m_g);
174  }
175 
176  template <class BidirectionalGraph, class GRef>
177  std::pair<typename undirected_graph<BidirectionalGraph>::edge_iterator,
178  typename undirected_graph<BidirectionalGraph>::edge_iterator>
180  {
181  return edges(g.m_g);
182  }
183 
184  template <class BidirectionalGraph, class GRef>
185  inline std::pair<typename undirected_graph<BidirectionalGraph,GRef>::out_edge_iterator,
186  typename undirected_graph<BidirectionalGraph,GRef>::out_edge_iterator>
187  out_edges(const typename BidirectionalGraph::vertex_descriptor u,
189  {
190  std::pair<typename BidirectionalGraph::out_edge_iterator,
191  typename BidirectionalGraph::out_edge_iterator>
193  std::pair<typename BidirectionalGraph::in_edge_iterator,
194  typename BidirectionalGraph::in_edge_iterator>
195  in_edges = boost::in_edges(u, g.m_g);
196 
198  return std::make_pair(
199  edge_iterator(in_edges.first, in_edges.second, out_edges.first, out_edges.first),
200  edge_iterator(in_edges.second, in_edges.second, out_edges.second, out_edges.second));
201  }
202 
203  template <class BidirectionalGraph, class GRef>
204  inline typename BidirectionalGraph::vertices_size_type
206  {
207  return num_vertices(g.m_g);
208  }
209 
210  template <class BidirectionalGraph, class GRef>
211  inline typename undirected_graph<BidirectionalGraph>::edges_size_type
213  {
214  return num_edges(g.m_g);
215  }
216 
217  template <class BidirectionalGraph, class GRef>
218  inline typename BidirectionalGraph::degree_size_type
219  out_degree(const typename BidirectionalGraph::vertex_descriptor u,
221  {
222  return in_degree(u, g.m_g) + out_degree(u, g.m_g);
223  }
224 
225  template <class BidirectionalGraph, class GRef>
226  inline std::pair<typename BidirectionalGraph::edge_descriptor, bool>
227  edge(const typename BidirectionalGraph::vertex_descriptor u,
228  const typename BidirectionalGraph::vertex_descriptor v,
230  {
231  return edge(v, u, g.m_g);
232  }
233 
234  template <class BidirectionalGraph, class GRef>
235  inline std::pair<typename BidirectionalGraph::out_edge_iterator,
236  typename BidirectionalGraph::out_edge_iterator>
237  in_edges(const typename BidirectionalGraph::vertex_descriptor u,
239  { return out_edges(u, g); }
240 
241  template <class BidirectionalGraph, class GRef>
242  inline std::pair<typename undirected_graph<BidirectionalGraph,GRef>::adjacency_iterator,
243  typename undirected_graph<BidirectionalGraph,GRef>::adjacency_iterator>
244  adjacent_vertices(const typename BidirectionalGraph::vertex_descriptor u,
246  {
247  std::pair<typename BidirectionalGraph::adjacency_iterator,
248  typename BidirectionalGraph::adjacency_iterator>
249  adjacency = boost::adjacent_vertices(u, g.m_g);
250  std::pair<typename BidirectionalGraph::inv_adjacency_iterator,
251  typename BidirectionalGraph::inv_adjacency_iterator>
252  inv_adjacency = boost::inv_adjacent_vertices(u, g.m_g);
253 
254  typedef typename undirected_graph<BidirectionalGraph,GRef>::adjacency_iterator adjacency_iterator;
255  return std::make_pair(
256  adjacency_iterator(adjacency.first, adjacency.second, inv_adjacency.first, inv_adjacency.first),
257  adjacency_iterator(adjacency.second, adjacency.second, inv_adjacency.second, inv_adjacency.second));
258  }
259 
260  template <class BidirectionalGraph, class GRef>
261  inline typename BidirectionalGraph::degree_size_type
262  in_degree(const typename BidirectionalGraph::vertex_descriptor u,
264  { return out_degree(u, g); }
265 
266  template <class Edge, class BidirectionalGraph, class GRef>
267  inline typename boost::graph_traits<BidirectionalGraph>::vertex_descriptor
269  {
270  if (e.second)
271  return target(e.first, g.m_g);
272  else
273  return source(e.first, g.m_g);
274  }
275 
276  template <class Edge, class BidirectionalGraph, class GRef>
277  inline typename boost::graph_traits<BidirectionalGraph>::vertex_descriptor
279  {
280  if (e.second)
281  return source(e.first, g.m_g);
282  else
283  return target(e.first, g.m_g);
284  }
285 
286 
287  namespace detail {
288 
290  template <class UndirectedGraph, class Property, class Tag>
291  struct bind_ {
292  typedef typename UndirectedGraph::base_type Graph;
293  typedef boost::property_map<Graph, Tag> PMap;
294  typedef typename PMap::type type;
295  typedef typename PMap::const_type const_type;
296  };
297  };
298 
300  template <class UndirectedGraph, class Property, class Tag>
301  struct bind_ {
302  typedef typename UndirectedGraph::base_type Graph;
303  typedef boost::property_map<Graph, Tag> PMap;
304  typedef typename PMap::type type;
305  typedef typename PMap::const_type const_type;
306  };
307  };
308 
309  } // namespace detail
310 
313  template<typename PropertyMap>
315  {
316  public:
317  undirected_property_map(PropertyMap pmap)
318  : m_map(pmap) {}
319 
320  PropertyMap& map() { return m_map; }
321  PropertyMap const& map() const { return m_map; }
322 
323  private:
324  PropertyMap m_map;
325  };
326 
327  template<typename PropertyMap, typename EdgeDescriptor, typename ValueType>
329  EdgeDescriptor e, ValueType value)
330  { put(map.map(), e.first, value); }
331  template<typename PropertyMap, typename EdgeDescriptor>
332  typename boost::property_traits<PropertyMap>::value_type
334  EdgeDescriptor e)
335  { return get(map.map(), e.first); }
336 
337  template<typename PropertyMap>
339  { return undirected_property_map<PropertyMap>(pmap); }
340 
341 
342 } // namespace utilmm
343 
344 // Include specialization in the boost namespace
345 namespace boost {
346  template<typename PropertyMap>
347  struct property_traits< utilmm::undirected_property_map<PropertyMap> >
348  : property_traits<PropertyMap> {};
349 
350  template <>
351  struct vertex_property_selector<utilmm::undirected_graph_tag> {
353  };
354 
355  template <>
356  struct edge_property_selector<utilmm::undirected_graph_tag> {
358  };
359 
360  namespace detail {
361  template<typename BidirGraph, typename GRef, typename Property>
363  template<typename BidirGraph, typename Property>
364  struct get_property_map_type<BidirGraph, const BidirGraph&, Property>
365  { typedef typename property_map<BidirGraph, Property>::const_type type; };
366  template<typename BidirGraph, typename Property>
367  struct get_property_map_type<BidirGraph, BidirGraph&, Property>
368  { typedef typename property_map<BidirGraph, Property>::type type; };
369  }
370 
371  template <class BidirGraph, class GRef, class Property>
374  {
375  return get(p, g.m_g);
376  }
377 
378  template <class BidirGraph, class GRef, class Property>
379  typename detail::get_property_map_type<BidirGraph, GRef, Property>::type
381  {
382  return get(p, g.m_g);
383  }
384 
385  template <class BidirectionalGraph, class GRef, class Property, class Key>
386  typename property_traits<
387  typename property_map<BidirectionalGraph, Property>::const_type
388  >::value_type
389  get(Property p, const utilmm::undirected_graph<BidirectionalGraph,GRef>& g, const Key& k)
390  {
391  return get(p, g.m_g, k);
392  }
393 
394  template <class BidirectionalGraph, class GRef, class Property, class Key, class Value>
395  void
396  put(Property p, const utilmm::undirected_graph<BidirectionalGraph,GRef>& g, const Key& k,
397  const Value& val)
398  {
399  put(p, g.m_g, k, val);
400  }
401 
402  template<typename BidirectionalGraph, typename GRef, typename Tag,
403  typename Value>
404  inline void
406  const Value& value)
407  {
408  set_property(g.m_g, tag, value);
409  }
410 
411  template<typename BidirectionalGraph, typename GRef, typename Tag>
412  inline
413  typename graph_property<BidirectionalGraph, Tag>::type
415  {
416  return get_property(g.m_g, tag);
417  }
418 
419 } // namespace boost
420 
421 #endif
adjacency_iterator inv_adjacency_iterator
Definition: undirected_graph.hh:105
void put(Property p, const utilmm::undirected_graph< BidirectionalGraph, GRef > &g, const Key &k, const Value &val)
Definition: undirected_graph.hh:396
property_map< BidirGraph, Property >::type type
Definition: undirected_graph.hh:368
PMap::const_type const_type
Definition: undirected_graph.hh:295
boost::graph_traits< BidirectionalGraph >::vertex_descriptor source(const Edge &e, const undirected_graph< BidirectionalGraph, GRef > &g)
Definition: undirected_graph.hh:268
std::pair< typename undirected_graph< BidirectionalGraph >::vertex_iterator, typename undirected_graph< BidirectionalGraph >::vertex_iterator > vertices(const undirected_graph< BidirectionalGraph, GRef > &g)
Definition: undirected_graph.hh:171
static edge_descriptor make_out_edge_descriptor(typename Traits::edge_descriptor e)
Definition: undirected_graph.hh:52
PropertyMap & map()
Definition: undirected_graph.hh:320
undirected_graph(GraphRef g)
Definition: undirected_graph.hh:38
base_in_edge_iterator(typename Traits::in_edge_iterator e)
Definition: undirected_graph.hh:76
undirected_property_map(PropertyMap pmap)
Definition: undirected_graph.hh:317
undirected_property_map< PropertyMap > make_undirected_edge_map(PropertyMap pmap)
Definition: undirected_graph.hh:338
std::pair< typename undirected_graph< BidirectionalGraph, GRef >::adjacency_iterator, typename undirected_graph< BidirectionalGraph, GRef >::adjacency_iterator > adjacent_vertices(const typename BidirectionalGraph::vertex_descriptor u, const undirected_graph< BidirectionalGraph, GRef > &g)
Definition: undirected_graph.hh:244
boost::graph::detail::bundled_result< BidirectionalGraph, vertex_descriptor >::type & operator[](vertex_descriptor x)
Definition: undirected_graph.hh:140
static vertex_descriptor null_vertex()
Definition: undirected_graph.hh:122
std::pair< typename Traits::edge_descriptor, bool > edge_descriptor
Definition: undirected_graph.hh:48
base_out_edge_iterator(typename Traits::out_edge_iterator e)
Definition: undirected_graph.hh:62
Traits::edge_iterator traits_edge_iterator
Definition: undirected_graph.hh:111
iterator_sequence< base_in_edge_iterator, base_out_edge_iterator > in_edge_iterator
Definition: undirected_graph.hh:97
GraphRef m_g
Definition: undirected_graph.hh:151
std::pair< typename BidirectionalGraph::edge_descriptor, bool > edge(const typename BidirectionalGraph::vertex_descriptor u, const typename BidirectionalGraph::vertex_descriptor v, const undirected_graph< BidirectionalGraph, GRef > &g)
Definition: undirected_graph.hh:227
std::pair< typename BidirectionalGraph::out_edge_iterator, typename BidirectionalGraph::out_edge_iterator > in_edges(const typename BidirectionalGraph::vertex_descriptor u, const undirected_graph< BidirectionalGraph, GRef > &g)
Definition: undirected_graph.hh:237
PMap::type type
Definition: undirected_graph.hh:294
utilmm::detail::undirected_graph_edge_property_selector type
Definition: undirected_graph.hh:357
boost::undirected_tag directed_category
Definition: undirected_graph.hh:42
base_out_edge_iterator()
Definition: undirected_graph.hh:61
property_map< BidirGraph, Property >::const_type type
Definition: undirected_graph.hh:365
UndirectedGraph::base_type Graph
Definition: undirected_graph.hh:302
boost::graph::detail::bundled_result< BidirectionalGraph, vertex_descriptor >::type const & operator[](vertex_descriptor x) const
Definition: undirected_graph.hh:145
Definition: undirected_graph.hh:28
PropertyMap const & map() const
Definition: undirected_graph.hh:321
BidirectionalGraph::degree_size_type in_degree(const typename BidirectionalGraph::vertex_descriptor u, const undirected_graph< BidirectionalGraph, GRef > &g)
Definition: undirected_graph.hh:262
Definition: undirected_graph.hh:54
Traits::edge_parallel_category edge_parallel_category
Definition: undirected_graph.hh:43
static edge_descriptor make_in_edge_descriptor(typename Traits::edge_descriptor e)
Definition: undirected_graph.hh:66
Traits::traversal_category traversal_category
Definition: undirected_graph.hh:44
Traits::vertex_iterator vertex_iterator
Definition: undirected_graph.hh:108
utilmm::detail::undirected_graph_vertex_property_selector type
Definition: undirected_graph.hh:352
undirected_graph_tag graph_tag
Definition: undirected_graph.hh:120
edge_descriptor(* make_undirected_edge_descriptor)(typename Traits::edge_descriptor)
Definition: undirected_graph.hh:49
boost::property_map< Graph, Tag > PMap
Definition: undirected_graph.hh:303
Traits::vertex_descriptor vertex_descriptor
Definition: undirected_graph.hh:41
edge_iterator()
Definition: undirected_graph.hh:87
Definition: undirected_graph.hh:68
boost::graph::detail::bundled_result< BidirectionalGraph, edge_descriptor >::type & operator[](edge_descriptor x)
Definition: undirected_graph.hh:128
Traits::degree_size_type degree_size_type
Definition: undirected_graph.hh:93
base_in_edge_iterator()
Definition: undirected_graph.hh:75
BidirectionalGraph::vertices_size_type num_vertices(const undirected_graph< BidirectionalGraph, GRef > &g)
Definition: undirected_graph.hh:205
Definition: undirected_graph.hh:81
undirected_graph< BidirectionalGraph >::edges_size_type num_edges(const undirected_graph< BidirectionalGraph, GRef > &g)
Definition: undirected_graph.hh:212
iterator_sequence< typename Traits::adjacency_iterator, typename BidirectionalGraph::inv_adjacency_iterator > adjacency_iterator
Definition: undirected_graph.hh:104
edge_iterator(typename Traits::edge_iterator e)
Definition: undirected_graph.hh:88
BidirectionalGraph::edge_property_type edge_property_type
Definition: undirected_graph.hh:117
BidirectionalGraph::vertex_property_type vertex_property_type
Definition: undirected_graph.hh:119
boost::property_map< Graph, Tag > PMap
Definition: undirected_graph.hh:293
void put(undirected_property_map< PropertyMap > &map, EdgeDescriptor e, ValueType value)
Definition: undirected_graph.hh:328
boost::graph::detail::bundled_result< BidirectionalGraph, edge_descriptor >::type const & operator[](edge_descriptor x) const
Definition: undirected_graph.hh:133
void set_property(const utilmm::undirected_graph< BidirectionalGraph, GRef > &g, Tag tag, const Value &value)
Definition: undirected_graph.hh:405
PMap::type type
Definition: undirected_graph.hh:304
in_edge_iterator out_edge_iterator
Definition: undirected_graph.hh:98
PMap::const_type const_type
Definition: undirected_graph.hh:305
graph_property< BidirectionalGraph, Tag >::type get_property(const utilmm::undirected_graph< BidirectionalGraph, GRef > &g, Tag tag)
Definition: undirected_graph.hh:414
Traits::edges_size_type edges_size_type
Definition: undirected_graph.hh:113
Definition: undirected_graph.hh:314
BidirectionalGraph base_type
Definition: undirected_graph.hh:35
std::pair< typename undirected_graph< BidirectionalGraph >::edge_iterator, typename undirected_graph< BidirectionalGraph >::edge_iterator > edges(const undirected_graph< BidirectionalGraph, GRef > &g)
Definition: undirected_graph.hh:179
std::pair< typename undirected_graph< BidirectionalGraph, GRef >::out_edge_iterator, typename undirected_graph< BidirectionalGraph, GRef >::out_edge_iterator > out_edges(const typename BidirectionalGraph::vertex_descriptor u, const undirected_graph< BidirectionalGraph, GRef > &g)
Definition: undirected_graph.hh:187
BidirectionalGraph::degree_size_type out_degree(const typename BidirectionalGraph::vertex_descriptor u, const undirected_graph< BidirectionalGraph, GRef > &g)
Definition: undirected_graph.hh:219
undirected_graph< BidirectionalGraph > make_undirected_graph(const BidirectionalGraph &g)
Definition: undirected_graph.hh:156
UndirectedGraph::base_type Graph
Definition: undirected_graph.hh:292
boost::graph_traits< BidirectionalGraph >::vertex_descriptor target(const Edge &e, const undirected_graph< BidirectionalGraph, GRef > &g)
Definition: undirected_graph.hh:278
Definition: undirected_graph.hh:22
Definition: undirected_graph.hh:362
Traits::vertices_size_type vertices_size_type
Definition: undirected_graph.hh:112
Definition: iterator_sequence.hh:14

Generated on Tue Oct 9 2018 10:12:45 for Util-- by doxygen 1.8.6
SourceForge.net Project Page