/Src/Dependencies/Boost/boost/graph/copy.hpp

http://hadesmem.googlecode.com/ · C++ Header · 465 lines · 377 code · 39 blank · 49 comment · 23 complexity · 97aa464838b7c9d43b8749de3c6611db MD5 · raw file

  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. typename graph_traits<NewGraph>::vertex_descriptor copy_one_vertex(Vertex u) 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. return new_u;
  325. }
  326. template <class Edge, class Graph>
  327. void tree_edge(Edge e, const Graph& g_in) const {
  328. // For a tree edge, the target vertex has not been copied yet.
  329. typename graph_traits<NewGraph>::edge_descriptor new_e;
  330. bool inserted;
  331. boost::tie(new_e, inserted) = add_edge(get(orig2copy, source(e, g_in)),
  332. this->copy_one_vertex(target(e, g_in)),
  333. g_out);
  334. copy_edge(e, new_e);
  335. }
  336. template <class Edge, class Graph>
  337. void non_tree_edge(Edge e, const Graph& g_in) const {
  338. // For a non-tree edge, the target vertex has already been copied.
  339. typename graph_traits<NewGraph>::edge_descriptor new_e;
  340. bool inserted;
  341. boost::tie(new_e, inserted) = add_edge(get(orig2copy, source(e, g_in)),
  342. get(orig2copy, target(e, g_in)),
  343. g_out);
  344. copy_edge(e, new_e);
  345. }
  346. private:
  347. NewGraph& g_out;
  348. Copy2OrigIndexMap orig2copy;
  349. CopyVertex copy_vertex;
  350. CopyEdge copy_edge;
  351. };
  352. template <typename Graph, typename MutableGraph,
  353. typename CopyVertex, typename CopyEdge,
  354. typename Orig2CopyVertexIndexMap, typename Params>
  355. typename graph_traits<MutableGraph>::vertex_descriptor
  356. copy_component_impl
  357. (const Graph& g_in,
  358. typename graph_traits<Graph>::vertex_descriptor src,
  359. MutableGraph& g_out,
  360. CopyVertex copy_vertex, CopyEdge copy_edge,
  361. Orig2CopyVertexIndexMap orig2copy,
  362. const Params& params)
  363. {
  364. graph_copy_visitor<MutableGraph, Orig2CopyVertexIndexMap,
  365. CopyVertex, CopyEdge> vis(g_out, orig2copy, copy_vertex, copy_edge);
  366. typename graph_traits<MutableGraph>::vertex_descriptor src_copy
  367. = vis.copy_one_vertex(src);
  368. breadth_first_search(g_in, src, params.visitor(vis));
  369. return src_copy;
  370. }
  371. } // namespace detail
  372. // Copy all the vertices and edges of graph g_in that are reachable
  373. // from the source vertex into graph g_out. Return the vertex
  374. // in g_out that matches the source vertex of g_in.
  375. template <typename IncidenceGraph, typename MutableGraph,
  376. typename P, typename T, typename R>
  377. typename graph_traits<MutableGraph>::vertex_descriptor
  378. copy_component(IncidenceGraph& g_in,
  379. typename graph_traits<IncidenceGraph>::vertex_descriptor src,
  380. MutableGraph& g_out,
  381. const bgl_named_params<P, T, R>& params)
  382. {
  383. typename std::vector<T>::size_type n;
  384. n = is_default_param(get_param(params, orig_to_copy_t()))
  385. ? num_vertices(g_in) : 1;
  386. std::vector<typename graph_traits<IncidenceGraph>::vertex_descriptor>
  387. orig2copy(n);
  388. return detail::copy_component_impl
  389. (g_in, src, g_out,
  390. detail::choose_vertex_copier(get_param(params, vertex_copy_t()),
  391. g_in, g_out),
  392. detail::choose_edge_copier(get_param(params, edge_copy_t()),
  393. g_in, g_out),
  394. choose_param(get_param(params, orig_to_copy_t()),
  395. make_iterator_property_map
  396. (orig2copy.begin(),
  397. choose_pmap(get_param(params, vertex_index),
  398. g_in, vertex_index), orig2copy[0])),
  399. params
  400. );
  401. }
  402. template <typename IncidenceGraph, typename MutableGraph>
  403. typename graph_traits<MutableGraph>::vertex_descriptor
  404. copy_component(IncidenceGraph& g_in,
  405. typename graph_traits<IncidenceGraph>::vertex_descriptor src,
  406. MutableGraph& g_out)
  407. {
  408. std::vector<typename graph_traits<IncidenceGraph>::vertex_descriptor>
  409. orig2copy(num_vertices(g_in));
  410. return detail::copy_component_impl
  411. (g_in, src, g_out,
  412. make_vertex_copier(g_in, g_out),
  413. make_edge_copier(g_in, g_out),
  414. make_iterator_property_map(orig2copy.begin(),
  415. get(vertex_index, g_in), orig2copy[0]),
  416. bgl_named_params<char,char>('x') // dummy param object
  417. );
  418. }
  419. } // namespace boost
  420. #endif // BOOST_GRAPH_COPY_HPP