copy.hpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  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/property_map/property_map.hpp>
  38. #include <boost/graph/named_function_params.hpp>
  39. #include <boost/graph/breadth_first_search.hpp>
  40. #include <boost/type_traits/conversion_traits.hpp>
  41. namespace boost {
  42. namespace detail {
  43. // Default edge and vertex property copiers
  44. template <typename Graph1, typename Graph2>
  45. struct edge_copier {
  46. edge_copier(const Graph1& g1, Graph2& g2)
  47. : edge_all_map1(get(edge_all, g1)),
  48. edge_all_map2(get(edge_all, g2)) { }
  49. template <typename Edge1, typename Edge2>
  50. void operator()(const Edge1& e1, Edge2& e2) const {
  51. put(edge_all_map2, e2, get(edge_all_map1, e1));
  52. }
  53. typename property_map<Graph1, edge_all_t>::const_type edge_all_map1;
  54. mutable typename property_map<Graph2, edge_all_t>::type edge_all_map2;
  55. };
  56. template <typename Graph1, typename Graph2>
  57. inline edge_copier<Graph1,Graph2>
  58. make_edge_copier(const Graph1& g1, Graph2& g2)
  59. {
  60. return edge_copier<Graph1,Graph2>(g1, g2);
  61. }
  62. template <typename Graph1, typename Graph2>
  63. struct vertex_copier {
  64. vertex_copier(const Graph1& g1, Graph2& g2)
  65. : vertex_all_map1(get(vertex_all, g1)),
  66. vertex_all_map2(get(vertex_all, g2)) { }
  67. template <typename Vertex1, typename Vertex2>
  68. void operator()(const Vertex1& v1, Vertex2& v2) const {
  69. put(vertex_all_map2, v2, get(vertex_all_map1, v1));
  70. }
  71. typename property_map<Graph1, vertex_all_t>::const_type vertex_all_map1;
  72. mutable typename property_map<Graph2, vertex_all_t>::type
  73. vertex_all_map2;
  74. };
  75. template <typename Graph1, typename Graph2>
  76. inline vertex_copier<Graph1,Graph2>
  77. make_vertex_copier(const Graph1& g1, Graph2& g2)
  78. {
  79. return vertex_copier<Graph1,Graph2>(g1, g2);
  80. }
  81. // Copy all the vertices and edges of graph g_in into graph g_out.
  82. // The copy_vertex and copy_edge function objects control how vertex
  83. // and edge properties are copied.
  84. template <int Version>
  85. struct copy_graph_impl { };
  86. template <> struct copy_graph_impl<0>
  87. {
  88. template <typename Graph, typename MutableGraph,
  89. typename CopyVertex, typename CopyEdge, typename IndexMap,
  90. typename Orig2CopyVertexIndexMap>
  91. static void apply(const Graph& g_in, MutableGraph& g_out,
  92. CopyVertex copy_vertex, CopyEdge copy_edge,
  93. Orig2CopyVertexIndexMap orig2copy, IndexMap)
  94. {
  95. typename graph_traits<Graph>::vertex_iterator vi, vi_end;
  96. for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
  97. typename graph_traits<MutableGraph>::vertex_descriptor
  98. new_v = add_vertex(g_out);
  99. put(orig2copy, *vi, new_v);
  100. copy_vertex(*vi, new_v);
  101. }
  102. typename graph_traits<Graph>::edge_iterator ei, ei_end;
  103. for (boost::tie(ei, ei_end) = edges(g_in); ei != ei_end; ++ei) {
  104. typename graph_traits<MutableGraph>::edge_descriptor new_e;
  105. bool inserted;
  106. boost::tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei, g_in)),
  107. get(orig2copy, target(*ei, g_in)),
  108. g_out);
  109. copy_edge(*ei, new_e);
  110. }
  111. }
  112. };
  113. // for directed graphs
  114. template <> struct copy_graph_impl<1>
  115. {
  116. template <typename Graph, typename MutableGraph,
  117. typename CopyVertex, typename CopyEdge, typename IndexMap,
  118. typename Orig2CopyVertexIndexMap>
  119. static void apply(const Graph& g_in, MutableGraph& g_out,
  120. CopyVertex copy_vertex, CopyEdge copy_edge,
  121. Orig2CopyVertexIndexMap orig2copy, IndexMap)
  122. {
  123. typename graph_traits<Graph>::vertex_iterator vi, vi_end;
  124. for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
  125. typename graph_traits<MutableGraph>::vertex_descriptor
  126. new_v = add_vertex(g_out);
  127. put(orig2copy, *vi, new_v);
  128. copy_vertex(*vi, new_v);
  129. }
  130. for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
  131. typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
  132. for (boost::tie(ei, ei_end) = out_edges(*vi, g_in); ei != ei_end; ++ei) {
  133. typename graph_traits<MutableGraph>::edge_descriptor new_e;
  134. bool inserted;
  135. boost::tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei, g_in)),
  136. get(orig2copy, target(*ei, g_in)),
  137. g_out);
  138. copy_edge(*ei, new_e);
  139. }
  140. }
  141. }
  142. };
  143. // for undirected graphs
  144. template <> struct copy_graph_impl<2>
  145. {
  146. template <typename Graph, typename MutableGraph,
  147. typename CopyVertex, typename CopyEdge, typename IndexMap,
  148. typename Orig2CopyVertexIndexMap>
  149. static void apply(const Graph& g_in, MutableGraph& g_out,
  150. CopyVertex copy_vertex, CopyEdge copy_edge,
  151. Orig2CopyVertexIndexMap orig2copy,
  152. IndexMap index_map)
  153. {
  154. typedef color_traits<default_color_type> Color;
  155. std::vector<default_color_type>
  156. color(num_vertices(g_in), Color::white());
  157. typename graph_traits<Graph>::vertex_iterator vi, vi_end;
  158. for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
  159. typename graph_traits<MutableGraph>::vertex_descriptor
  160. new_v = add_vertex(g_out);
  161. put(orig2copy, *vi, new_v);
  162. copy_vertex(*vi, new_v);
  163. }
  164. for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
  165. typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
  166. for (boost::tie(ei, ei_end) = out_edges(*vi, g_in); ei != ei_end; ++ei) {
  167. typename graph_traits<MutableGraph>::edge_descriptor new_e;
  168. bool inserted;
  169. if (color[get(index_map, target(*ei, g_in))] == Color::white()) {
  170. boost::tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei,g_in)),
  171. get(orig2copy, target(*ei,g_in)),
  172. g_out);
  173. copy_edge(*ei, new_e);
  174. }
  175. }
  176. color[get(index_map, *vi)] = Color::black();
  177. }
  178. }
  179. };
  180. template <class Graph>
  181. struct choose_graph_copy {
  182. typedef typename Graph::traversal_category Trv;
  183. typedef typename Graph::directed_category Dr;
  184. enum { algo =
  185. (is_convertible<Trv, vertex_list_graph_tag>::value
  186. && is_convertible<Trv, edge_list_graph_tag>::value)
  187. ? 0 : is_convertible<Dr, directed_tag>::value ? 1 : 2 };
  188. typedef copy_graph_impl<algo> type;
  189. };
  190. //-------------------------------------------------------------------------
  191. struct choose_copier_parameter {
  192. template <class P, class G1, class G2>
  193. struct bind_ {
  194. typedef const P& result_type;
  195. static result_type apply(const P& p, const G1&, G2&)
  196. { return p; }
  197. };
  198. };
  199. struct choose_default_edge_copier {
  200. template <class P, class G1, class G2>
  201. struct bind_ {
  202. typedef edge_copier<G1, G2> result_type;
  203. static result_type apply(const P&, const G1& g1, G2& g2) {
  204. return result_type(g1, g2);
  205. }
  206. };
  207. };
  208. template <class Param>
  209. struct choose_edge_copy {
  210. typedef choose_copier_parameter type;
  211. };
  212. template <>
  213. struct choose_edge_copy<detail::error_property_not_found> {
  214. typedef choose_default_edge_copier type;
  215. };
  216. template <class Param, class G1, class G2>
  217. struct choose_edge_copier_helper {
  218. typedef typename choose_edge_copy<Param>::type Selector;
  219. typedef typename Selector:: template bind_<Param, G1, G2> Bind;
  220. typedef Bind type;
  221. typedef typename Bind::result_type result_type;
  222. };
  223. template <typename Param, typename G1, typename G2>
  224. typename detail::choose_edge_copier_helper<Param,G1,G2>::result_type
  225. choose_edge_copier(const Param& params, const G1& g_in, G2& g_out)
  226. {
  227. typedef typename
  228. detail::choose_edge_copier_helper<Param,G1,G2>::type Choice;
  229. return Choice::apply(params, g_in, g_out);
  230. }
  231. struct choose_default_vertex_copier {
  232. template <class P, class G1, class G2>
  233. struct bind_ {
  234. typedef vertex_copier<G1, G2> result_type;
  235. static result_type apply(const P&, const G1& g1, G2& g2) {
  236. return result_type(g1, g2);
  237. }
  238. };
  239. };
  240. template <class Param>
  241. struct choose_vertex_copy {
  242. typedef choose_copier_parameter type;
  243. };
  244. template <>
  245. struct choose_vertex_copy<detail::error_property_not_found> {
  246. typedef choose_default_vertex_copier type;
  247. };
  248. template <class Param, class G1, class G2>
  249. struct choose_vertex_copier_helper {
  250. typedef typename choose_vertex_copy<Param>::type Selector;
  251. typedef typename Selector:: template bind_<Param, G1, G2> Bind;
  252. typedef Bind type;
  253. typedef typename Bind::result_type result_type;
  254. };
  255. template <typename Param, typename G1, typename G2>
  256. typename detail::choose_vertex_copier_helper<Param,G1,G2>::result_type
  257. choose_vertex_copier(const Param& params, const G1& g_in, G2& g_out)
  258. {
  259. typedef typename
  260. detail::choose_vertex_copier_helper<Param,G1,G2>::type Choice;
  261. return Choice::apply(params, g_in, g_out);
  262. }
  263. } // namespace detail
  264. template <typename VertexListGraph, typename MutableGraph>
  265. void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out)
  266. {
  267. if (num_vertices(g_in) == 0)
  268. return;
  269. typedef typename graph_traits<MutableGraph>::vertex_descriptor vertex_t;
  270. std::vector<vertex_t> orig2copy(num_vertices(g_in));
  271. typedef typename detail::choose_graph_copy<VertexListGraph>::type
  272. copy_impl;
  273. copy_impl::apply
  274. (g_in, g_out,
  275. detail::make_vertex_copier(g_in, g_out),
  276. detail::make_edge_copier(g_in, g_out),
  277. make_iterator_property_map(orig2copy.begin(),
  278. get(vertex_index, g_in), orig2copy[0]),
  279. get(vertex_index, g_in)
  280. );
  281. }
  282. template <typename VertexListGraph, typename MutableGraph,
  283. class P, class T, class R>
  284. void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out,
  285. const bgl_named_params<P, T, R>& params)
  286. {
  287. typename std::vector<T>::size_type n;
  288. n = is_default_param(get_param(params, orig_to_copy_t()))
  289. ? num_vertices(g_in) : 1;
  290. if (n == 0)
  291. return;
  292. std::vector<BOOST_DEDUCED_TYPENAME graph_traits<MutableGraph>::vertex_descriptor>
  293. orig2copy(n);
  294. typedef typename detail::choose_graph_copy<VertexListGraph>::type
  295. copy_impl;
  296. copy_impl::apply
  297. (g_in, g_out,
  298. detail::choose_vertex_copier(get_param(params, vertex_copy_t()),
  299. g_in, g_out),
  300. detail::choose_edge_copier(get_param(params, edge_copy_t()),
  301. g_in, g_out),
  302. choose_param(get_param(params, orig_to_copy_t()),
  303. make_iterator_property_map
  304. (orig2copy.begin(),
  305. choose_const_pmap(get_param(params, vertex_index),
  306. g_in, vertex_index), orig2copy[0])),
  307. choose_const_pmap(get_param(params, vertex_index), g_in, vertex_index)
  308. );
  309. }
  310. namespace detail {
  311. template <class NewGraph, class Copy2OrigIndexMap,
  312. class CopyVertex, class CopyEdge>
  313. struct graph_copy_visitor : public bfs_visitor<>
  314. {
  315. graph_copy_visitor(NewGraph& graph, Copy2OrigIndexMap c,
  316. CopyVertex cv, CopyEdge ce)
  317. : g_out(graph), orig2copy(c), copy_vertex(cv), copy_edge(ce) { }
  318. template <class Vertex, class Graph>
  319. void examine_vertex(Vertex u, const Graph& g_in) const {
  320. typename graph_traits<NewGraph>::vertex_descriptor
  321. new_u = add_vertex(g_out);
  322. put(orig2copy, u, new_u);
  323. copy_vertex(u, new_u);
  324. }
  325. template <class Edge, class Graph>
  326. void examine_edge(Edge e, const Graph& g_in) const {
  327. typename graph_traits<NewGraph>::edge_descriptor new_e;
  328. bool inserted;
  329. boost::tie(new_e, inserted) = add_edge(get(orig2copy, source(e, g_in)),
  330. get(orig2copy, target(e, g_in)),
  331. g_out);
  332. copy_edge(e, new_e);
  333. }
  334. private:
  335. NewGraph& g_out;
  336. Copy2OrigIndexMap orig2copy;
  337. CopyVertex copy_vertex;
  338. CopyEdge copy_edge;
  339. };
  340. template <typename Graph, typename MutableGraph,
  341. typename CopyVertex, typename CopyEdge,
  342. typename Orig2CopyVertexIndexMap, typename Params>
  343. typename graph_traits<MutableGraph>::vertex_descriptor
  344. copy_component_impl
  345. (const Graph& g_in,
  346. typename graph_traits<Graph>::vertex_descriptor src,
  347. MutableGraph& g_out,
  348. CopyVertex copy_vertex, CopyEdge copy_edge,
  349. Orig2CopyVertexIndexMap orig2copy,
  350. const Params& params)
  351. {
  352. graph_copy_visitor<MutableGraph, Orig2CopyVertexIndexMap,
  353. CopyVertex, CopyEdge> vis(g_out, orig2copy, copy_vertex, copy_edge);
  354. breadth_first_search(g_in, src, params.visitor(vis));
  355. return get(orig2copy, src);
  356. }
  357. } // namespace detail
  358. // Copy all the vertices and edges of graph g_in that are reachable
  359. // from the source vertex into graph g_out. Return the vertex
  360. // in g_out that matches the source vertex of g_in.
  361. template <typename IncidenceGraph, typename MutableGraph,
  362. typename P, typename T, typename R>
  363. typename graph_traits<MutableGraph>::vertex_descriptor
  364. copy_component(IncidenceGraph& g_in,
  365. typename graph_traits<IncidenceGraph>::vertex_descriptor src,
  366. MutableGraph& g_out,
  367. const bgl_named_params<P, T, R>& params)
  368. {
  369. typename std::vector<T>::size_type n;
  370. n = is_default_param(get_param(params, orig_to_copy_t()))
  371. ? num_vertices(g_in) : 1;
  372. std::vector<typename graph_traits<IncidenceGraph>::vertex_descriptor>
  373. orig2copy(n);
  374. return detail::copy_component_impl
  375. (g_in, src, g_out,
  376. detail::choose_vertex_copier(get_param(params, vertex_copy_t()),
  377. g_in, g_out),
  378. detail::choose_edge_copier(get_param(params, edge_copy_t()),
  379. g_in, g_out),
  380. choose_param(get_param(params, orig_to_copy_t()),
  381. make_iterator_property_map
  382. (orig2copy.begin(),
  383. choose_pmap(get_param(params, vertex_index),
  384. g_in, vertex_index), orig2copy[0])),
  385. params
  386. );
  387. }
  388. template <typename IncidenceGraph, typename MutableGraph>
  389. typename graph_traits<MutableGraph>::vertex_descriptor
  390. copy_component(IncidenceGraph& g_in,
  391. typename graph_traits<IncidenceGraph>::vertex_descriptor src,
  392. MutableGraph& g_out)
  393. {
  394. std::vector<typename graph_traits<IncidenceGraph>::vertex_descriptor>
  395. orig2copy(num_vertices(g_in));
  396. return detail::copy_component_impl
  397. (g_in, src, g_out,
  398. make_vertex_copier(g_in, g_out),
  399. make_edge_copier(g_in, g_out),
  400. make_iterator_property_map(orig2copy.begin(),
  401. get(vertex_index, g_in), orig2copy[0]),
  402. bgl_named_params<char,char>('x') // dummy param object
  403. );
  404. }
  405. } // namespace boost
  406. #endif // BOOST_GRAPH_COPY_HPP