1 | //======================================================================= |
---|
2 | // Copyright 1997, 1998, 1999, 2000 University of Notre Dame. |
---|
3 | // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek |
---|
4 | // |
---|
5 | // Distributed under the Boost Software License, Version 1.0. (See |
---|
6 | // accompanying file LICENSE_1_0.txt or copy at |
---|
7 | // http://www.boost.org/LICENSE_1_0.txt) |
---|
8 | //======================================================================= |
---|
9 | |
---|
10 | #include <boost/config.hpp> |
---|
11 | #include <iostream> |
---|
12 | #include <string> |
---|
13 | #include <boost/graph/adjacency_list.hpp> |
---|
14 | #include <boost/graph/graph_utility.hpp> |
---|
15 | |
---|
16 | using namespace boost; |
---|
17 | |
---|
18 | // Predicate Function for use in remove if |
---|
19 | template <class NamePropertyMap> |
---|
20 | struct name_equals_predicate |
---|
21 | { |
---|
22 | name_equals_predicate(const std::string& x, NamePropertyMap name) |
---|
23 | : m_str(x), m_name(name) { } |
---|
24 | |
---|
25 | template <class Edge> |
---|
26 | bool operator()(const Edge& e) const { |
---|
27 | return m_str == m_name[e]; |
---|
28 | } |
---|
29 | std::string m_str; |
---|
30 | NamePropertyMap m_name; |
---|
31 | }; |
---|
32 | // helper creation function |
---|
33 | template <class NamePropertyMap> |
---|
34 | inline name_equals_predicate<NamePropertyMap> |
---|
35 | name_equals(const std::string& str, NamePropertyMap name) { |
---|
36 | return name_equals_predicate<NamePropertyMap>(str, name); |
---|
37 | } |
---|
38 | |
---|
39 | template <class MutableGraph> |
---|
40 | void modify_demo(MutableGraph& g) |
---|
41 | { |
---|
42 | typedef graph_traits<MutableGraph> GraphTraits; |
---|
43 | typedef typename GraphTraits::vertices_size_type size_type; |
---|
44 | typedef typename GraphTraits::edge_descriptor edge_descriptor; |
---|
45 | size_type n = 0; |
---|
46 | typename GraphTraits::edges_size_type m = 0; |
---|
47 | typename GraphTraits::vertex_descriptor u, v, w; |
---|
48 | edge_descriptor e, e1, e2; |
---|
49 | typename property_map<MutableGraph, edge_name_t>::type |
---|
50 | name_map = get(edge_name, g); |
---|
51 | bool added; |
---|
52 | typename GraphTraits::vertex_iterator vi, vi_end; |
---|
53 | |
---|
54 | { |
---|
55 | v = add_vertex(g); |
---|
56 | |
---|
57 | assert(num_vertices(g) == n + 1); |
---|
58 | assert(size_type(vertices(g).second - vertices(g).first) == n + 1); |
---|
59 | assert(v == *std::find(vertices(g).first, vertices(g).second, v)); |
---|
60 | } |
---|
61 | { |
---|
62 | remove_vertex(v, g); |
---|
63 | |
---|
64 | assert(num_vertices(g) == n); |
---|
65 | assert(size_type(vertices(g).second - vertices(g).first) == n); |
---|
66 | // v is no longer a valid vertex descriptor |
---|
67 | } |
---|
68 | { |
---|
69 | u = add_vertex(g); |
---|
70 | v = add_vertex(g); |
---|
71 | |
---|
72 | std::pair<edge_descriptor, bool> p = add_edge(u, v, g); |
---|
73 | |
---|
74 | assert(num_edges(g) == m + 1); |
---|
75 | assert(p.second == true); // edge should have been added |
---|
76 | assert(source(p.first, g) == u); |
---|
77 | assert(target(p.first, g) == v); |
---|
78 | assert(p.first == *std::find(out_edges(u, g).first, |
---|
79 | out_edges(u, g).second, p.first)); |
---|
80 | assert(p.first == *std::find(in_edges(v, g).first, |
---|
81 | in_edges(v, g).second, p.first)); |
---|
82 | } |
---|
83 | { |
---|
84 | // use tie() for convenience, avoid using the std::pair |
---|
85 | |
---|
86 | u = add_vertex(g); |
---|
87 | v = add_vertex(g); |
---|
88 | |
---|
89 | tie(e, added) = add_edge(u, v, g); |
---|
90 | |
---|
91 | assert(num_edges(g) == m + 2); |
---|
92 | assert(added == true); // edge should have been added |
---|
93 | assert(source(e, g) == u); |
---|
94 | assert(target(e, g) == v); |
---|
95 | assert(e == *std::find(out_edges(u, g).first, out_edges(u, g).second, e)); |
---|
96 | assert(e == *std::find(in_edges(v, g).first, in_edges(v, g).second, e)); |
---|
97 | } |
---|
98 | { |
---|
99 | add_edge(u, v, g); // add a parallel edge |
---|
100 | |
---|
101 | remove_edge(u, v, g); |
---|
102 | |
---|
103 | assert(num_edges(g) == m + 1); |
---|
104 | bool exists; |
---|
105 | tie(e, exists) = edge(u, v, g); |
---|
106 | assert(exists == false); |
---|
107 | assert(out_degree(u, g) == 0); |
---|
108 | assert(in_degree(v, g) == 0); |
---|
109 | } |
---|
110 | { |
---|
111 | e = *edges(g).first; |
---|
112 | tie(u, v) = incident(e, g); |
---|
113 | |
---|
114 | remove_edge(e, g); |
---|
115 | |
---|
116 | assert(num_edges(g) == m); |
---|
117 | assert(out_degree(u, g) == 0); |
---|
118 | assert(in_degree(v, g) == 0); |
---|
119 | } |
---|
120 | { |
---|
121 | add_edge(u, v, g); |
---|
122 | |
---|
123 | typename GraphTraits::out_edge_iterator iter, iter_end; |
---|
124 | tie(iter, iter_end) = out_edges(u, g); |
---|
125 | |
---|
126 | remove_edge(iter, g); |
---|
127 | |
---|
128 | assert(num_edges(g) == m); |
---|
129 | assert(out_degree(u, g) == 0); |
---|
130 | assert(in_degree(v, g) == 0); |
---|
131 | } |
---|
132 | { |
---|
133 | w = add_vertex(g); |
---|
134 | tie(e1, added) = add_edge(u, v, g); |
---|
135 | tie(e2, added) = add_edge(v, w, g); |
---|
136 | name_map[e1] = "I-5"; |
---|
137 | name_map[e2] = "Route 66"; |
---|
138 | |
---|
139 | typename GraphTraits::out_edge_iterator iter, iter_end; |
---|
140 | tie(iter, iter_end) = out_edges(u, g); |
---|
141 | |
---|
142 | remove_edge_if(name_equals("Route 66", name_map), g); |
---|
143 | |
---|
144 | assert(num_edges(g) == m + 1); |
---|
145 | |
---|
146 | remove_edge_if(name_equals("I-5", name_map), g); |
---|
147 | |
---|
148 | assert(num_edges(g) == m); |
---|
149 | assert(out_degree(u, g) == 0); |
---|
150 | assert(out_degree(v, g) == 0); |
---|
151 | assert(in_degree(v, g) == 0); |
---|
152 | assert(in_degree(w, g) == 0); |
---|
153 | } |
---|
154 | { |
---|
155 | tie(e1, added) = add_edge(u, v, g); |
---|
156 | tie(e2, added) = add_edge(u, w, g); |
---|
157 | name_map[e1] = "foo"; |
---|
158 | name_map[e2] = "foo"; |
---|
159 | |
---|
160 | remove_out_edge_if(u, name_equals("foo", name_map), g); |
---|
161 | |
---|
162 | assert(num_edges(g) == m); |
---|
163 | assert(out_degree(u, g) == 0); |
---|
164 | } |
---|
165 | { |
---|
166 | tie(e1, added) = add_edge(u, v, g); |
---|
167 | tie(e2, added) = add_edge(w, v, g); |
---|
168 | name_map[e1] = "bar"; |
---|
169 | name_map[e2] = "bar"; |
---|
170 | |
---|
171 | remove_in_edge_if(v, name_equals("bar", name_map), g); |
---|
172 | |
---|
173 | assert(num_edges(g) == m); |
---|
174 | assert(in_degree(v, g) == 0); |
---|
175 | } |
---|
176 | { |
---|
177 | add_edge(u, v, g); |
---|
178 | add_edge(u, w, g); |
---|
179 | add_edge(u, v, g); |
---|
180 | add_edge(v, u, g); |
---|
181 | |
---|
182 | clear_vertex(u, g); |
---|
183 | |
---|
184 | assert(out_degree(u, g) == 0); |
---|
185 | |
---|
186 | for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { |
---|
187 | typename GraphTraits::adjacency_iterator ai, ai_end; |
---|
188 | for (tie(ai, ai_end) = adjacent_vertices(*vi, g); |
---|
189 | ai != ai_end; ++ai) |
---|
190 | assert(*ai != u); |
---|
191 | } |
---|
192 | } |
---|
193 | } |
---|
194 | |
---|
195 | int |
---|
196 | main() |
---|
197 | { |
---|
198 | adjacency_list<listS, vecS, bidirectionalS, |
---|
199 | no_property, property<edge_name_t, std::string> > g; |
---|
200 | |
---|
201 | modify_demo(g); |
---|
202 | return 0; |
---|
203 | } |
---|