copy.hpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. //
  2. //=======================================================================
  3. // Copyright 1997-2001 University of Notre Dame.
  4. // Authors: Jeremy G. Siek, Lie-Quan Lee, Andrew Lumsdaine
  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. //
  11. /*
  12. This file implements the following functions:
  13. template <typename VertexListGraph, typename MutableGraph>
  14. void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out)
  15. template <typename VertexListGraph, typename MutableGraph,
  16. class P, class T, class R>
  17. void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out,
  18. const bgl_named_params<P, T, R>& params)
  19. template <typename IncidenceGraph, typename MutableGraph>
  20. typename graph_traits<MutableGraph>::vertex_descriptor
  21. copy_component(IncidenceGraph& g_in,
  22. typename graph_traits<IncidenceGraph>::vertex_descriptor src,
  23. MutableGraph& g_out)
  24. template <typename IncidenceGraph, typename MutableGraph,
  25. typename P, typename T, typename R>
  26. typename graph_traits<MutableGraph>::vertex_descriptor
  27. copy_component(IncidenceGraph& g_in,
  28. typename graph_traits<IncidenceGraph>::vertex_descriptor src,
  29. MutableGraph& g_out,
  30. const bgl_named_params<P, T, R>& params)
  31. */
  32. #ifndef BOOST_GRAPH_COPY_HPP
  33. #define BOOST_GRAPH_COPY_HPP
  34. #include <boost/config.hpp>
  35. #include <vector>
  36. #include <boost/graph/graph_traits.hpp>
  37. #include <boost/graph/reverse_graph.hpp>
  38. #include <boost/property_map/property_map.hpp>
  39. #include <boost/graph/named_function_params.hpp>
  40. #include <boost/graph/breadth_first_search.hpp>
  41. #include <boost/type_traits/conversion_traits.hpp>
  42. namespace boost
  43. {
  44. namespace detail
  45. {
  46. // Hack to make transpose_graph work with the same interface as before
  47. template < typename Graph, typename Desc >
  48. struct remove_reverse_edge_descriptor
  49. {
  50. typedef Desc type;
  51. static Desc convert(const Desc& d, const Graph&) { return d; }
  52. };
  53. template < typename Graph, typename Desc >
  54. struct remove_reverse_edge_descriptor< Graph,
  55. reverse_graph_edge_descriptor< Desc > >
  56. {
  57. typedef Desc type;
  58. static Desc convert(
  59. const reverse_graph_edge_descriptor< Desc >& d, const Graph& g)
  60. {
  61. return get(edge_underlying, g, d);
  62. }
  63. };
  64. // Add a reverse_graph_edge_descriptor wrapper if the Graph is a
  65. // reverse_graph but the edge descriptor is from the original graph (this
  66. // case comes from the fact that transpose_graph uses reverse_graph
  67. // internally but doesn't expose the different edge descriptor type to the
  68. // user).
  69. template < typename Desc, typename Graph >
  70. struct add_reverse_edge_descriptor
  71. {
  72. typedef Desc type;
  73. static Desc convert(const Desc& d) { return d; }
  74. };
  75. template < typename Desc, typename G, typename GR >
  76. struct add_reverse_edge_descriptor< Desc, boost::reverse_graph< G, GR > >
  77. {
  78. typedef reverse_graph_edge_descriptor< Desc > type;
  79. static reverse_graph_edge_descriptor< Desc > convert(const Desc& d)
  80. {
  81. return reverse_graph_edge_descriptor< Desc >(d);
  82. }
  83. };
  84. template < typename Desc, typename G, typename GR >
  85. struct add_reverse_edge_descriptor< reverse_graph_edge_descriptor< Desc >,
  86. boost::reverse_graph< G, GR > >
  87. {
  88. typedef reverse_graph_edge_descriptor< Desc > type;
  89. static reverse_graph_edge_descriptor< Desc > convert(
  90. const reverse_graph_edge_descriptor< Desc >& d)
  91. {
  92. return d;
  93. }
  94. };
  95. // Default edge and vertex property copiers
  96. template < typename Graph1, typename Graph2 > struct edge_copier
  97. {
  98. edge_copier(const Graph1& g1, Graph2& g2)
  99. : edge_all_map1(get(edge_all, g1)), edge_all_map2(get(edge_all, g2))
  100. {
  101. }
  102. template < typename Edge1, typename Edge2 >
  103. void operator()(const Edge1& e1, Edge2& e2) const
  104. {
  105. put(edge_all_map2, e2,
  106. get(edge_all_map1,
  107. add_reverse_edge_descriptor< Edge1, Graph1 >::convert(e1)));
  108. }
  109. typename property_map< Graph1, edge_all_t >::const_type edge_all_map1;
  110. mutable typename property_map< Graph2, edge_all_t >::type edge_all_map2;
  111. };
  112. template < typename Graph1, typename Graph2 >
  113. inline edge_copier< Graph1, Graph2 > make_edge_copier(
  114. const Graph1& g1, Graph2& g2)
  115. {
  116. return edge_copier< Graph1, Graph2 >(g1, g2);
  117. }
  118. template < typename Graph1, typename Graph2 > struct vertex_copier
  119. {
  120. vertex_copier(const Graph1& g1, Graph2& g2)
  121. : vertex_all_map1(get(vertex_all, g1))
  122. , vertex_all_map2(get(vertex_all, g2))
  123. {
  124. }
  125. template < typename Vertex1, typename Vertex2 >
  126. void operator()(const Vertex1& v1, Vertex2& v2) const
  127. {
  128. put(vertex_all_map2, v2, get(vertex_all_map1, v1));
  129. }
  130. typename property_map< Graph1, vertex_all_t >::const_type
  131. vertex_all_map1;
  132. mutable
  133. typename property_map< Graph2, vertex_all_t >::type vertex_all_map2;
  134. };
  135. template < typename Graph1, typename Graph2 >
  136. inline vertex_copier< Graph1, Graph2 > make_vertex_copier(
  137. const Graph1& g1, Graph2& g2)
  138. {
  139. return vertex_copier< Graph1, Graph2 >(g1, g2);
  140. }
  141. // Copy all the vertices and edges of graph g_in into graph g_out.
  142. // The copy_vertex and copy_edge function objects control how vertex
  143. // and edge properties are copied.
  144. template < int Version > struct copy_graph_impl
  145. {
  146. };
  147. template <> struct copy_graph_impl< 0 >
  148. {
  149. template < typename Graph, typename MutableGraph, typename CopyVertex,
  150. typename CopyEdge, typename IndexMap,
  151. typename Orig2CopyVertexIndexMap >
  152. static void apply(const Graph& g_in, MutableGraph& g_out,
  153. CopyVertex copy_vertex, CopyEdge copy_edge,
  154. Orig2CopyVertexIndexMap orig2copy, IndexMap)
  155. {
  156. typedef remove_reverse_edge_descriptor< Graph,
  157. typename graph_traits< Graph >::edge_descriptor >
  158. cvt;
  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. {
  162. typename graph_traits< MutableGraph >::vertex_descriptor new_v
  163. = add_vertex(g_out);
  164. put(orig2copy, *vi, new_v);
  165. copy_vertex(*vi, new_v);
  166. }
  167. typename graph_traits< Graph >::edge_iterator ei, ei_end;
  168. for (boost::tie(ei, ei_end) = edges(g_in); ei != ei_end; ++ei)
  169. {
  170. typename graph_traits< MutableGraph >::edge_descriptor new_e;
  171. bool inserted;
  172. boost::tie(new_e, inserted)
  173. = add_edge(get(orig2copy, source(*ei, g_in)),
  174. get(orig2copy, target(*ei, g_in)), g_out);
  175. copy_edge(cvt::convert(*ei, g_in), new_e);
  176. }
  177. }
  178. };
  179. // for directed graphs
  180. template <> struct copy_graph_impl< 1 >
  181. {
  182. template < typename Graph, typename MutableGraph, typename CopyVertex,
  183. typename CopyEdge, typename IndexMap,
  184. typename Orig2CopyVertexIndexMap >
  185. static void apply(const Graph& g_in, MutableGraph& g_out,
  186. CopyVertex copy_vertex, CopyEdge copy_edge,
  187. Orig2CopyVertexIndexMap orig2copy, IndexMap)
  188. {
  189. typedef remove_reverse_edge_descriptor< Graph,
  190. typename graph_traits< Graph >::edge_descriptor >
  191. cvt;
  192. typename graph_traits< Graph >::vertex_iterator vi, vi_end;
  193. for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi)
  194. {
  195. typename graph_traits< MutableGraph >::vertex_descriptor new_v
  196. = add_vertex(g_out);
  197. put(orig2copy, *vi, new_v);
  198. copy_vertex(*vi, new_v);
  199. }
  200. for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi)
  201. {
  202. typename graph_traits< Graph >::out_edge_iterator ei, ei_end;
  203. for (boost::tie(ei, ei_end) = out_edges(*vi, g_in);
  204. ei != ei_end; ++ei)
  205. {
  206. typename graph_traits< MutableGraph >::edge_descriptor
  207. new_e;
  208. bool inserted;
  209. boost::tie(new_e, inserted)
  210. = add_edge(get(orig2copy, source(*ei, g_in)),
  211. get(orig2copy, target(*ei, g_in)), g_out);
  212. copy_edge(cvt::convert(*ei, g_in), new_e);
  213. }
  214. }
  215. }
  216. };
  217. // for undirected graphs
  218. template <> struct copy_graph_impl< 2 >
  219. {
  220. template < typename Graph, typename MutableGraph, typename CopyVertex,
  221. typename CopyEdge, typename IndexMap,
  222. typename Orig2CopyVertexIndexMap >
  223. static void apply(const Graph& g_in, MutableGraph& g_out,
  224. CopyVertex copy_vertex, CopyEdge copy_edge,
  225. Orig2CopyVertexIndexMap orig2copy, IndexMap index_map)
  226. {
  227. typedef remove_reverse_edge_descriptor< Graph,
  228. typename graph_traits< Graph >::edge_descriptor >
  229. cvt;
  230. typedef color_traits< default_color_type > Color;
  231. std::vector< default_color_type > color(
  232. num_vertices(g_in), Color::white());
  233. typename graph_traits< Graph >::vertex_iterator vi, vi_end;
  234. for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi)
  235. {
  236. typename graph_traits< MutableGraph >::vertex_descriptor new_v
  237. = add_vertex(g_out);
  238. put(orig2copy, *vi, new_v);
  239. copy_vertex(*vi, new_v);
  240. }
  241. for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi)
  242. {
  243. typename graph_traits< Graph >::out_edge_iterator ei, ei_end;
  244. for (boost::tie(ei, ei_end) = out_edges(*vi, g_in);
  245. ei != ei_end; ++ei)
  246. {
  247. typename graph_traits< MutableGraph >::edge_descriptor
  248. new_e;
  249. bool inserted;
  250. if (color[get(index_map, target(*ei, g_in))]
  251. == Color::white())
  252. {
  253. boost::tie(new_e, inserted)
  254. = add_edge(get(orig2copy, source(*ei, g_in)),
  255. get(orig2copy, target(*ei, g_in)), g_out);
  256. copy_edge(cvt::convert(*ei, g_in), new_e);
  257. }
  258. }
  259. color[get(index_map, *vi)] = Color::black();
  260. }
  261. }
  262. };
  263. template < class Graph > struct choose_graph_copy
  264. {
  265. typedef typename graph_traits< Graph >::traversal_category Trv;
  266. typedef typename graph_traits< Graph >::directed_category Dr;
  267. enum
  268. {
  269. algo = (is_convertible< Trv, vertex_list_graph_tag >::value
  270. && is_convertible< Trv, edge_list_graph_tag >::value)
  271. ? 0
  272. : is_convertible< Dr, directed_tag >::value ? 1 : 2
  273. };
  274. typedef copy_graph_impl< algo > type;
  275. };
  276. //-------------------------------------------------------------------------
  277. struct choose_copier_parameter
  278. {
  279. template < class P, class G1, class G2 > struct bind_
  280. {
  281. typedef const P& result_type;
  282. static result_type apply(const P& p, const G1&, G2&) { return p; }
  283. };
  284. };
  285. struct choose_default_edge_copier
  286. {
  287. template < class P, class G1, class G2 > struct bind_
  288. {
  289. typedef edge_copier< G1, G2 > result_type;
  290. static result_type apply(const P&, const G1& g1, G2& g2)
  291. {
  292. return result_type(g1, g2);
  293. }
  294. };
  295. };
  296. template < class Param > struct choose_edge_copy
  297. {
  298. typedef choose_copier_parameter type;
  299. };
  300. template <> struct choose_edge_copy< param_not_found >
  301. {
  302. typedef choose_default_edge_copier type;
  303. };
  304. template < class Param, class G1, class G2 >
  305. struct choose_edge_copier_helper
  306. {
  307. typedef typename choose_edge_copy< Param >::type Selector;
  308. typedef typename Selector::template bind_< Param, G1, G2 > Bind;
  309. typedef Bind type;
  310. typedef typename Bind::result_type result_type;
  311. };
  312. template < typename Param, typename G1, typename G2 >
  313. typename detail::choose_edge_copier_helper< Param, G1, G2 >::result_type
  314. choose_edge_copier(const Param& params, const G1& g_in, G2& g_out)
  315. {
  316. typedef
  317. typename detail::choose_edge_copier_helper< Param, G1, G2 >::type
  318. Choice;
  319. return Choice::apply(params, g_in, g_out);
  320. }
  321. struct choose_default_vertex_copier
  322. {
  323. template < class P, class G1, class G2 > struct bind_
  324. {
  325. typedef vertex_copier< G1, G2 > result_type;
  326. static result_type apply(const P&, const G1& g1, G2& g2)
  327. {
  328. return result_type(g1, g2);
  329. }
  330. };
  331. };
  332. template < class Param > struct choose_vertex_copy
  333. {
  334. typedef choose_copier_parameter type;
  335. };
  336. template <> struct choose_vertex_copy< param_not_found >
  337. {
  338. typedef choose_default_vertex_copier type;
  339. };
  340. template < class Param, class G1, class G2 >
  341. struct choose_vertex_copier_helper
  342. {
  343. typedef typename choose_vertex_copy< Param >::type Selector;
  344. typedef typename Selector::template bind_< Param, G1, G2 > Bind;
  345. typedef Bind type;
  346. typedef typename Bind::result_type result_type;
  347. };
  348. template < typename Param, typename G1, typename G2 >
  349. typename detail::choose_vertex_copier_helper< Param, G1, G2 >::result_type
  350. choose_vertex_copier(const Param& params, const G1& g_in, G2& g_out)
  351. {
  352. typedef
  353. typename detail::choose_vertex_copier_helper< Param, G1, G2 >::type
  354. Choice;
  355. return Choice::apply(params, g_in, g_out);
  356. }
  357. } // namespace detail
  358. template < typename VertexListGraph, typename MutableGraph >
  359. void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out)
  360. {
  361. if (num_vertices(g_in) == 0)
  362. return;
  363. typedef typename graph_traits< MutableGraph >::vertex_descriptor vertex_t;
  364. std::vector< vertex_t > orig2copy(num_vertices(g_in));
  365. typedef
  366. typename detail::choose_graph_copy< VertexListGraph >::type copy_impl;
  367. copy_impl::apply(g_in, g_out, detail::make_vertex_copier(g_in, g_out),
  368. detail::make_edge_copier(g_in, g_out),
  369. make_iterator_property_map(
  370. orig2copy.begin(), get(vertex_index, g_in), orig2copy[0]),
  371. get(vertex_index, g_in));
  372. }
  373. template < typename VertexListGraph, typename MutableGraph, class P, class T,
  374. class R >
  375. void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out,
  376. const bgl_named_params< P, T, R >& params)
  377. {
  378. typename std::vector< T >::size_type n;
  379. n = is_default_param(get_param(params, orig_to_copy_t()))
  380. ? num_vertices(g_in)
  381. : 1;
  382. if (n == 0)
  383. return;
  384. std::vector<
  385. BOOST_DEDUCED_TYPENAME graph_traits< MutableGraph >::vertex_descriptor >
  386. orig2copy(n);
  387. typedef
  388. typename detail::choose_graph_copy< VertexListGraph >::type copy_impl;
  389. copy_impl::apply(g_in, g_out,
  390. detail::choose_vertex_copier(
  391. get_param(params, vertex_copy_t()), g_in, g_out),
  392. detail::choose_edge_copier(
  393. get_param(params, edge_copy_t()), g_in, g_out),
  394. choose_param(get_param(params, orig_to_copy_t()),
  395. make_iterator_property_map(orig2copy.begin(),
  396. choose_const_pmap(
  397. get_param(params, vertex_index), g_in, vertex_index),
  398. orig2copy[0])),
  399. choose_const_pmap(get_param(params, vertex_index), g_in, vertex_index));
  400. }
  401. namespace detail
  402. {
  403. template < class NewGraph, class Copy2OrigIndexMap, class CopyVertex,
  404. class CopyEdge >
  405. struct graph_copy_visitor : public bfs_visitor<>
  406. {
  407. graph_copy_visitor(
  408. NewGraph& graph, Copy2OrigIndexMap c, CopyVertex cv, CopyEdge ce)
  409. : g_out(graph), orig2copy(c), copy_vertex(cv), copy_edge(ce)
  410. {
  411. }
  412. template < class Vertex >
  413. typename graph_traits< NewGraph >::vertex_descriptor copy_one_vertex(
  414. Vertex u) const
  415. {
  416. typename graph_traits< NewGraph >::vertex_descriptor new_u
  417. = add_vertex(g_out);
  418. put(orig2copy, u, new_u);
  419. copy_vertex(u, new_u);
  420. return new_u;
  421. }
  422. template < class Edge, class Graph >
  423. void tree_edge(Edge e, const Graph& g_in) const
  424. {
  425. // For a tree edge, the target vertex has not been copied yet.
  426. typename graph_traits< NewGraph >::edge_descriptor new_e;
  427. bool inserted;
  428. boost::tie(new_e, inserted)
  429. = add_edge(get(orig2copy, source(e, g_in)),
  430. this->copy_one_vertex(target(e, g_in)), g_out);
  431. copy_edge(e, new_e);
  432. }
  433. template < class Edge, class Graph >
  434. void non_tree_edge(Edge e, const Graph& g_in) const
  435. {
  436. // For a non-tree edge, the target vertex has already been copied.
  437. typename graph_traits< NewGraph >::edge_descriptor new_e;
  438. bool inserted;
  439. boost::tie(new_e, inserted)
  440. = add_edge(get(orig2copy, source(e, g_in)),
  441. get(orig2copy, target(e, g_in)), g_out);
  442. copy_edge(e, new_e);
  443. }
  444. private:
  445. NewGraph& g_out;
  446. Copy2OrigIndexMap orig2copy;
  447. CopyVertex copy_vertex;
  448. CopyEdge copy_edge;
  449. };
  450. template < typename Graph, typename MutableGraph, typename CopyVertex,
  451. typename CopyEdge, typename Orig2CopyVertexIndexMap, typename Params >
  452. typename graph_traits< MutableGraph >::vertex_descriptor
  453. copy_component_impl(const Graph& g_in,
  454. typename graph_traits< Graph >::vertex_descriptor src,
  455. MutableGraph& g_out, CopyVertex copy_vertex, CopyEdge copy_edge,
  456. Orig2CopyVertexIndexMap orig2copy, const Params& params)
  457. {
  458. graph_copy_visitor< MutableGraph, Orig2CopyVertexIndexMap, CopyVertex,
  459. CopyEdge >
  460. vis(g_out, orig2copy, copy_vertex, copy_edge);
  461. typename graph_traits< MutableGraph >::vertex_descriptor src_copy
  462. = vis.copy_one_vertex(src);
  463. breadth_first_search(g_in, src, params.visitor(vis));
  464. return src_copy;
  465. }
  466. } // namespace detail
  467. // Copy all the vertices and edges of graph g_in that are reachable
  468. // from the source vertex into graph g_out. Return the vertex
  469. // in g_out that matches the source vertex of g_in.
  470. template < typename IncidenceGraph, typename MutableGraph, typename P,
  471. typename T, typename R >
  472. typename graph_traits< MutableGraph >::vertex_descriptor copy_component(
  473. IncidenceGraph& g_in,
  474. typename graph_traits< IncidenceGraph >::vertex_descriptor src,
  475. MutableGraph& g_out, const bgl_named_params< P, T, R >& params)
  476. {
  477. typename std::vector< T >::size_type n;
  478. n = is_default_param(get_param(params, orig_to_copy_t()))
  479. ? num_vertices(g_in)
  480. : 1;
  481. std::vector< typename graph_traits< IncidenceGraph >::vertex_descriptor >
  482. orig2copy(n);
  483. return detail::copy_component_impl(g_in, src, g_out,
  484. detail::choose_vertex_copier(
  485. get_param(params, vertex_copy_t()), g_in, g_out),
  486. detail::choose_edge_copier(
  487. get_param(params, edge_copy_t()), g_in, g_out),
  488. choose_param(get_param(params, orig_to_copy_t()),
  489. make_iterator_property_map(orig2copy.begin(),
  490. choose_pmap(
  491. get_param(params, vertex_index), g_in, vertex_index),
  492. orig2copy[0])),
  493. params);
  494. }
  495. template < typename IncidenceGraph, typename MutableGraph >
  496. typename graph_traits< MutableGraph >::vertex_descriptor copy_component(
  497. IncidenceGraph& g_in,
  498. typename graph_traits< IncidenceGraph >::vertex_descriptor src,
  499. MutableGraph& g_out)
  500. {
  501. std::vector< typename graph_traits< IncidenceGraph >::vertex_descriptor >
  502. orig2copy(num_vertices(g_in));
  503. return detail::copy_component_impl(g_in, src, g_out,
  504. make_vertex_copier(g_in, g_out), make_edge_copier(g_in, g_out),
  505. make_iterator_property_map(
  506. orig2copy.begin(), get(vertex_index, g_in), orig2copy[0]),
  507. bgl_named_params< char, char >('x') // dummy param object
  508. );
  509. }
  510. } // namespace boost
  511. #endif // BOOST_GRAPH_COPY_HPP