face_iterators.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. //=======================================================================
  2. // Copyright (c) Aaron Windsor 2007
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //=======================================================================
  8. #ifndef __FACE_ITERATORS_HPP__
  9. #define __FACE_ITERATORS_HPP__
  10. #include <boost/iterator/iterator_facade.hpp>
  11. #include <boost/mpl/bool.hpp>
  12. #include <boost/graph/graph_traits.hpp>
  13. namespace boost
  14. {
  15. //tags for defining traversal properties
  16. //VisitorType
  17. struct lead_visitor {};
  18. struct follow_visitor {};
  19. //TraversalType
  20. struct single_side {};
  21. struct both_sides {};
  22. //TraversalSubType
  23. struct first_side {}; //for single_side
  24. struct second_side {}; //for single_side
  25. struct alternating {}; //for both_sides
  26. //Time
  27. struct current_iteration {};
  28. struct previous_iteration {};
  29. // Why TraversalType AND TraversalSubType? TraversalSubType is a function
  30. // template parameter passed in to the constructor of the face iterator,
  31. // whereas TraversalType is a class template parameter. This lets us decide
  32. // at runtime whether to move along the first or second side of a bicomp (by
  33. // assigning a face_iterator that has been constructed with TraversalSubType
  34. // = first_side or second_side to a face_iterator variable) without any of
  35. // the virtual function overhead that comes with implementing this
  36. // functionality as a more structured form of type erasure. It also allows
  37. // a single face_iterator to be the end iterator of two iterators traversing
  38. // both sides of a bicomp.
  39. //ValueType is either graph_traits<Graph>::vertex_descriptor
  40. //or graph_traits<Graph>::edge_descriptor
  41. //forward declaration (defining defaults)
  42. template <typename Graph,
  43. typename FaceHandlesMap,
  44. typename ValueType,
  45. typename BicompSideToTraverse = single_side,
  46. typename VisitorType = lead_visitor,
  47. typename Time = current_iteration
  48. >
  49. class face_iterator;
  50. template <typename Graph, bool StoreEdge>
  51. struct edge_storage
  52. {};
  53. template <typename Graph>
  54. struct edge_storage <Graph, true>
  55. {
  56. typename graph_traits<Graph>::edge_descriptor value;
  57. };
  58. //specialization for TraversalType = traverse_vertices
  59. template <typename Graph,
  60. typename FaceHandlesMap,
  61. typename ValueType,
  62. typename TraversalType,
  63. typename VisitorType,
  64. typename Time
  65. >
  66. class face_iterator
  67. : public boost::iterator_facade < face_iterator<Graph,
  68. FaceHandlesMap,
  69. ValueType,
  70. TraversalType,
  71. VisitorType,
  72. Time
  73. >,
  74. ValueType,
  75. boost::forward_traversal_tag,
  76. ValueType
  77. >
  78. {
  79. public:
  80. typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
  81. typedef typename graph_traits<Graph>::edge_descriptor edge_t;
  82. typedef face_iterator
  83. <Graph,FaceHandlesMap,ValueType,TraversalType,VisitorType,Time> self;
  84. typedef typename FaceHandlesMap::value_type face_handle_t;
  85. face_iterator() :
  86. m_lead(graph_traits<Graph>::null_vertex()),
  87. m_follow(graph_traits<Graph>::null_vertex())
  88. {}
  89. template <typename TraversalSubType>
  90. face_iterator(face_handle_t anchor_handle,
  91. FaceHandlesMap face_handles,
  92. TraversalSubType traversal_type):
  93. m_follow(anchor_handle.get_anchor()),
  94. m_face_handles(face_handles)
  95. {
  96. set_lead_dispatch(anchor_handle, traversal_type);
  97. }
  98. template <typename TraversalSubType>
  99. face_iterator(vertex_t anchor,
  100. FaceHandlesMap face_handles,
  101. TraversalSubType traversal_type):
  102. m_follow(anchor),
  103. m_face_handles(face_handles)
  104. {
  105. set_lead_dispatch(m_face_handles[anchor], traversal_type);
  106. }
  107. private:
  108. friend class boost::iterator_core_access;
  109. inline vertex_t get_first_vertex(face_handle_t anchor_handle,
  110. current_iteration
  111. )
  112. {
  113. return anchor_handle.first_vertex();
  114. }
  115. inline vertex_t get_second_vertex(face_handle_t anchor_handle,
  116. current_iteration
  117. )
  118. {
  119. return anchor_handle.second_vertex();
  120. }
  121. inline vertex_t get_first_vertex(face_handle_t anchor_handle,
  122. previous_iteration
  123. )
  124. {
  125. return anchor_handle.old_first_vertex();
  126. }
  127. inline vertex_t get_second_vertex(face_handle_t anchor_handle,
  128. previous_iteration
  129. )
  130. {
  131. return anchor_handle.old_second_vertex();
  132. }
  133. inline void set_lead_dispatch(face_handle_t anchor_handle, first_side)
  134. {
  135. m_lead = get_first_vertex(anchor_handle, Time());
  136. set_edge_to_first_dispatch(anchor_handle, ValueType(), Time());
  137. }
  138. inline void set_lead_dispatch(face_handle_t anchor_handle, second_side)
  139. {
  140. m_lead = get_second_vertex(anchor_handle, Time());
  141. set_edge_to_second_dispatch(anchor_handle, ValueType(), Time());
  142. }
  143. inline void set_edge_to_first_dispatch(face_handle_t anchor_handle,
  144. edge_t,
  145. current_iteration
  146. )
  147. {
  148. m_edge.value = anchor_handle.first_edge();
  149. }
  150. inline void set_edge_to_second_dispatch(face_handle_t anchor_handle,
  151. edge_t,
  152. current_iteration
  153. )
  154. {
  155. m_edge.value = anchor_handle.second_edge();
  156. }
  157. inline void set_edge_to_first_dispatch(face_handle_t anchor_handle,
  158. edge_t,
  159. previous_iteration
  160. )
  161. {
  162. m_edge.value = anchor_handle.old_first_edge();
  163. }
  164. inline void set_edge_to_second_dispatch(face_handle_t anchor_handle,
  165. edge_t,
  166. previous_iteration
  167. )
  168. {
  169. m_edge.value = anchor_handle.old_second_edge();
  170. }
  171. template<typename T>
  172. inline void set_edge_to_first_dispatch(face_handle_t, vertex_t, T)
  173. {}
  174. template<typename T>
  175. inline void set_edge_to_second_dispatch(face_handle_t, vertex_t, T)
  176. {}
  177. void increment()
  178. {
  179. face_handle_t curr_face_handle(m_face_handles[m_lead]);
  180. vertex_t first = get_first_vertex(curr_face_handle, Time());
  181. vertex_t second = get_second_vertex(curr_face_handle, Time());
  182. if (first == m_follow)
  183. {
  184. m_follow = m_lead;
  185. set_edge_to_second_dispatch(curr_face_handle, ValueType(), Time());
  186. m_lead = second;
  187. }
  188. else if (second == m_follow)
  189. {
  190. m_follow = m_lead;
  191. set_edge_to_first_dispatch(curr_face_handle, ValueType(), Time());
  192. m_lead = first;
  193. }
  194. else
  195. m_lead = m_follow = graph_traits<Graph>::null_vertex();
  196. }
  197. bool equal(self const& other) const
  198. {
  199. return m_lead == other.m_lead && m_follow == other.m_follow;
  200. }
  201. ValueType dereference() const
  202. {
  203. return dereference_dispatch(VisitorType(), ValueType());
  204. }
  205. inline ValueType dereference_dispatch(lead_visitor, vertex_t) const
  206. { return m_lead; }
  207. inline ValueType dereference_dispatch(follow_visitor, vertex_t) const
  208. { return m_follow; }
  209. inline ValueType dereference_dispatch(lead_visitor, edge_t) const
  210. { return m_edge.value; }
  211. inline ValueType dereference_dispatch(follow_visitor, edge_t) const
  212. { return m_edge.value; }
  213. vertex_t m_lead;
  214. vertex_t m_follow;
  215. edge_storage<Graph, boost::is_same<ValueType, edge_t>::value > m_edge;
  216. FaceHandlesMap m_face_handles;
  217. };
  218. template <typename Graph,
  219. typename FaceHandlesMap,
  220. typename ValueType,
  221. typename VisitorType,
  222. typename Time
  223. >
  224. class face_iterator
  225. <Graph, FaceHandlesMap, ValueType, both_sides, VisitorType, Time>
  226. : public boost::iterator_facade< face_iterator<Graph,
  227. FaceHandlesMap,
  228. ValueType,
  229. both_sides,
  230. VisitorType,
  231. Time>,
  232. ValueType,
  233. boost::forward_traversal_tag,
  234. ValueType >
  235. {
  236. public:
  237. typedef face_iterator
  238. <Graph,FaceHandlesMap,ValueType,both_sides,VisitorType,Time> self;
  239. typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
  240. typedef typename FaceHandlesMap::value_type face_handle_t;
  241. face_iterator() {}
  242. face_iterator(face_handle_t anchor_handle, FaceHandlesMap face_handles):
  243. first_itr(anchor_handle, face_handles, first_side()),
  244. second_itr(anchor_handle, face_handles, second_side()),
  245. first_is_active(true),
  246. first_increment(true)
  247. {}
  248. face_iterator(vertex_t anchor, FaceHandlesMap face_handles):
  249. first_itr(face_handles[anchor], face_handles, first_side()),
  250. second_itr(face_handles[anchor], face_handles, second_side()),
  251. first_is_active(true),
  252. first_increment(true)
  253. {}
  254. private:
  255. friend class boost::iterator_core_access;
  256. typedef face_iterator
  257. <Graph, FaceHandlesMap, ValueType, single_side, follow_visitor, Time>
  258. inner_itr_t;
  259. void increment()
  260. {
  261. if (first_increment)
  262. {
  263. ++first_itr;
  264. ++second_itr;
  265. first_increment = false;
  266. }
  267. else if (first_is_active)
  268. ++first_itr;
  269. else
  270. ++second_itr;
  271. first_is_active = !first_is_active;
  272. }
  273. bool equal(self const& other) const
  274. {
  275. //Want this iterator to be equal to the "end" iterator when at least
  276. //one of the iterators has reached the root of the current bicomp.
  277. //This isn't ideal, but it works.
  278. return (first_itr == other.first_itr || second_itr == other.second_itr);
  279. }
  280. ValueType dereference() const
  281. {
  282. return first_is_active ? *first_itr : *second_itr;
  283. }
  284. inner_itr_t first_itr;
  285. inner_itr_t second_itr;
  286. inner_itr_t face_end;
  287. bool first_is_active;
  288. bool first_increment;
  289. };
  290. } /* namespace boost */
  291. #endif //__FACE_ITERATORS_HPP__