41 #ifndef BOOST_GRAPH_COPY_HPP
42 #define BOOST_GRAPH_COPY_HPP
44 #include <boost/config.hpp>
46 #include <boost/graph/graph_traits.hpp>
47 #include <boost/graph/reverse_graph.hpp>
48 #include <boost/property_map/property_map.hpp>
49 #include <boost/graph/named_function_params.hpp>
50 #include <boost/graph/breadth_first_search.hpp>
51 #include <boost/type_traits/conversion_traits.hpp>
58 template <
typename Graph,
typename Desc>
61 static Desc convert(
const Desc& d,
const Graph&) {
return d;}
64 template <
typename Graph,
typename Desc>
67 static Desc convert(
const reverse_graph_edge_descriptor<Desc>& d,
const Graph& g) {
68 return get(edge_underlying, g, d);
77 template <
typename Desc,
typename Graph>
80 static Desc convert(
const Desc& d) {
return d;}
83 template <
typename Desc,
typename G,
typename GR>
85 typedef reverse_graph_edge_descriptor<Desc> type;
86 static reverse_graph_edge_descriptor<Desc> convert(
const Desc& d) {
87 return reverse_graph_edge_descriptor<Desc>(d);
91 template <
typename Desc,
typename G,
typename GR>
93 typedef reverse_graph_edge_descriptor<Desc> type;
94 static reverse_graph_edge_descriptor<Desc> convert(
const reverse_graph_edge_descriptor<Desc>& d) {
101 template <
typename Graph1,
typename Graph2>
104 : edge_all_map1(
get(edge_all, g1)),
105 edge_all_map2(
get(edge_all, g2)) { }
107 template <
typename Edge1,
typename Edge2>
108 void operator()(
const Edge1& e1, Edge2& e2)
const {
111 typename property_map<Graph1, edge_all_t>::const_type edge_all_map1;
112 mutable typename property_map<Graph2, edge_all_t>::type edge_all_map2;
114 template <
typename Graph1,
typename Graph2>
116 make_edge_copier(
const Graph1& g1, Graph2& g2)
121 template <
typename Graph1,
typename Graph2>
124 : vertex_all_map1(
get(vertex_all, g1)),
125 vertex_all_map2(
get(vertex_all, g2)) { }
127 template <
typename Vertex1,
typename Vertex2>
128 void operator()(
const Vertex1& v1, Vertex2& v2)
const {
129 put(vertex_all_map2, v2,
get(vertex_all_map1, v1));
131 typename property_map<Graph1, vertex_all_t>::const_type vertex_all_map1;
132 mutable typename property_map<Graph2, vertex_all_t>::type
135 template <
typename Graph1,
typename Graph2>
137 make_vertex_copier(
const Graph1& g1, Graph2& g2)
146 template <
int Version>
151 template <
typename Graph,
typename MutableGraph,
152 typename CopyVertex,
typename CopyEdge,
typename IndexMap,
153 typename Orig2CopyVertexIndexMap>
154 static void apply(
const Graph& g_in, MutableGraph& g_out,
155 CopyVertex copy_vertex, CopyEdge copy_edge,
156 Orig2CopyVertexIndexMap orig2copy, IndexMap)
159 typename graph_traits<Graph>::vertex_iterator vi, vi_end;
160 for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
161 typename graph_traits<MutableGraph>::vertex_descriptor
162 new_v = add_vertex(g_out);
163 put(orig2copy, *vi, new_v);
164 copy_vertex(*vi, new_v);
166 typename graph_traits<Graph>::edge_iterator ei, ei_end;
167 for (boost::tie(ei, ei_end) = edges(g_in); ei != ei_end; ++ei) {
168 typename graph_traits<MutableGraph>::edge_descriptor new_e;
170 boost::tie(new_e, inserted) = add_edge(
get(orig2copy, source(*ei, g_in)),
171 get(orig2copy, target(*ei, g_in)),
173 copy_edge(cvt::convert(*ei, g_in), new_e);
181 template <
typename Graph,
typename MutableGraph,
182 typename CopyVertex,
typename CopyEdge,
typename IndexMap,
183 typename Orig2CopyVertexIndexMap>
184 static void apply(
const Graph& g_in, MutableGraph& g_out,
185 CopyVertex copy_vertex, CopyEdge copy_edge,
186 Orig2CopyVertexIndexMap orig2copy, IndexMap)
189 typename graph_traits<Graph>::vertex_iterator vi, vi_end;
190 for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
191 typename graph_traits<MutableGraph>::vertex_descriptor
192 new_v = add_vertex(g_out);
193 put(orig2copy, *vi, new_v);
194 copy_vertex(*vi, new_v);
196 for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
197 typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
198 for (boost::tie(ei, ei_end) = out_edges(*vi, g_in); ei != ei_end; ++ei) {
199 typename graph_traits<MutableGraph>::edge_descriptor new_e;
201 boost::tie(new_e, inserted) = add_edge(
get(orig2copy, source(*ei, g_in)),
202 get(orig2copy, target(*ei, g_in)),
204 copy_edge(cvt::convert(*ei, g_in), new_e);
213 template <
typename Graph,
typename MutableGraph,
214 typename CopyVertex,
typename CopyEdge,
typename IndexMap,
215 typename Orig2CopyVertexIndexMap>
216 static void apply(
const Graph& g_in, MutableGraph& g_out,
217 CopyVertex copy_vertex, CopyEdge copy_edge,
218 Orig2CopyVertexIndexMap orig2copy,
222 typedef color_traits<default_color_type> Color;
223 std::vector<default_color_type>
224 color(num_vertices(g_in), Color::white());
225 typename graph_traits<Graph>::vertex_iterator vi, vi_end;
226 for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
227 typename graph_traits<MutableGraph>::vertex_descriptor
228 new_v = add_vertex(g_out);
229 put(orig2copy, *vi, new_v);
230 copy_vertex(*vi, new_v);
232 for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
233 typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
234 for (boost::tie(ei, ei_end) = out_edges(*vi, g_in); ei != ei_end; ++ei) {
235 typename graph_traits<MutableGraph>::edge_descriptor new_e;
237 if (color[
get(index_map, target(*ei, g_in))] == Color::white()) {
238 boost::tie(new_e, inserted) = add_edge(
get(orig2copy, source(*ei,g_in)),
239 get(orig2copy, target(*ei,g_in)),
241 copy_edge(cvt::convert(*ei, g_in), new_e);
244 color[
get(index_map, *vi)] = Color::black();
249 template <
class Graph>
251 typedef typename Graph::traversal_category Trv;
252 typedef typename Graph::directed_category Dr;
254 (is_convertible<Trv, vertex_list_graph_tag>::value
255 && is_convertible<Trv, edge_list_graph_tag>::value)
256 ? 0 : is_convertible<Dr, directed_tag>::value ? 1 : 2 };
262 template <
class P,
class G1,
class G2>
264 typedef const P& result_type;
265 static result_type apply(
const P& p,
const G1&, G2&)
270 template <
class P,
class G1,
class G2>
273 static result_type apply(
const P&,
const G1& g1, G2& g2) {
274 return result_type(g1, g2);
278 template <
class Param>
286 template <
class Param,
class G1,
class G2>
289 typedef typename Selector:: template bind_<Param, G1, G2> Bind;
291 typedef typename Bind::result_type result_type;
293 template <
typename Param,
typename G1,
typename G2>
294 typename detail::choose_edge_copier_helper<Param,G1,G2>::result_type
295 choose_edge_copier(
const Param& params,
const G1& g_in, G2& g_out)
298 detail::choose_edge_copier_helper<Param,G1,G2>::type Choice;
299 return Choice::apply(params, g_in, g_out);
304 template <
class P,
class G1,
class G2>
307 static result_type apply(
const P&,
const G1& g1, G2& g2) {
308 return result_type(g1, g2);
312 template <
class Param>
320 template <
class Param,
class G1,
class G2>
323 typedef typename Selector:: template bind_<Param, G1, G2> Bind;
325 typedef typename Bind::result_type result_type;
327 template <
typename Param,
typename G1,
typename G2>
328 typename detail::choose_vertex_copier_helper<Param,G1,G2>::result_type
329 choose_vertex_copier(
const Param& params,
const G1& g_in, G2& g_out)
332 detail::choose_vertex_copier_helper<Param,G1,G2>::type Choice;
333 return Choice::apply(params, g_in, g_out);
339 template <
typename VertexListGraph,
typename MutableGraph>
340 void copy_graph(
const VertexListGraph& g_in, MutableGraph& g_out)
342 if (num_vertices(g_in) == 0)
344 typedef typename graph_traits<MutableGraph>::vertex_descriptor vertex_t;
345 std::vector<vertex_t> orig2copy(num_vertices(g_in));
346 typedef typename detail::choose_graph_copy<VertexListGraph>::type
350 detail::make_vertex_copier(g_in, g_out),
351 detail::make_edge_copier(g_in, g_out),
352 make_iterator_property_map(orig2copy.begin(),
353 get(vertex_index, g_in), orig2copy[0]),
354 get(vertex_index, g_in)
358 template <
typename VertexListGraph,
typename MutableGraph,
359 class P,
class T,
class R>
360 void copy_graph(
const VertexListGraph& g_in, MutableGraph& g_out,
361 const bgl_named_params<P, T, R>& params)
363 typename std::vector<T>::size_type n;
364 n = is_default_param(get_param(params, orig_to_copy_t()))
365 ? num_vertices(g_in) : 1;
368 std::vector<BOOST_DEDUCED_TYPENAME graph_traits<MutableGraph>::vertex_descriptor>
371 typedef typename detail::choose_graph_copy<VertexListGraph>::type
375 detail::choose_vertex_copier(get_param(params, vertex_copy_t()),
377 detail::choose_edge_copier(get_param(params, edge_copy_t()),
379 choose_param(get_param(params, orig_to_copy_t()),
380 make_iterator_property_map
382 choose_const_pmap(get_param(params, vertex_index),
383 g_in, vertex_index), orig2copy[0])),
384 choose_const_pmap(get_param(params, vertex_index), g_in, vertex_index)
390 template <
class NewGraph,
class Copy2OrigIndexMap,
391 class CopyVertex,
class CopyEdge>
395 CopyVertex cv, CopyEdge ce)
396 : g_out(graph), orig2copy(c), copy_vertex(cv), copy_edge(ce) { }
398 template <
class Vertex>
399 typename graph_traits<NewGraph>::vertex_descriptor copy_one_vertex(Vertex u)
const {
400 typename graph_traits<NewGraph>::vertex_descriptor
401 new_u = add_vertex(g_out);
402 put(orig2copy, u, new_u);
403 copy_vertex(u, new_u);
407 template <
class Edge,
class Graph>
408 void tree_edge(Edge e,
const Graph& g_in)
const {
410 typename graph_traits<NewGraph>::edge_descriptor new_e;
412 boost::tie(new_e, inserted) = add_edge(
get(orig2copy, source(e, g_in)),
413 this->copy_one_vertex(target(e, g_in)),
418 template <
class Edge,
class Graph>
419 void non_tree_edge(Edge e,
const Graph& g_in)
const {
421 typename graph_traits<NewGraph>::edge_descriptor new_e;
423 boost::tie(new_e, inserted) = add_edge(
get(orig2copy, source(e, g_in)),
424 get(orig2copy, target(e, g_in)),
430 Copy2OrigIndexMap orig2copy;
431 CopyVertex copy_vertex;
435 template <
typename Graph,
typename MutableGraph,
436 typename CopyVertex,
typename CopyEdge,
437 typename Orig2CopyVertexIndexMap,
typename Params>
438 typename graph_traits<MutableGraph>::vertex_descriptor
441 typename graph_traits<Graph>::vertex_descriptor src,
443 CopyVertex copy_vertex, CopyEdge copy_edge,
444 Orig2CopyVertexIndexMap orig2copy,
445 const Params& params)
448 CopyVertex, CopyEdge> vis(g_out, orig2copy, copy_vertex, copy_edge);
449 typename graph_traits<MutableGraph>::vertex_descriptor src_copy
450 = vis.copy_one_vertex(src);
451 breadth_first_search(g_in, src, params.visitor(vis));
461 template <
typename IncidenceGraph,
typename MutableGraph,
462 typename P,
typename T,
typename R>
463 typename graph_traits<MutableGraph>::vertex_descriptor
464 copy_component(IncidenceGraph& g_in,
465 typename graph_traits<IncidenceGraph>::vertex_descriptor src,
467 const bgl_named_params<P, T, R>& params)
469 typename std::vector<T>::size_type n;
470 n = is_default_param(get_param(params, orig_to_copy_t()))
471 ? num_vertices(g_in) : 1;
472 std::vector<typename graph_traits<IncidenceGraph>::vertex_descriptor>
475 return detail::copy_component_impl
477 detail::choose_vertex_copier(get_param(params, vertex_copy_t()),
479 detail::choose_edge_copier(get_param(params, edge_copy_t()),
481 choose_param(get_param(params, orig_to_copy_t()),
482 make_iterator_property_map
484 choose_pmap(get_param(params, vertex_index),
485 g_in, vertex_index), orig2copy[0])),
490 template <
typename Inc
idenceGraph,
typename MutableGraph>
491 typename graph_traits<MutableGraph>::vertex_descriptor
492 copy_component(IncidenceGraph& g_in,
493 typename graph_traits<IncidenceGraph>::vertex_descriptor src,
496 std::vector<typename graph_traits<IncidenceGraph>::vertex_descriptor>
497 orig2copy(num_vertices(g_in));
499 return detail::copy_component_impl
501 detail::make_vertex_copier(g_in, g_out),
502 detail::make_edge_copier(g_in, g_out),
503 make_iterator_property_map(orig2copy.begin(),
504 get(vertex_index, g_in), orig2copy[0]),
505 bgl_named_params<char,char>(
'x')
511 #endif // BOOST_GRAPH_COPY_HPP