visitors.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  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. // Revision History:
  11. // 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
  12. //
  13. #ifndef BOOST_GRAPH_GRAPH_SEARCH_VISITORS_HPP
  14. #define BOOST_GRAPH_GRAPH_SEARCH_VISITORS_HPP
  15. #include <iosfwd>
  16. #include <boost/config.hpp>
  17. #include <boost/type_traits/is_same.hpp>
  18. #include <boost/mpl/bool.hpp>
  19. #include <boost/property_map/property_map.hpp>
  20. #include <boost/graph/graph_traits.hpp>
  21. #include <boost/limits.hpp>
  22. namespace boost
  23. {
  24. // This is a bit more convenient than std::numeric_limits because
  25. // you don't have to explicitly provide type T.
  26. template < class T > inline T numeric_limits_max(T)
  27. {
  28. return (std::numeric_limits< T >::max)();
  29. }
  30. //========================================================================
  31. // Event Tags
  32. namespace detail
  33. {
  34. // For partial specialization workaround
  35. enum event_visitor_enum
  36. {
  37. on_no_event_num,
  38. on_initialize_vertex_num,
  39. on_start_vertex_num,
  40. on_discover_vertex_num,
  41. on_finish_vertex_num,
  42. on_examine_vertex_num,
  43. on_examine_edge_num,
  44. on_tree_edge_num,
  45. on_non_tree_edge_num,
  46. on_gray_target_num,
  47. on_black_target_num,
  48. on_forward_or_cross_edge_num,
  49. on_back_edge_num,
  50. on_finish_edge_num,
  51. on_edge_relaxed_num,
  52. on_edge_not_relaxed_num,
  53. on_edge_minimized_num,
  54. on_edge_not_minimized_num
  55. };
  56. template < typename Event, typename Visitor >
  57. struct functor_to_visitor : Visitor
  58. {
  59. typedef Event event_filter;
  60. functor_to_visitor(const Visitor& visitor) : Visitor(visitor) {}
  61. };
  62. } // namespace detail
  63. struct on_no_event
  64. {
  65. enum
  66. {
  67. num = detail::on_no_event_num
  68. };
  69. };
  70. struct on_initialize_vertex
  71. {
  72. enum
  73. {
  74. num = detail::on_initialize_vertex_num
  75. };
  76. };
  77. struct on_start_vertex
  78. {
  79. enum
  80. {
  81. num = detail::on_start_vertex_num
  82. };
  83. };
  84. struct on_discover_vertex
  85. {
  86. enum
  87. {
  88. num = detail::on_discover_vertex_num
  89. };
  90. };
  91. struct on_examine_vertex
  92. {
  93. enum
  94. {
  95. num = detail::on_examine_vertex_num
  96. };
  97. };
  98. struct on_finish_vertex
  99. {
  100. enum
  101. {
  102. num = detail::on_finish_vertex_num
  103. };
  104. };
  105. struct on_examine_edge
  106. {
  107. enum
  108. {
  109. num = detail::on_examine_edge_num
  110. };
  111. };
  112. struct on_tree_edge
  113. {
  114. enum
  115. {
  116. num = detail::on_tree_edge_num
  117. };
  118. };
  119. struct on_non_tree_edge
  120. {
  121. enum
  122. {
  123. num = detail::on_non_tree_edge_num
  124. };
  125. };
  126. struct on_gray_target
  127. {
  128. enum
  129. {
  130. num = detail::on_gray_target_num
  131. };
  132. };
  133. struct on_black_target
  134. {
  135. enum
  136. {
  137. num = detail::on_black_target_num
  138. };
  139. };
  140. struct on_forward_or_cross_edge
  141. {
  142. enum
  143. {
  144. num = detail::on_forward_or_cross_edge_num
  145. };
  146. };
  147. struct on_back_edge
  148. {
  149. enum
  150. {
  151. num = detail::on_back_edge_num
  152. };
  153. };
  154. struct on_finish_edge
  155. {
  156. enum
  157. {
  158. num = detail::on_finish_edge_num
  159. };
  160. };
  161. struct on_edge_relaxed
  162. {
  163. enum
  164. {
  165. num = detail::on_edge_relaxed_num
  166. };
  167. };
  168. struct on_edge_not_relaxed
  169. {
  170. enum
  171. {
  172. num = detail::on_edge_not_relaxed_num
  173. };
  174. };
  175. struct on_edge_minimized
  176. {
  177. enum
  178. {
  179. num = detail::on_edge_minimized_num
  180. };
  181. };
  182. struct on_edge_not_minimized
  183. {
  184. enum
  185. {
  186. num = detail::on_edge_not_minimized_num
  187. };
  188. };
  189. //========================================================================
  190. // base_visitor and null_visitor
  191. // needed for MSVC workaround
  192. template < class Visitor > struct base_visitor
  193. {
  194. typedef on_no_event event_filter;
  195. template < class T, class Graph > void operator()(T, Graph&) {}
  196. };
  197. struct null_visitor : public base_visitor< null_visitor >
  198. {
  199. typedef on_no_event event_filter;
  200. template < class T, class Graph > void operator()(T, Graph&) {}
  201. };
  202. //========================================================================
  203. // The invoke_visitors() function
  204. namespace detail
  205. {
  206. template < class Visitor, class T, class Graph >
  207. inline void invoke_dispatch(Visitor& v, T x, Graph& g, mpl::true_)
  208. {
  209. v(x, g);
  210. }
  211. template < class Visitor, class T, class Graph >
  212. inline void invoke_dispatch(Visitor&, T, Graph&, mpl::false_)
  213. {
  214. }
  215. } // namespace detail
  216. template < class Visitor, class Rest, class T, class Graph, class Tag >
  217. inline void invoke_visitors(
  218. std::pair< Visitor, Rest >& vlist, T x, Graph& g, Tag tag)
  219. {
  220. typedef typename Visitor::event_filter Category;
  221. typedef typename is_same< Category, Tag >::type IsSameTag;
  222. detail::invoke_dispatch(vlist.first, x, g, IsSameTag());
  223. invoke_visitors(vlist.second, x, g, tag);
  224. }
  225. template < class Visitor, class T, class Graph, class Tag >
  226. inline void invoke_visitors(Visitor& v, T x, Graph& g, Tag)
  227. {
  228. typedef typename Visitor::event_filter Category;
  229. typedef typename is_same< Category, Tag >::type IsSameTag;
  230. detail::invoke_dispatch(v, x, g, IsSameTag());
  231. }
  232. //========================================================================
  233. // predecessor_recorder
  234. template < class PredecessorMap, class Tag >
  235. struct predecessor_recorder
  236. : public base_visitor< predecessor_recorder< PredecessorMap, Tag > >
  237. {
  238. typedef Tag event_filter;
  239. predecessor_recorder(PredecessorMap pa) : m_predecessor(pa) {}
  240. template < class Edge, class Graph > void operator()(Edge e, const Graph& g)
  241. {
  242. put(m_predecessor, target(e, g), source(e, g));
  243. }
  244. PredecessorMap m_predecessor;
  245. };
  246. template < class PredecessorMap, class Tag >
  247. predecessor_recorder< PredecessorMap, Tag > record_predecessors(
  248. PredecessorMap pa, Tag)
  249. {
  250. return predecessor_recorder< PredecessorMap, Tag >(pa);
  251. }
  252. //========================================================================
  253. // edge_predecessor_recorder
  254. template < class PredEdgeMap, class Tag >
  255. struct edge_predecessor_recorder
  256. : public base_visitor< edge_predecessor_recorder< PredEdgeMap, Tag > >
  257. {
  258. typedef Tag event_filter;
  259. edge_predecessor_recorder(PredEdgeMap pa) : m_predecessor(pa) {}
  260. template < class Edge, class Graph > void operator()(Edge e, const Graph& g)
  261. {
  262. put(m_predecessor, target(e, g), e);
  263. }
  264. PredEdgeMap m_predecessor;
  265. };
  266. template < class PredEdgeMap, class Tag >
  267. edge_predecessor_recorder< PredEdgeMap, Tag > record_edge_predecessors(
  268. PredEdgeMap pa, Tag)
  269. {
  270. return edge_predecessor_recorder< PredEdgeMap, Tag >(pa);
  271. }
  272. //========================================================================
  273. // distance_recorder
  274. template < class DistanceMap, class Tag >
  275. struct distance_recorder
  276. : public base_visitor< distance_recorder< DistanceMap, Tag > >
  277. {
  278. typedef Tag event_filter;
  279. distance_recorder(DistanceMap pa) : m_distance(pa) {}
  280. template < class Edge, class Graph > void operator()(Edge e, const Graph& g)
  281. {
  282. typename graph_traits< Graph >::vertex_descriptor u = source(e, g),
  283. v = target(e, g);
  284. put(m_distance, v, get(m_distance, u) + 1);
  285. }
  286. DistanceMap m_distance;
  287. };
  288. template < class DistanceMap, class Tag >
  289. distance_recorder< DistanceMap, Tag > record_distances(DistanceMap pa, Tag)
  290. {
  291. return distance_recorder< DistanceMap, Tag >(pa);
  292. }
  293. //========================================================================
  294. // time_stamper
  295. template < class TimeMap, class TimeT, class Tag >
  296. struct time_stamper : public base_visitor< time_stamper< TimeMap, TimeT, Tag > >
  297. {
  298. typedef Tag event_filter;
  299. time_stamper(TimeMap pa, TimeT& t) : m_time_pa(pa), m_time(t) {}
  300. template < class Vertex, class Graph >
  301. void operator()(Vertex u, const Graph&)
  302. {
  303. put(m_time_pa, u, ++m_time);
  304. }
  305. TimeMap m_time_pa;
  306. TimeT& m_time;
  307. };
  308. template < class TimeMap, class TimeT, class Tag >
  309. time_stamper< TimeMap, TimeT, Tag > stamp_times(
  310. TimeMap pa, TimeT& time_counter, Tag)
  311. {
  312. return time_stamper< TimeMap, TimeT, Tag >(pa, time_counter);
  313. }
  314. //========================================================================
  315. // property_writer
  316. template < class PA, class OutputIterator, class Tag >
  317. struct property_writer
  318. : public base_visitor< property_writer< PA, OutputIterator, Tag > >
  319. {
  320. typedef Tag event_filter;
  321. property_writer(PA pa, OutputIterator out) : m_pa(pa), m_out(out) {}
  322. template < class T, class Graph > void operator()(T x, Graph&)
  323. {
  324. *m_out++ = get(m_pa, x);
  325. }
  326. PA m_pa;
  327. OutputIterator m_out;
  328. };
  329. template < class PA, class OutputIterator, class Tag >
  330. property_writer< PA, OutputIterator, Tag > write_property(
  331. PA pa, OutputIterator out, Tag)
  332. {
  333. return property_writer< PA, OutputIterator, Tag >(pa, out);
  334. }
  335. //========================================================================
  336. // property_put
  337. /**
  338. * Functor which just sets a given value to a vertex or edge in a property map.
  339. */
  340. template < typename PropertyMap, typename EventTag > struct property_put
  341. {
  342. typedef EventTag event_filter;
  343. property_put(PropertyMap property_map,
  344. typename property_traits< PropertyMap >::value_type value)
  345. : property_map_(property_map), value_(value)
  346. {
  347. }
  348. template < typename VertexOrEdge, typename Graph >
  349. void operator()(VertexOrEdge v, const Graph&)
  350. {
  351. put(property_map_, v, value_);
  352. }
  353. private:
  354. PropertyMap property_map_;
  355. typename property_traits< PropertyMap >::value_type value_;
  356. };
  357. /**
  358. * Creates a property_put functor which just sets a given value to a vertex or
  359. * edge.
  360. *
  361. * @param property_map Given writeable property map
  362. * @param value Fixed value of the map
  363. * @param tag Event Filter
  364. * @return The functor.
  365. */
  366. template < typename PropertyMap, typename EventTag >
  367. inline property_put< PropertyMap, EventTag > put_property(
  368. PropertyMap property_map,
  369. typename property_traits< PropertyMap >::value_type value, EventTag)
  370. {
  371. return property_put< PropertyMap, EventTag >(property_map, value);
  372. }
  373. #define BOOST_GRAPH_EVENT_STUB(Event, Kind) \
  374. typedef ::boost::Event Event##_type; \
  375. template < typename Visitor > \
  376. Kind##_visitor< std::pair< \
  377. detail::functor_to_visitor< Event##_type, Visitor >, Visitors > > \
  378. do_##Event(Visitor visitor) \
  379. { \
  380. typedef std::pair< \
  381. detail::functor_to_visitor< Event##_type, Visitor >, Visitors > \
  382. visitor_list; \
  383. typedef Kind##_visitor< visitor_list > result_type; \
  384. return result_type(visitor_list(visitor, m_vis)); \
  385. }
  386. } /* namespace boost */
  387. #endif