• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // (C) Copyright 2007-2009 Andrew Sutton
2 //
3 // Use, modification and distribution are subject to the
4 // Boost Software License, Version 1.0 (See accompanying file
5 // LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
6 
7 #ifndef BOOST_GRAPH_UNDIRECTED_GRAPH_HPP
8 #define BOOST_GRAPH_UNDIRECTED_GRAPH_HPP
9 
10 #include <boost/graph/adjacency_list.hpp>
11 #include <boost/graph/properties.hpp>
12 #include <boost/pending/property.hpp>
13 #include <boost/property_map/transform_value_property_map.hpp>
14 #include <boost/type_traits.hpp>
15 #include <boost/mpl/if.hpp>
16 
17 namespace boost
18 {
19 struct undirected_graph_tag
20 {
21 };
22 
23 /**
24  * The undirected_graph class template is a simplified version of the BGL
25  * adjacency list. This class is provided for ease of use, but may not
26  * perform as well as custom-defined adjacency list classes. Instances of
27  * this template model the VertexIndexGraph, and EdgeIndexGraph concepts. The
28  * graph is also fully mutable, supporting both insertions and removals of
29  * vertices and edges.
30  *
31  * @note Special care must be taken when removing vertices or edges since
32  * those operations can invalidate the numbering of vertices.
33  */
34 template < typename VertexProp = no_property, typename EdgeProp = no_property,
35     typename GraphProp = no_property >
36 class undirected_graph
37 {
38 public:
39     typedef GraphProp graph_property_type;
40     typedef VertexProp vertex_property_type;
41     typedef EdgeProp edge_property_type;
42     typedef typename lookup_one_property< GraphProp, graph_bundle_t >::type
43         graph_bundled;
44     typedef typename lookup_one_property< VertexProp, vertex_bundle_t >::type
45         vertex_bundled;
46     typedef typename lookup_one_property< EdgeProp, edge_bundle_t >::type
47         edge_bundled;
48 
49 public:
50     // Embed indices into the vertex type.
51     typedef property< vertex_index_t, unsigned, vertex_property_type >
52         internal_vertex_property;
53     typedef property< edge_index_t, unsigned, edge_property_type >
54         internal_edge_property;
55 
56 public:
57     typedef adjacency_list< listS, listS, undirectedS, internal_vertex_property,
58         internal_edge_property, GraphProp, listS >
59         graph_type;
60 
61 private:
62     // storage selectors
63     typedef typename graph_type::vertex_list_selector vertex_list_selector;
64     typedef typename graph_type::edge_list_selector edge_list_selector;
65     typedef typename graph_type::out_edge_list_selector out_edge_list_selector;
66     typedef typename graph_type::directed_selector directed_selector;
67 
68 public:
69     // more commonly used graph types
70     typedef typename graph_type::stored_vertex stored_vertex;
71     typedef typename graph_type::vertices_size_type vertices_size_type;
72     typedef typename graph_type::edges_size_type edges_size_type;
73     typedef typename graph_type::degree_size_type degree_size_type;
74     typedef typename graph_type::vertex_descriptor vertex_descriptor;
75     typedef typename graph_type::edge_descriptor edge_descriptor;
76 
77     // iterator types
78     typedef typename graph_type::vertex_iterator vertex_iterator;
79     typedef typename graph_type::edge_iterator edge_iterator;
80     typedef typename graph_type::out_edge_iterator out_edge_iterator;
81     typedef typename graph_type::in_edge_iterator in_edge_iterator;
82     typedef typename graph_type::adjacency_iterator adjacency_iterator;
83 
84     // miscellaneous types
85     typedef undirected_graph_tag graph_tag;
86     typedef typename graph_type::directed_category directed_category;
87     typedef typename graph_type::edge_parallel_category edge_parallel_category;
88     typedef typename graph_type::traversal_category traversal_category;
89 
90     typedef std::size_t vertex_index_type;
91     typedef std::size_t edge_index_type;
92 
undirected_graph(GraphProp const & p=GraphProp ())93     inline undirected_graph(GraphProp const& p = GraphProp())
94     : m_graph(p)
95     , m_num_vertices(0)
96     , m_num_edges(0)
97     , m_max_vertex_index(0)
98     , m_max_edge_index(0)
99     {
100     }
101 
undirected_graph(undirected_graph const & x)102     inline undirected_graph(undirected_graph const& x)
103     : m_graph(x.m_graph)
104     , m_num_vertices(x.m_num_vertices)
105     , m_num_edges(x.m_num_edges)
106     , m_max_vertex_index(x.m_max_vertex_index)
107     , m_max_edge_index(x.m_max_edge_index)
108     {
109     }
110 
undirected_graph(vertices_size_type n,GraphProp const & p=GraphProp ())111     inline undirected_graph(
112         vertices_size_type n, GraphProp const& p = GraphProp())
113     : m_graph(n, p)
114     , m_num_vertices(n)
115     , m_num_edges(0)
116     , m_max_vertex_index(n)
117     , m_max_edge_index(0)
118     {
119         renumber_vertex_indices();
120     }
121 
122     template < typename EdgeIterator >
undirected_graph(EdgeIterator f,EdgeIterator l,vertices_size_type n,edges_size_type m=0,GraphProp const & p=GraphProp ())123     inline undirected_graph(EdgeIterator f, EdgeIterator l,
124         vertices_size_type n, edges_size_type m = 0,
125         GraphProp const& p = GraphProp())
126     : m_graph(f, l, n, m, p)
127     , m_num_vertices(n)
128     , m_num_edges(0)
129     , m_max_vertex_index(n)
130     , m_max_edge_index(0)
131     {
132         // Unfortunately, we have to renumber to ensure correct indexing.
133         renumber_indices();
134 
135         // Can't always guarantee that the number of edges is actually
136         // m if distance(f, l) != m (or is undefined).
137         m_num_edges = m_max_edge_index = boost::num_edges(m_graph);
138     }
139 
operator =(undirected_graph const & g)140     undirected_graph& operator=(undirected_graph const& g)
141     {
142         if (&g != this)
143         {
144             m_graph = g.m_graph;
145             m_num_vertices = g.m_num_vertices;
146             m_num_edges = g.m_num_edges;
147             m_max_vertex_index = g.m_max_vertex_index;
148         }
149         return *this;
150     }
151 
152     // The impl_() methods are not part of the public interface.
impl()153     graph_type& impl() { return m_graph; }
154 
impl() const155     graph_type const& impl() const { return m_graph; }
156 
157     // The following methods are not part of the public interface
num_vertices() const158     vertices_size_type num_vertices() const { return m_num_vertices; }
159 
160 private:
161     // This helper function manages the attribution of vertex indices.
make_index(vertex_descriptor v)162     vertex_descriptor make_index(vertex_descriptor v)
163     {
164         boost::put(vertex_index, m_graph, v, m_max_vertex_index);
165         m_num_vertices++;
166         m_max_vertex_index++;
167         return v;
168     }
169 
170 public:
add_vertex()171     vertex_descriptor add_vertex()
172     {
173         return make_index(boost::add_vertex(m_graph));
174     }
175 
add_vertex(vertex_property_type const & p)176     vertex_descriptor add_vertex(vertex_property_type const& p)
177     {
178         return make_index(
179             boost::add_vertex(internal_vertex_property(0u, p), m_graph));
180     }
181 
clear_vertex(vertex_descriptor v)182     void clear_vertex(vertex_descriptor v)
183     {
184         std::pair< out_edge_iterator, out_edge_iterator > p
185             = boost::out_edges(v, m_graph);
186         m_num_edges -= std::distance(p.first, p.second);
187         boost::clear_vertex(v, m_graph);
188     }
189 
remove_vertex(vertex_descriptor v)190     void remove_vertex(vertex_descriptor v)
191     {
192         boost::remove_vertex(v, m_graph);
193         --m_num_vertices;
194     }
195 
num_edges() const196     edges_size_type num_edges() const { return m_num_edges; }
197 
198 private:
199     // A helper fucntion for managing edge index attributes.
make_index(std::pair<edge_descriptor,bool> const & x)200     std::pair< edge_descriptor, bool > const& make_index(
201         std::pair< edge_descriptor, bool > const& x)
202     {
203         if (x.second)
204         {
205             boost::put(edge_index, m_graph, x.first, m_max_edge_index);
206             ++m_num_edges;
207             ++m_max_edge_index;
208         }
209         return x;
210     }
211 
212 public:
add_edge(vertex_descriptor u,vertex_descriptor v)213     std::pair< edge_descriptor, bool > add_edge(
214         vertex_descriptor u, vertex_descriptor v)
215     {
216         return make_index(boost::add_edge(u, v, m_graph));
217     }
218 
add_edge(vertex_descriptor u,vertex_descriptor v,edge_property_type const & p)219     std::pair< edge_descriptor, bool > add_edge(
220         vertex_descriptor u, vertex_descriptor v, edge_property_type const& p)
221     {
222         return make_index(
223             boost::add_edge(u, v, internal_edge_property(0u, p), m_graph));
224     }
225 
remove_edge(vertex_descriptor u,vertex_descriptor v)226     void remove_edge(vertex_descriptor u, vertex_descriptor v)
227     {
228         // find all edges, (u, v)
229         std::vector< edge_descriptor > edges;
230         out_edge_iterator i, i_end;
231         for (boost::tie(i, i_end) = boost::out_edges(u, m_graph); i != i_end;
232              ++i)
233         {
234             if (boost::target(*i, m_graph) == v)
235             {
236                 edges.push_back(*i);
237             }
238         }
239         // remove all edges, (u, v)
240         typename std::vector< edge_descriptor >::iterator j = edges.begin(),
241                                                           j_end = edges.end();
242         for (; j != j_end; ++j)
243         {
244             remove_edge(*j);
245         }
246     }
247 
remove_edge(edge_iterator i)248     void remove_edge(edge_iterator i) { remove_edge(*i); }
249 
remove_edge(edge_descriptor e)250     void remove_edge(edge_descriptor e)
251     {
252         boost::remove_edge(e, m_graph);
253         --m_num_edges;
254     }
255 
max_vertex_index() const256     vertex_index_type max_vertex_index() const { return m_max_vertex_index; }
257 
renumber_vertex_indices()258     void renumber_vertex_indices()
259     {
260         vertex_iterator i, i_end;
261         boost::tie(i, i_end) = vertices(m_graph);
262         m_max_vertex_index = renumber_vertex_indices(i, i_end, 0);
263     }
264 
remove_vertex_and_renumber_indices(vertex_iterator i)265     void remove_vertex_and_renumber_indices(vertex_iterator i)
266     {
267         vertex_iterator j = next(i), end = vertices(m_graph).second;
268         vertex_index_type n = get(vertex_index, m_graph, *i);
269 
270         // remove the offending vertex and renumber everything after
271         remove_vertex(*i);
272         m_max_vertex_index = renumber_vertex_indices(j, end, n);
273     }
274 
max_edge_index() const275     edge_index_type max_edge_index() const { return m_max_edge_index; }
276 
renumber_edge_indices()277     void renumber_edge_indices()
278     {
279         edge_iterator i, end;
280         boost::tie(i, end) = edges(m_graph);
281         m_max_edge_index = renumber_edge_indices(i, end, 0);
282     }
283 
remove_edge_and_renumber_indices(edge_iterator i)284     void remove_edge_and_renumber_indices(edge_iterator i)
285     {
286         edge_iterator j = next(i), end = edges(m_graph.second);
287         edge_index_type n = get(edge_index, m_graph, *i);
288 
289         // remove the edge and renumber everything after it
290         remove_edge(*i);
291         m_max_edge_index = renumber_edge_indices(j, end, n);
292     }
293 
renumber_indices()294     void renumber_indices()
295     {
296         renumber_vertex_indices();
297         renumber_edge_indices();
298     }
299 
300     // bundled property support
301 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
operator [](vertex_descriptor v)302     vertex_bundled& operator[](vertex_descriptor v) { return m_graph[v]; }
303 
operator [](vertex_descriptor v) const304     vertex_bundled const& operator[](vertex_descriptor v) const
305     {
306         return m_graph[v];
307     }
308 
operator [](edge_descriptor e)309     edge_bundled& operator[](edge_descriptor e) { return m_graph[e]; }
310 
operator [](edge_descriptor e) const311     edge_bundled const& operator[](edge_descriptor e) const
312     {
313         return m_graph[e];
314     }
315 
operator [](graph_bundle_t)316     graph_bundled& operator[](graph_bundle_t) { return get_property(*this); }
317 
operator [](graph_bundle_t) const318     graph_bundled const& operator[](graph_bundle_t) const
319     {
320         return get_property(*this);
321     }
322 #endif
323 
324     // Graph concepts
null_vertex()325     static vertex_descriptor null_vertex() { return graph_type::null_vertex(); }
326 
clear()327     void clear()
328     {
329         m_graph.clear();
330         m_num_vertices = m_max_vertex_index = 0;
331         m_num_edges = m_max_edge_index = 0;
332     }
333 
swap(undirected_graph & g)334     void swap(undirected_graph& g)
335     {
336         m_graph.swap(g.m_graph);
337         std::swap(m_num_vertices, g.m_num_vertices);
338         std::swap(m_max_vertex_index, g.m_max_vertex_index);
339         std::swap(m_num_edges, g.m_num_edges);
340         std::swap(m_max_edge_index, g.m_max_edge_index);
341     }
342 
343 private:
renumber_vertex_indices(vertex_iterator i,vertex_iterator end,vertices_size_type n)344     vertices_size_type renumber_vertex_indices(
345         vertex_iterator i, vertex_iterator end, vertices_size_type n)
346     {
347         typedef
348             typename property_map< graph_type, vertex_index_t >::type IndexMap;
349         IndexMap indices = get(vertex_index, m_graph);
350         for (; i != end; ++i)
351         {
352             indices[*i] = n++;
353         }
354         return n;
355     }
356 
renumber_edge_indices(edge_iterator i,edge_iterator end,edges_size_type n)357     edges_size_type renumber_edge_indices(
358         edge_iterator i, edge_iterator end, edges_size_type n)
359     {
360         typedef
361             typename property_map< graph_type, edge_index_t >::type IndexMap;
362         IndexMap indices = get(edge_index, m_graph);
363         for (; i != end; ++i)
364         {
365             indices[*i] = n++;
366         }
367         return n;
368     }
369 
370     graph_type m_graph;
371     vertices_size_type m_num_vertices;
372     edges_size_type m_num_edges;
373     vertex_index_type m_max_vertex_index;
374     edge_index_type m_max_edge_index;
375 };
376 
377 #define UNDIRECTED_GRAPH_PARAMS typename VP, typename EP, typename GP
378 #define UNDIRECTED_GRAPH undirected_graph< VP, EP, GP >
379 
380 // IncidenceGraph concepts
381 template < UNDIRECTED_GRAPH_PARAMS >
source(typename UNDIRECTED_GRAPH::edge_descriptor e,UNDIRECTED_GRAPH const & g)382 inline typename UNDIRECTED_GRAPH::vertex_descriptor source(
383     typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH const& g)
384 {
385     return source(e, g.impl());
386 }
387 
388 template < UNDIRECTED_GRAPH_PARAMS >
target(typename UNDIRECTED_GRAPH::edge_descriptor e,UNDIRECTED_GRAPH const & g)389 inline typename UNDIRECTED_GRAPH::vertex_descriptor target(
390     typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH const& g)
391 {
392     return target(e, g.impl());
393 }
394 
395 template < UNDIRECTED_GRAPH_PARAMS >
out_degree(typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH const & g)396 inline typename UNDIRECTED_GRAPH::degree_size_type out_degree(
397     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
398 {
399     return out_degree(v, g.impl());
400 }
401 
402 template < UNDIRECTED_GRAPH_PARAMS >
403 inline std::pair< typename UNDIRECTED_GRAPH::out_edge_iterator,
404     typename UNDIRECTED_GRAPH::out_edge_iterator >
out_edges(typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH const & g)405 out_edges(
406     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
407 {
408     return out_edges(v, g.impl());
409 }
410 
411 // BidirectionalGraph concepts
412 template < UNDIRECTED_GRAPH_PARAMS >
in_degree(typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH const & g)413 inline typename UNDIRECTED_GRAPH::degree_size_type in_degree(
414     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
415 {
416     return in_degree(v, g.impl());
417 }
418 
419 template < UNDIRECTED_GRAPH_PARAMS >
420 inline std::pair< typename UNDIRECTED_GRAPH::in_edge_iterator,
421     typename UNDIRECTED_GRAPH::in_edge_iterator >
in_edges(typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH const & g)422 in_edges(
423     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
424 {
425     return in_edges(v, g.impl());
426 }
427 
428 template < UNDIRECTED_GRAPH_PARAMS >
429 inline std::pair< typename UNDIRECTED_GRAPH::out_edge_iterator,
430     typename UNDIRECTED_GRAPH::out_edge_iterator >
incident_edges(typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH const & g)431 incident_edges(
432     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
433 {
434     return out_edges(v, g.impl());
435 }
436 
437 template < UNDIRECTED_GRAPH_PARAMS >
degree(typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH const & g)438 inline typename UNDIRECTED_GRAPH::degree_size_type degree(
439     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
440 {
441     return degree(v, g.impl());
442 }
443 
444 // AdjacencyGraph concepts
445 template < UNDIRECTED_GRAPH_PARAMS >
446 inline std::pair< typename UNDIRECTED_GRAPH::adjacency_iterator,
447     typename UNDIRECTED_GRAPH::adjacency_iterator >
adjacent_vertices(typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH const & g)448 adjacent_vertices(
449     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
450 {
451     return adjacent_vertices(v, g.impl());
452 }
453 
454 template < UNDIRECTED_GRAPH_PARAMS >
vertex(typename UNDIRECTED_GRAPH::vertices_size_type n,UNDIRECTED_GRAPH const & g)455 typename UNDIRECTED_GRAPH::vertex_descriptor vertex(
456     typename UNDIRECTED_GRAPH::vertices_size_type n, UNDIRECTED_GRAPH const& g)
457 {
458     return vertex(n, g.impl());
459 }
460 
461 template < UNDIRECTED_GRAPH_PARAMS >
edge(typename UNDIRECTED_GRAPH::vertex_descriptor u,typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH const & g)462 std::pair< typename UNDIRECTED_GRAPH::edge_descriptor, bool > edge(
463     typename UNDIRECTED_GRAPH::vertex_descriptor u,
464     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
465 {
466     return edge(u, v, g.impl());
467 }
468 
469 // VertexListGraph concepts
470 template < UNDIRECTED_GRAPH_PARAMS >
num_vertices(UNDIRECTED_GRAPH const & g)471 inline typename UNDIRECTED_GRAPH::vertices_size_type num_vertices(
472     UNDIRECTED_GRAPH const& g)
473 {
474     return g.num_vertices();
475 }
476 
477 template < UNDIRECTED_GRAPH_PARAMS >
478 inline std::pair< typename UNDIRECTED_GRAPH::vertex_iterator,
479     typename UNDIRECTED_GRAPH::vertex_iterator >
vertices(UNDIRECTED_GRAPH const & g)480 vertices(UNDIRECTED_GRAPH const& g)
481 {
482     return vertices(g.impl());
483 }
484 
485 // EdgeListGraph concepts
486 template < UNDIRECTED_GRAPH_PARAMS >
num_edges(UNDIRECTED_GRAPH const & g)487 inline typename UNDIRECTED_GRAPH::edges_size_type num_edges(
488     UNDIRECTED_GRAPH const& g)
489 {
490     return g.num_edges();
491 }
492 
493 template < UNDIRECTED_GRAPH_PARAMS >
494 inline std::pair< typename UNDIRECTED_GRAPH::edge_iterator,
495     typename UNDIRECTED_GRAPH::edge_iterator >
edges(UNDIRECTED_GRAPH const & g)496 edges(UNDIRECTED_GRAPH const& g)
497 {
498     return edges(g.impl());
499 }
500 
501 // MutableGraph concepts
502 template < UNDIRECTED_GRAPH_PARAMS >
add_vertex(UNDIRECTED_GRAPH & g)503 inline typename UNDIRECTED_GRAPH::vertex_descriptor add_vertex(
504     UNDIRECTED_GRAPH& g)
505 {
506     return g.add_vertex();
507 }
508 
509 template < UNDIRECTED_GRAPH_PARAMS >
add_vertex(typename UNDIRECTED_GRAPH::vertex_property_type const & p,UNDIRECTED_GRAPH & g)510 inline typename UNDIRECTED_GRAPH::vertex_descriptor add_vertex(
511     typename UNDIRECTED_GRAPH::vertex_property_type const& p,
512     UNDIRECTED_GRAPH& g)
513 {
514     return g.add_vertex(p);
515 }
516 
517 template < UNDIRECTED_GRAPH_PARAMS >
clear_vertex(typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH & g)518 inline void clear_vertex(
519     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
520 {
521     return g.clear_vertex(v);
522 }
523 
524 template < UNDIRECTED_GRAPH_PARAMS >
remove_vertex(typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH & g)525 inline void remove_vertex(
526     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
527 {
528     return g.remove_vertex(v);
529 }
530 
531 template < UNDIRECTED_GRAPH_PARAMS >
add_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u,typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH & g)532 inline std::pair< typename UNDIRECTED_GRAPH::edge_descriptor, bool > add_edge(
533     typename UNDIRECTED_GRAPH::vertex_descriptor u,
534     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
535 {
536     return g.add_edge(u, v);
537 }
538 
539 template < UNDIRECTED_GRAPH_PARAMS >
add_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u,typename UNDIRECTED_GRAPH::vertex_descriptor v,typename UNDIRECTED_GRAPH::edge_property_type const & p,UNDIRECTED_GRAPH & g)540 inline std::pair< typename UNDIRECTED_GRAPH::edge_descriptor, bool > add_edge(
541     typename UNDIRECTED_GRAPH::vertex_descriptor u,
542     typename UNDIRECTED_GRAPH::vertex_descriptor v,
543     typename UNDIRECTED_GRAPH::edge_property_type const& p, UNDIRECTED_GRAPH& g)
544 {
545     return g.add_edge(u, v, p);
546 }
547 
548 template < UNDIRECTED_GRAPH_PARAMS >
remove_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u,typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH & g)549 inline void remove_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u,
550     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
551 {
552     return g.remove_edge(u, v);
553 }
554 
555 template < UNDIRECTED_GRAPH_PARAMS >
remove_edge(typename UNDIRECTED_GRAPH::edge_descriptor e,UNDIRECTED_GRAPH & g)556 inline void remove_edge(
557     typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH& g)
558 {
559     return g.remove_edge(e);
560 }
561 
562 template < UNDIRECTED_GRAPH_PARAMS >
remove_edge(typename UNDIRECTED_GRAPH::edge_iterator i,UNDIRECTED_GRAPH & g)563 inline void remove_edge(
564     typename UNDIRECTED_GRAPH::edge_iterator i, UNDIRECTED_GRAPH& g)
565 {
566     return g.remove_edge(i);
567 }
568 
569 template < UNDIRECTED_GRAPH_PARAMS, class Predicate >
remove_edge_if(Predicate pred,UNDIRECTED_GRAPH & g)570 inline void remove_edge_if(Predicate pred, UNDIRECTED_GRAPH& g)
571 {
572     return remove_edge_if(pred, g.impl());
573 }
574 
575 template < UNDIRECTED_GRAPH_PARAMS, class Predicate >
remove_incident_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v,Predicate pred,UNDIRECTED_GRAPH & g)576 inline void remove_incident_edge_if(
577     typename UNDIRECTED_GRAPH::vertex_descriptor v, Predicate pred,
578     UNDIRECTED_GRAPH& g)
579 {
580     return remove_out_edge_if(v, pred, g.impl());
581 }
582 
583 template < UNDIRECTED_GRAPH_PARAMS, class Predicate >
remove_out_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v,Predicate pred,UNDIRECTED_GRAPH & g)584 inline void remove_out_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v,
585     Predicate pred, UNDIRECTED_GRAPH& g)
586 {
587     return remove_out_edge_if(v, pred, g.impl());
588 }
589 
590 template < UNDIRECTED_GRAPH_PARAMS, class Predicate >
remove_in_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v,Predicate pred,UNDIRECTED_GRAPH & g)591 inline void remove_in_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v,
592     Predicate pred, UNDIRECTED_GRAPH& g)
593 {
594     return remove_in_edge_if(v, pred, g.impl());
595 }
596 
597 template < UNDIRECTED_GRAPH_PARAMS, typename Property >
598 struct property_map< UNDIRECTED_GRAPH, Property >
599 : property_map< typename UNDIRECTED_GRAPH::graph_type, Property >
600 {
601 };
602 
603 template < UNDIRECTED_GRAPH_PARAMS >
604 struct property_map< UNDIRECTED_GRAPH, vertex_all_t >
605 {
606     typedef transform_value_property_map< detail::remove_first_property,
607         typename property_map< typename UNDIRECTED_GRAPH::graph_type,
608             vertex_all_t >::const_type >
609         const_type;
610     typedef transform_value_property_map< detail::remove_first_property,
611         typename property_map< typename UNDIRECTED_GRAPH::graph_type,
612             vertex_all_t >::type >
613         type;
614 };
615 
616 template < UNDIRECTED_GRAPH_PARAMS >
617 struct property_map< UNDIRECTED_GRAPH, edge_all_t >
618 {
619     typedef transform_value_property_map< detail::remove_first_property,
620         typename property_map< typename UNDIRECTED_GRAPH::graph_type,
621             edge_all_t >::const_type >
622         const_type;
623     typedef transform_value_property_map< detail::remove_first_property,
624         typename property_map< typename UNDIRECTED_GRAPH::graph_type,
625             edge_all_t >::type >
626         type;
627 };
628 
629 // PropertyGraph concepts
630 template < UNDIRECTED_GRAPH_PARAMS, typename Property >
get(Property p,UNDIRECTED_GRAPH & g)631 inline typename property_map< UNDIRECTED_GRAPH, Property >::type get(
632     Property p, UNDIRECTED_GRAPH& g)
633 {
634     return get(p, g.impl());
635 }
636 
637 template < UNDIRECTED_GRAPH_PARAMS, typename Property >
get(Property p,UNDIRECTED_GRAPH const & g)638 inline typename property_map< UNDIRECTED_GRAPH, Property >::const_type get(
639     Property p, UNDIRECTED_GRAPH const& g)
640 {
641     return get(p, g.impl());
642 }
643 
644 template < UNDIRECTED_GRAPH_PARAMS >
get(vertex_all_t,UNDIRECTED_GRAPH & g)645 inline typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::type get(
646     vertex_all_t, UNDIRECTED_GRAPH& g)
647 {
648     return typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::type(
649         detail::remove_first_property(), get(vertex_all, g.impl()));
650 }
651 
652 template < UNDIRECTED_GRAPH_PARAMS >
get(vertex_all_t,UNDIRECTED_GRAPH const & g)653 inline typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::const_type get(
654     vertex_all_t, UNDIRECTED_GRAPH const& g)
655 {
656     return typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::const_type(
657         detail::remove_first_property(), get(vertex_all, g.impl()));
658 }
659 
660 template < UNDIRECTED_GRAPH_PARAMS >
get(edge_all_t,UNDIRECTED_GRAPH & g)661 inline typename property_map< UNDIRECTED_GRAPH, edge_all_t >::type get(
662     edge_all_t, UNDIRECTED_GRAPH& g)
663 {
664     return typename property_map< UNDIRECTED_GRAPH, edge_all_t >::type(
665         detail::remove_first_property(), get(edge_all, g.impl()));
666 }
667 
668 template < UNDIRECTED_GRAPH_PARAMS >
get(edge_all_t,UNDIRECTED_GRAPH const & g)669 inline typename property_map< UNDIRECTED_GRAPH, edge_all_t >::const_type get(
670     edge_all_t, UNDIRECTED_GRAPH const& g)
671 {
672     return typename property_map< UNDIRECTED_GRAPH, edge_all_t >::const_type(
673         detail::remove_first_property(), get(edge_all, g.impl()));
674 }
675 
676 template < UNDIRECTED_GRAPH_PARAMS, typename Property, typename Key >
677 inline typename property_traits< typename property_map<
678     typename UNDIRECTED_GRAPH::graph_type, Property >::const_type >::value_type
get(Property p,UNDIRECTED_GRAPH const & g,Key const & k)679 get(Property p, UNDIRECTED_GRAPH const& g, Key const& k)
680 {
681     return get(p, g.impl(), k);
682 }
683 
684 template < UNDIRECTED_GRAPH_PARAMS, typename Key >
685 inline typename property_traits<
686     typename property_map< typename UNDIRECTED_GRAPH::graph_type,
687         vertex_all_t >::const_type >::value_type
get(vertex_all_t,UNDIRECTED_GRAPH const & g,Key const & k)688 get(vertex_all_t, UNDIRECTED_GRAPH const& g, Key const& k)
689 {
690     return get(vertex_all, g.impl(), k).m_base;
691 }
692 
693 template < UNDIRECTED_GRAPH_PARAMS, typename Key >
694 inline typename property_traits<
695     typename property_map< typename UNDIRECTED_GRAPH::graph_type,
696         edge_all_t >::const_type >::value_type
get(edge_all_t,UNDIRECTED_GRAPH const & g,Key const & k)697 get(edge_all_t, UNDIRECTED_GRAPH const& g, Key const& k)
698 {
699     return get(edge_all, g.impl(), k).m_base;
700 }
701 
702 template < UNDIRECTED_GRAPH_PARAMS, typename Property, typename Key,
703     typename Value >
put(Property p,UNDIRECTED_GRAPH & g,Key const & k,Value const & v)704 inline void put(Property p, UNDIRECTED_GRAPH& g, Key const& k, Value const& v)
705 {
706     put(p, g.impl(), k, v);
707 }
708 
709 template < UNDIRECTED_GRAPH_PARAMS, typename Key, typename Value >
put(vertex_all_t,UNDIRECTED_GRAPH & g,Key const & k,Value const & v)710 inline void put(vertex_all_t, UNDIRECTED_GRAPH& g, Key const& k, Value const& v)
711 {
712     put(vertex_all, g.impl(), k,
713         typename UNDIRECTED_GRAPH::internal_vertex_property(
714             get(vertex_index, g.impl(), k), v));
715 }
716 
717 template < UNDIRECTED_GRAPH_PARAMS, typename Key, typename Value >
put(edge_all_t,UNDIRECTED_GRAPH & g,Key const & k,Value const & v)718 inline void put(edge_all_t, UNDIRECTED_GRAPH& g, Key const& k, Value const& v)
719 {
720     put(edge_all, g.impl(), k,
721         typename UNDIRECTED_GRAPH::internal_vertex_property(
722             get(edge_index, g.impl(), k), v));
723 }
724 
725 template < UNDIRECTED_GRAPH_PARAMS, class Property >
726 inline typename graph_property< UNDIRECTED_GRAPH, Property >::type&
get_property(UNDIRECTED_GRAPH & g,Property p)727 get_property(UNDIRECTED_GRAPH& g, Property p)
728 {
729     return get_property(g.impl(), p);
730 }
731 
732 template < UNDIRECTED_GRAPH_PARAMS, class Property >
733 inline typename graph_property< UNDIRECTED_GRAPH, Property >::type const&
get_property(UNDIRECTED_GRAPH const & g,Property p)734 get_property(UNDIRECTED_GRAPH const& g, Property p)
735 {
736     return get_property(g.impl(), p);
737 }
738 
739 template < UNDIRECTED_GRAPH_PARAMS, class Property, class Value >
set_property(UNDIRECTED_GRAPH & g,Property p,Value v)740 inline void set_property(UNDIRECTED_GRAPH& g, Property p, Value v)
741 {
742     return set_property(g.impl(), p, v);
743 }
744 
745 // Indexed Vertex graph
746 
747 template < UNDIRECTED_GRAPH_PARAMS >
get_vertex_index(typename UNDIRECTED_GRAPH::vertex_descriptor v,UNDIRECTED_GRAPH const & g)748 inline typename UNDIRECTED_GRAPH::vertex_index_type get_vertex_index(
749     typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
750 {
751     return get(vertex_index, g, v);
752 }
753 
754 template < UNDIRECTED_GRAPH_PARAMS >
max_vertex_index(UNDIRECTED_GRAPH const & g)755 typename UNDIRECTED_GRAPH::vertex_index_type max_vertex_index(
756     UNDIRECTED_GRAPH const& g)
757 {
758     return g.max_vertex_index();
759 }
760 
761 template < UNDIRECTED_GRAPH_PARAMS >
renumber_vertex_indices(UNDIRECTED_GRAPH & g)762 inline void renumber_vertex_indices(UNDIRECTED_GRAPH& g)
763 {
764     g.renumber_vertex_indices();
765 }
766 
767 template < UNDIRECTED_GRAPH_PARAMS >
remove_vertex_and_renumber_indices(typename UNDIRECTED_GRAPH::vertex_iterator i,UNDIRECTED_GRAPH & g)768 inline void remove_vertex_and_renumber_indices(
769     typename UNDIRECTED_GRAPH::vertex_iterator i, UNDIRECTED_GRAPH& g)
770 {
771     g.remove_vertex_and_renumber_indices(i);
772 }
773 
774 // Edge index management
775 
776 template < UNDIRECTED_GRAPH_PARAMS >
get_edge_index(typename UNDIRECTED_GRAPH::edge_descriptor v,UNDIRECTED_GRAPH const & g)777 inline typename UNDIRECTED_GRAPH::edge_index_type get_edge_index(
778     typename UNDIRECTED_GRAPH::edge_descriptor v, UNDIRECTED_GRAPH const& g)
779 {
780     return get(edge_index, g, v);
781 }
782 
783 template < UNDIRECTED_GRAPH_PARAMS >
max_edge_index(UNDIRECTED_GRAPH const & g)784 typename UNDIRECTED_GRAPH::edge_index_type max_edge_index(
785     UNDIRECTED_GRAPH const& g)
786 {
787     return g.max_edge_index();
788 }
789 
790 template < UNDIRECTED_GRAPH_PARAMS >
renumber_edge_indices(UNDIRECTED_GRAPH & g)791 inline void renumber_edge_indices(UNDIRECTED_GRAPH& g)
792 {
793     g.renumber_edge_indices();
794 }
795 
796 template < UNDIRECTED_GRAPH_PARAMS >
remove_edge_and_renumber_indices(typename UNDIRECTED_GRAPH::edge_iterator i,UNDIRECTED_GRAPH & g)797 inline void remove_edge_and_renumber_indices(
798     typename UNDIRECTED_GRAPH::edge_iterator i, UNDIRECTED_GRAPH& g)
799 {
800     g.remove_edge_and_renumber_indices(i);
801 }
802 
803 // Index management
804 template < UNDIRECTED_GRAPH_PARAMS >
renumber_indices(UNDIRECTED_GRAPH & g)805 inline void renumber_indices(UNDIRECTED_GRAPH& g)
806 {
807     g.renumber_indices();
808 }
809 
810 // Mutability Traits
811 template < UNDIRECTED_GRAPH_PARAMS >
812 struct graph_mutability_traits< UNDIRECTED_GRAPH >
813 {
814     typedef mutable_property_graph_tag category;
815 };
816 
817 #undef UNDIRECTED_GRAPH_PARAMS
818 #undef UNDIRECTED_GRAPH
819 
820 } /* namespace boost */
821 
822 #endif
823