annotate DEPENDENCIES/generic/include/boost/graph/planar_detail/face_iterators.hpp @ 118:770eb830ec19 emscripten

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