File indexing completed on 2025-01-18 09:37:21
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef __FACE_HANDLES_HPP__
0010 #define __FACE_HANDLES_HPP__
0011
0012 #include <list>
0013 #include <boost/graph/graph_traits.hpp>
0014 #include <boost/shared_ptr.hpp>
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 namespace boost
0045 {
0046 namespace graph
0047 {
0048 namespace detail
0049 {
0050
0051
0052
0053
0054 struct store_embedding
0055 {
0056 };
0057 struct recursive_lazy_list : public store_embedding
0058 {
0059 };
0060 struct std_list : public store_embedding
0061 {
0062 };
0063 struct no_embedding
0064 {
0065 };
0066
0067
0068 struct store_old_handles
0069 {
0070 };
0071 struct no_old_handles
0072 {
0073 };
0074
0075 template < typename DataType > struct lazy_list_node
0076 {
0077 typedef shared_ptr< lazy_list_node< DataType > > ptr_t;
0078
0079 lazy_list_node(const DataType& data)
0080 : m_reversed(false), m_data(data), m_has_data(true)
0081 {
0082 }
0083
0084 lazy_list_node(ptr_t left_child, ptr_t right_child)
0085 : m_reversed(false)
0086 , m_has_data(false)
0087 , m_left_child(left_child)
0088 , m_right_child(right_child)
0089 {
0090 }
0091
0092 bool m_reversed;
0093 DataType m_data;
0094 bool m_has_data;
0095 shared_ptr< lazy_list_node > m_left_child;
0096 shared_ptr< lazy_list_node > m_right_child;
0097 };
0098
0099 template < typename StoreOldHandlesPolicy, typename Vertex,
0100 typename Edge >
0101 struct old_handles_storage;
0102
0103 template < typename Vertex, typename Edge >
0104 struct old_handles_storage< store_old_handles, Vertex, Edge >
0105 {
0106 Vertex first_vertex;
0107 Vertex second_vertex;
0108 Edge first_edge;
0109 Edge second_edge;
0110 };
0111
0112 template < typename Vertex, typename Edge >
0113 struct old_handles_storage< no_old_handles, Vertex, Edge >
0114 {
0115 };
0116
0117 template < typename StoreEmbeddingPolicy, typename Edge >
0118 struct edge_list_storage;
0119
0120 template < typename Edge >
0121 struct edge_list_storage< no_embedding, Edge >
0122 {
0123 typedef void type;
0124
0125 void push_back(Edge) {}
0126 void push_front(Edge) {}
0127 void reverse() {}
0128 void concat_front(edge_list_storage< no_embedding, Edge >) {}
0129 void concat_back(edge_list_storage< no_embedding, Edge >) {}
0130 template < typename OutputIterator > void get_list(OutputIterator)
0131 {
0132 }
0133 };
0134
0135 template < typename Edge >
0136 struct edge_list_storage< recursive_lazy_list, Edge >
0137 {
0138 typedef lazy_list_node< Edge > node_type;
0139 typedef shared_ptr< node_type > type;
0140 type value;
0141
0142 void push_back(Edge e)
0143 {
0144 type new_node(new node_type(e));
0145 value = type(new node_type(value, new_node));
0146 }
0147
0148 void push_front(Edge e)
0149 {
0150 type new_node(new node_type(e));
0151 value = type(new node_type(new_node, value));
0152 }
0153
0154 void reverse() { value->m_reversed = !value->m_reversed; }
0155
0156 void concat_front(
0157 edge_list_storage< recursive_lazy_list, Edge > other)
0158 {
0159 value = type(new node_type(other.value, value));
0160 }
0161
0162 void concat_back(
0163 edge_list_storage< recursive_lazy_list, Edge > other)
0164 {
0165 value = type(new node_type(value, other.value));
0166 }
0167
0168 template < typename OutputIterator >
0169 void get_list(OutputIterator out)
0170 {
0171 get_list_helper(out, value);
0172 }
0173
0174 private:
0175 template < typename OutputIterator >
0176 void get_list_helper(
0177 OutputIterator o_itr, type root, bool flipped = false)
0178 {
0179 if (!root)
0180 return;
0181
0182 if (root->m_has_data)
0183 *o_itr = root->m_data;
0184
0185 if ((flipped && !root->m_reversed)
0186 || (!flipped && root->m_reversed))
0187 {
0188 get_list_helper(o_itr, root->m_right_child, true);
0189 get_list_helper(o_itr, root->m_left_child, true);
0190 }
0191 else
0192 {
0193 get_list_helper(o_itr, root->m_left_child, false);
0194 get_list_helper(o_itr, root->m_right_child, false);
0195 }
0196 }
0197 };
0198
0199 template < typename Edge > struct edge_list_storage< std_list, Edge >
0200 {
0201 typedef std::list< Edge > type;
0202 type value;
0203
0204 void push_back(Edge e) { value.push_back(e); }
0205
0206 void push_front(Edge e) { value.push_front(e); }
0207
0208 void reverse() { value.reverse(); }
0209
0210 void concat_front(edge_list_storage< std_list, Edge > other)
0211 {
0212 value.splice(value.begin(), other.value);
0213 }
0214
0215 void concat_back(edge_list_storage< std_list, Edge > other)
0216 {
0217 value.splice(value.end(), other.value);
0218 }
0219
0220 template < typename OutputIterator >
0221 void get_list(OutputIterator out)
0222 {
0223 std::copy(value.begin(), value.end(), out);
0224 }
0225 };
0226
0227 template < typename Graph, typename StoreOldHandlesPolicy,
0228 typename StoreEmbeddingPolicy >
0229 struct face_handle_impl
0230 {
0231 typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
0232 typedef typename graph_traits< Graph >::edge_descriptor edge_t;
0233 typedef
0234 typename edge_list_storage< StoreEmbeddingPolicy, edge_t >::type
0235 edge_list_storage_t;
0236
0237 face_handle_impl()
0238 : cached_first_vertex(graph_traits< Graph >::null_vertex())
0239 , cached_second_vertex(graph_traits< Graph >::null_vertex())
0240 , true_first_vertex(graph_traits< Graph >::null_vertex())
0241 , true_second_vertex(graph_traits< Graph >::null_vertex())
0242 , anchor(graph_traits< Graph >::null_vertex())
0243 {
0244 initialize_old_vertices_dispatch(StoreOldHandlesPolicy());
0245 }
0246
0247 void initialize_old_vertices_dispatch(store_old_handles)
0248 {
0249 old_handles.first_vertex = graph_traits< Graph >::null_vertex();
0250 old_handles.second_vertex
0251 = graph_traits< Graph >::null_vertex();
0252 }
0253
0254 void initialize_old_vertices_dispatch(no_old_handles) {}
0255
0256 vertex_t cached_first_vertex;
0257 vertex_t cached_second_vertex;
0258 vertex_t true_first_vertex;
0259 vertex_t true_second_vertex;
0260 vertex_t anchor;
0261 edge_t cached_first_edge;
0262 edge_t cached_second_edge;
0263
0264 edge_list_storage< StoreEmbeddingPolicy, edge_t > edge_list;
0265 old_handles_storage< StoreOldHandlesPolicy, vertex_t, edge_t >
0266 old_handles;
0267 };
0268
0269 template < typename Graph,
0270 typename StoreOldHandlesPolicy = store_old_handles,
0271 typename StoreEmbeddingPolicy = recursive_lazy_list >
0272 class face_handle
0273 {
0274 public:
0275 typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
0276 typedef typename graph_traits< Graph >::edge_descriptor edge_t;
0277 typedef face_handle_impl< Graph, StoreOldHandlesPolicy,
0278 StoreEmbeddingPolicy >
0279 impl_t;
0280 typedef face_handle< Graph, StoreOldHandlesPolicy,
0281 StoreEmbeddingPolicy >
0282 self_t;
0283
0284 face_handle(vertex_t anchor = graph_traits< Graph >::null_vertex())
0285 : pimpl(new impl_t())
0286 {
0287 pimpl->anchor = anchor;
0288 }
0289
0290 face_handle(vertex_t anchor, edge_t initial_edge, const Graph& g)
0291 : pimpl(new impl_t())
0292 {
0293 vertex_t s(source(initial_edge, g));
0294 vertex_t t(target(initial_edge, g));
0295 vertex_t other_vertex = s == anchor ? t : s;
0296 pimpl->anchor = anchor;
0297 pimpl->cached_first_edge = initial_edge;
0298 pimpl->cached_second_edge = initial_edge;
0299 pimpl->cached_first_vertex = other_vertex;
0300 pimpl->cached_second_vertex = other_vertex;
0301 pimpl->true_first_vertex = other_vertex;
0302 pimpl->true_second_vertex = other_vertex;
0303
0304 pimpl->edge_list.push_back(initial_edge);
0305 store_old_face_handles_dispatch(StoreOldHandlesPolicy());
0306 }
0307
0308
0309
0310 void push_first(edge_t e, const Graph& g)
0311 {
0312 pimpl->edge_list.push_front(e);
0313 pimpl->cached_first_vertex = pimpl->true_first_vertex
0314 = source(e, g) == pimpl->anchor ? target(e, g)
0315 : source(e, g);
0316 pimpl->cached_first_edge = e;
0317 }
0318
0319 void push_second(edge_t e, const Graph& g)
0320 {
0321 pimpl->edge_list.push_back(e);
0322 pimpl->cached_second_vertex = pimpl->true_second_vertex
0323 = source(e, g) == pimpl->anchor ? target(e, g)
0324 : source(e, g);
0325 pimpl->cached_second_edge = e;
0326 }
0327
0328 inline void store_old_face_handles()
0329 {
0330 store_old_face_handles_dispatch(StoreOldHandlesPolicy());
0331 }
0332
0333 inline vertex_t first_vertex() const
0334 {
0335 return pimpl->cached_first_vertex;
0336 }
0337
0338 inline vertex_t second_vertex() const
0339 {
0340 return pimpl->cached_second_vertex;
0341 }
0342
0343 inline vertex_t true_first_vertex() const
0344 {
0345 return pimpl->true_first_vertex;
0346 }
0347
0348 inline vertex_t true_second_vertex() const
0349 {
0350 return pimpl->true_second_vertex;
0351 }
0352
0353 inline vertex_t old_first_vertex() const
0354 {
0355 return pimpl->old_handles.first_vertex;
0356 }
0357
0358 inline vertex_t old_second_vertex() const
0359 {
0360 return pimpl->old_handles.second_vertex;
0361 }
0362
0363 inline edge_t old_first_edge() const
0364 {
0365 return pimpl->old_handles.first_edge;
0366 }
0367
0368 inline edge_t old_second_edge() const
0369 {
0370 return pimpl->old_handles.second_edge;
0371 }
0372
0373 inline edge_t first_edge() const
0374 {
0375 return pimpl->cached_first_edge;
0376 }
0377
0378 inline edge_t second_edge() const
0379 {
0380 return pimpl->cached_second_edge;
0381 }
0382
0383 inline vertex_t get_anchor() const { return pimpl->anchor; }
0384
0385 void glue_first_to_second(face_handle< Graph, StoreOldHandlesPolicy,
0386 StoreEmbeddingPolicy >& bottom)
0387 {
0388 pimpl->edge_list.concat_front(bottom.pimpl->edge_list);
0389 pimpl->true_first_vertex = bottom.pimpl->true_first_vertex;
0390 pimpl->cached_first_vertex = bottom.pimpl->cached_first_vertex;
0391 pimpl->cached_first_edge = bottom.pimpl->cached_first_edge;
0392 }
0393
0394 void glue_second_to_first(face_handle< Graph, StoreOldHandlesPolicy,
0395 StoreEmbeddingPolicy >& bottom)
0396 {
0397 pimpl->edge_list.concat_back(bottom.pimpl->edge_list);
0398 pimpl->true_second_vertex = bottom.pimpl->true_second_vertex;
0399 pimpl->cached_second_vertex
0400 = bottom.pimpl->cached_second_vertex;
0401 pimpl->cached_second_edge = bottom.pimpl->cached_second_edge;
0402 }
0403
0404 void flip()
0405 {
0406 pimpl->edge_list.reverse();
0407 std::swap(pimpl->true_first_vertex, pimpl->true_second_vertex);
0408 std::swap(
0409 pimpl->cached_first_vertex, pimpl->cached_second_vertex);
0410 std::swap(pimpl->cached_first_edge, pimpl->cached_second_edge);
0411 }
0412
0413 template < typename OutputIterator >
0414 void get_list(OutputIterator o_itr)
0415 {
0416 pimpl->edge_list.get_list(o_itr);
0417 }
0418
0419 void reset_vertex_cache()
0420 {
0421 pimpl->cached_first_vertex = pimpl->true_first_vertex;
0422 pimpl->cached_second_vertex = pimpl->true_second_vertex;
0423 }
0424
0425 inline void set_first_vertex(vertex_t v)
0426 {
0427 pimpl->cached_first_vertex = v;
0428 }
0429
0430 inline void set_second_vertex(vertex_t v)
0431 {
0432 pimpl->cached_second_vertex = v;
0433 }
0434
0435 private:
0436 void store_old_face_handles_dispatch(store_old_handles)
0437 {
0438 pimpl->old_handles.first_vertex = pimpl->true_first_vertex;
0439 pimpl->old_handles.second_vertex = pimpl->true_second_vertex;
0440 pimpl->old_handles.first_edge = pimpl->cached_first_edge;
0441 pimpl->old_handles.second_edge = pimpl->cached_second_edge;
0442 }
0443
0444 void store_old_face_handles_dispatch(no_old_handles) {}
0445
0446 boost::shared_ptr< impl_t > pimpl;
0447 };
0448
0449 }
0450 }
0451 }
0452
0453 #endif