File indexing completed on 2025-01-18 09:37:21
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef __FACE_ITERATORS_HPP__
0010 #define __FACE_ITERATORS_HPP__
0011
0012 #include <boost/iterator/iterator_facade.hpp>
0013 #include <boost/mpl/bool.hpp>
0014 #include <boost/graph/graph_traits.hpp>
0015
0016 namespace boost
0017 {
0018
0019
0020
0021
0022 struct lead_visitor
0023 {
0024 };
0025 struct follow_visitor
0026 {
0027 };
0028
0029
0030 struct single_side
0031 {
0032 };
0033 struct both_sides
0034 {
0035 };
0036
0037
0038 struct first_side
0039 {
0040 };
0041 struct second_side
0042 {
0043 };
0044 struct alternating
0045 {
0046 };
0047
0048
0049 struct current_iteration
0050 {
0051 };
0052 struct previous_iteration
0053 {
0054 };
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 template < typename Graph, typename FaceHandlesMap, typename ValueType,
0072 typename BicompSideToTraverse = single_side,
0073 typename VisitorType = lead_visitor, typename Time = current_iteration >
0074 class face_iterator;
0075
0076 template < typename Graph, bool StoreEdge > struct edge_storage
0077 {
0078 };
0079
0080 template < typename Graph > struct edge_storage< Graph, true >
0081 {
0082 typename graph_traits< Graph >::edge_descriptor value;
0083 };
0084
0085
0086 template < typename Graph, typename FaceHandlesMap, typename ValueType,
0087 typename TraversalType, typename VisitorType, typename Time >
0088
0089 class face_iterator : public boost::iterator_facade<
0090 face_iterator< Graph, FaceHandlesMap, ValueType,
0091 TraversalType, VisitorType, Time >,
0092 ValueType, boost::forward_traversal_tag, ValueType >
0093 {
0094 public:
0095 typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
0096 typedef typename graph_traits< Graph >::edge_descriptor edge_t;
0097 typedef face_iterator< Graph, FaceHandlesMap, ValueType, TraversalType,
0098 VisitorType, Time >
0099 self;
0100 typedef typename FaceHandlesMap::value_type face_handle_t;
0101
0102 face_iterator()
0103 : m_lead(graph_traits< Graph >::null_vertex())
0104 , m_follow(graph_traits< Graph >::null_vertex())
0105 {
0106 }
0107
0108 template < typename TraversalSubType >
0109 face_iterator(face_handle_t anchor_handle, FaceHandlesMap face_handles,
0110 TraversalSubType traversal_type)
0111 : m_follow(anchor_handle.get_anchor()), m_face_handles(face_handles)
0112 {
0113 set_lead_dispatch(anchor_handle, traversal_type);
0114 }
0115
0116 template < typename TraversalSubType >
0117 face_iterator(vertex_t anchor, FaceHandlesMap face_handles,
0118 TraversalSubType traversal_type)
0119 : m_follow(anchor), m_face_handles(face_handles)
0120 {
0121 set_lead_dispatch(m_face_handles[anchor], traversal_type);
0122 }
0123
0124 private:
0125 friend class boost::iterator_core_access;
0126
0127 inline vertex_t get_first_vertex(
0128 face_handle_t anchor_handle, current_iteration)
0129 {
0130 return anchor_handle.first_vertex();
0131 }
0132
0133 inline vertex_t get_second_vertex(
0134 face_handle_t anchor_handle, current_iteration)
0135 {
0136 return anchor_handle.second_vertex();
0137 }
0138
0139 inline vertex_t get_first_vertex(
0140 face_handle_t anchor_handle, previous_iteration)
0141 {
0142 return anchor_handle.old_first_vertex();
0143 }
0144
0145 inline vertex_t get_second_vertex(
0146 face_handle_t anchor_handle, previous_iteration)
0147 {
0148 return anchor_handle.old_second_vertex();
0149 }
0150
0151 inline void set_lead_dispatch(face_handle_t anchor_handle, first_side)
0152 {
0153 m_lead = get_first_vertex(anchor_handle, Time());
0154 set_edge_to_first_dispatch(anchor_handle, ValueType(), Time());
0155 }
0156
0157 inline void set_lead_dispatch(face_handle_t anchor_handle, second_side)
0158 {
0159 m_lead = get_second_vertex(anchor_handle, Time());
0160 set_edge_to_second_dispatch(anchor_handle, ValueType(), Time());
0161 }
0162
0163 inline void set_edge_to_first_dispatch(
0164 face_handle_t anchor_handle, edge_t, current_iteration)
0165 {
0166 m_edge.value = anchor_handle.first_edge();
0167 }
0168
0169 inline void set_edge_to_second_dispatch(
0170 face_handle_t anchor_handle, edge_t, current_iteration)
0171 {
0172 m_edge.value = anchor_handle.second_edge();
0173 }
0174
0175 inline void set_edge_to_first_dispatch(
0176 face_handle_t anchor_handle, edge_t, previous_iteration)
0177 {
0178 m_edge.value = anchor_handle.old_first_edge();
0179 }
0180
0181 inline void set_edge_to_second_dispatch(
0182 face_handle_t anchor_handle, edge_t, previous_iteration)
0183 {
0184 m_edge.value = anchor_handle.old_second_edge();
0185 }
0186
0187 template < typename T >
0188 inline void set_edge_to_first_dispatch(face_handle_t, vertex_t, T)
0189 {
0190 }
0191
0192 template < typename T >
0193 inline void set_edge_to_second_dispatch(face_handle_t, vertex_t, T)
0194 {
0195 }
0196
0197 void increment()
0198 {
0199 face_handle_t curr_face_handle(m_face_handles[m_lead]);
0200 vertex_t first = get_first_vertex(curr_face_handle, Time());
0201 vertex_t second = get_second_vertex(curr_face_handle, Time());
0202 if (first == m_follow)
0203 {
0204 m_follow = m_lead;
0205 set_edge_to_second_dispatch(curr_face_handle, ValueType(), Time());
0206 m_lead = second;
0207 }
0208 else if (second == m_follow)
0209 {
0210 m_follow = m_lead;
0211 set_edge_to_first_dispatch(curr_face_handle, ValueType(), Time());
0212 m_lead = first;
0213 }
0214 else
0215 m_lead = m_follow = graph_traits< Graph >::null_vertex();
0216 }
0217
0218 bool equal(self const& other) const
0219 {
0220 return m_lead == other.m_lead && m_follow == other.m_follow;
0221 }
0222
0223 ValueType dereference() const
0224 {
0225 return dereference_dispatch(VisitorType(), ValueType());
0226 }
0227
0228 inline ValueType dereference_dispatch(lead_visitor, vertex_t) const
0229 {
0230 return m_lead;
0231 }
0232
0233 inline ValueType dereference_dispatch(follow_visitor, vertex_t) const
0234 {
0235 return m_follow;
0236 }
0237
0238 inline ValueType dereference_dispatch(lead_visitor, edge_t) const
0239 {
0240 return m_edge.value;
0241 }
0242
0243 inline ValueType dereference_dispatch(follow_visitor, edge_t) const
0244 {
0245 return m_edge.value;
0246 }
0247
0248 vertex_t m_lead;
0249 vertex_t m_follow;
0250 edge_storage< Graph, boost::is_same< ValueType, edge_t >::value > m_edge;
0251 FaceHandlesMap m_face_handles;
0252 };
0253
0254 template < typename Graph, typename FaceHandlesMap, typename ValueType,
0255 typename VisitorType, typename Time >
0256 class face_iterator< Graph, FaceHandlesMap, ValueType, both_sides, VisitorType,
0257 Time >
0258 : public boost::iterator_facade< face_iterator< Graph, FaceHandlesMap,
0259 ValueType, both_sides, VisitorType, Time >,
0260 ValueType, boost::forward_traversal_tag, ValueType >
0261 {
0262 public:
0263 typedef face_iterator< Graph, FaceHandlesMap, ValueType, both_sides,
0264 VisitorType, Time >
0265 self;
0266 typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
0267 typedef typename FaceHandlesMap::value_type face_handle_t;
0268
0269 face_iterator() {}
0270
0271 face_iterator(face_handle_t anchor_handle, FaceHandlesMap face_handles)
0272 : first_itr(anchor_handle, face_handles, first_side())
0273 , second_itr(anchor_handle, face_handles, second_side())
0274 , first_is_active(true)
0275 , first_increment(true)
0276 {
0277 }
0278
0279 face_iterator(vertex_t anchor, FaceHandlesMap face_handles)
0280 : first_itr(face_handles[anchor], face_handles, first_side())
0281 , second_itr(face_handles[anchor], face_handles, second_side())
0282 , first_is_active(true)
0283 , first_increment(true)
0284 {
0285 }
0286
0287 private:
0288 friend class boost::iterator_core_access;
0289
0290 typedef face_iterator< Graph, FaceHandlesMap, ValueType, single_side,
0291 follow_visitor, Time >
0292 inner_itr_t;
0293
0294 void increment()
0295 {
0296 if (first_increment)
0297 {
0298 ++first_itr;
0299 ++second_itr;
0300 first_increment = false;
0301 }
0302 else if (first_is_active)
0303 ++first_itr;
0304 else
0305 ++second_itr;
0306 first_is_active = !first_is_active;
0307 }
0308
0309 bool equal(self const& other) const
0310 {
0311
0312
0313
0314
0315 return (first_itr == other.first_itr || second_itr == other.second_itr);
0316 }
0317
0318 ValueType dereference() const
0319 {
0320 return first_is_active ? *first_itr : *second_itr;
0321 }
0322
0323 inner_itr_t first_itr;
0324 inner_itr_t second_itr;
0325 inner_itr_t face_end;
0326 bool first_is_active;
0327 bool first_increment;
0328 };
0329
0330 }
0331
0332 #endif