annotate DEPENDENCIES/generic/include/boost/graph/planar_detail/face_handles.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_HANDLES_HPP__
Chris@16 10 #define __FACE_HANDLES_HPP__
Chris@16 11
Chris@16 12
Chris@16 13 #include <list>
Chris@16 14 #include <boost/graph/graph_traits.hpp>
Chris@16 15 #include <boost/shared_ptr.hpp>
Chris@16 16
Chris@16 17
Chris@16 18 // A "face handle" is an optimization meant to serve two purposes in
Chris@16 19 // the implementation of the Boyer-Myrvold planarity test: (1) it holds
Chris@16 20 // the partial planar embedding of a particular vertex as it's being
Chris@16 21 // constructed, and (2) it allows for efficient traversal around the
Chris@16 22 // outer face of the partial embedding at that particular vertex. A face
Chris@16 23 // handle is lightweight, just a shared pointer to the actual implementation,
Chris@16 24 // since it is passed around/copied liberally in the algorithm. It consists
Chris@16 25 // of an "anchor" (the actual vertex it's associated with) as well as a
Chris@16 26 // sequence of edges. The functions first_vertex/second_vertex and
Chris@16 27 // first_edge/second_edge allow fast access to the beginning and end of the
Chris@16 28 // stored sequence, which allows one to traverse the outer face of the partial
Chris@16 29 // planar embedding as it's being created.
Chris@16 30 //
Chris@16 31 // There are some policies below that define the contents of the face handles:
Chris@16 32 // in the case no embedding is needed (for example, if one just wants to use
Chris@16 33 // the Boyer-Myrvold algorithm as a true/false test for planarity, the
Chris@16 34 // no_embedding class can be passed as the StoreEmbedding policy. Otherwise,
Chris@16 35 // either std_list (which uses as std::list) or recursive_lazy_list can be
Chris@16 36 // passed as this policy. recursive_lazy_list has the best theoretical
Chris@16 37 // performance (O(n) for a sequence of interleaved concatenations and reversals
Chris@16 38 // of the underlying list), but I've noticed little difference between std_list
Chris@16 39 // and recursive_lazy_list in my tests, even though using std_list changes
Chris@16 40 // the worst-case complexity of the planarity test to O(n^2)
Chris@16 41 //
Chris@16 42 // Another policy is StoreOldHandlesPolicy, which specifies whether or not
Chris@16 43 // to keep a record of the previous first/second vertex/edge - this is needed
Chris@16 44 // if a Kuratowski subgraph needs to be isolated.
Chris@16 45
Chris@16 46
Chris@16 47 namespace boost { namespace graph { namespace detail {
Chris@16 48
Chris@16 49
Chris@16 50 //face handle policies
Chris@16 51
Chris@16 52 //EmbeddingStorage policy
Chris@16 53 struct store_embedding {};
Chris@16 54 struct recursive_lazy_list : public store_embedding {};
Chris@16 55 struct std_list : public store_embedding {};
Chris@16 56 struct no_embedding {};
Chris@16 57
Chris@16 58 //StoreOldHandlesPolicy
Chris@16 59 struct store_old_handles {};
Chris@16 60 struct no_old_handles {};
Chris@16 61
Chris@16 62
Chris@16 63
Chris@16 64
Chris@16 65 template<typename DataType>
Chris@16 66 struct lazy_list_node
Chris@16 67 {
Chris@16 68 typedef shared_ptr< lazy_list_node<DataType> > ptr_t;
Chris@16 69
Chris@16 70 lazy_list_node(const DataType& data) :
Chris@16 71 m_reversed(false),
Chris@16 72 m_data(data),
Chris@16 73 m_has_data(true)
Chris@16 74 {}
Chris@16 75
Chris@16 76 lazy_list_node(ptr_t left_child, ptr_t right_child) :
Chris@16 77 m_reversed(false),
Chris@16 78 m_has_data(false),
Chris@16 79 m_left_child(left_child),
Chris@16 80 m_right_child(right_child)
Chris@16 81 {}
Chris@16 82
Chris@16 83 bool m_reversed;
Chris@16 84 DataType m_data;
Chris@16 85 bool m_has_data;
Chris@16 86 shared_ptr<lazy_list_node> m_left_child;
Chris@16 87 shared_ptr<lazy_list_node> m_right_child;
Chris@16 88 };
Chris@16 89
Chris@16 90
Chris@16 91
Chris@16 92 template <typename StoreOldHandlesPolicy, typename Vertex, typename Edge>
Chris@16 93 struct old_handles_storage;
Chris@16 94
Chris@16 95 template <typename Vertex, typename Edge>
Chris@16 96 struct old_handles_storage<store_old_handles, Vertex, Edge>
Chris@16 97 {
Chris@16 98 Vertex first_vertex;
Chris@16 99 Vertex second_vertex;
Chris@16 100 Edge first_edge;
Chris@16 101 Edge second_edge;
Chris@16 102 };
Chris@16 103
Chris@16 104 template <typename Vertex, typename Edge>
Chris@16 105 struct old_handles_storage<no_old_handles, Vertex, Edge>
Chris@16 106 {};
Chris@16 107
Chris@16 108
Chris@16 109
Chris@16 110
Chris@16 111
Chris@16 112
Chris@16 113 template <typename StoreEmbeddingPolicy, typename Edge>
Chris@16 114 struct edge_list_storage;
Chris@16 115
Chris@16 116
Chris@16 117
Chris@16 118
Chris@16 119
Chris@16 120 template <typename Edge>
Chris@16 121 struct edge_list_storage<no_embedding, Edge>
Chris@16 122 {
Chris@16 123 typedef void type;
Chris@16 124
Chris@16 125 void push_back(Edge) {}
Chris@16 126 void push_front(Edge) {}
Chris@16 127 void reverse() {}
Chris@16 128 void concat_front(edge_list_storage<no_embedding,Edge>) {}
Chris@16 129 void concat_back(edge_list_storage<no_embedding,Edge>) {}
Chris@16 130 template <typename OutputIterator>
Chris@16 131 void get_list(OutputIterator) {}
Chris@16 132 };
Chris@16 133
Chris@16 134
Chris@16 135
Chris@16 136
Chris@16 137
Chris@16 138 template <typename Edge>
Chris@16 139 struct edge_list_storage<recursive_lazy_list, Edge>
Chris@16 140 {
Chris@16 141 typedef lazy_list_node<Edge> node_type;
Chris@16 142 typedef shared_ptr< node_type > type;
Chris@16 143 type value;
Chris@16 144
Chris@16 145 void push_back(Edge e)
Chris@16 146 {
Chris@16 147 type new_node(new node_type(e));
Chris@16 148 value = type(new node_type(value, new_node));
Chris@16 149 }
Chris@16 150
Chris@16 151 void push_front(Edge e)
Chris@16 152 {
Chris@16 153 type new_node(new node_type(e));
Chris@16 154 value = type(new node_type(new_node, value));
Chris@16 155 }
Chris@16 156
Chris@16 157 void reverse()
Chris@16 158 {
Chris@16 159 value->m_reversed = !value->m_reversed;
Chris@16 160 }
Chris@16 161
Chris@16 162 void concat_front(edge_list_storage<recursive_lazy_list, Edge> other)
Chris@16 163 {
Chris@16 164 value = type(new node_type(other.value, value));
Chris@16 165 }
Chris@16 166
Chris@16 167 void concat_back(edge_list_storage<recursive_lazy_list, Edge> other)
Chris@16 168 {
Chris@16 169 value = type(new node_type(value, other.value));
Chris@16 170 }
Chris@16 171
Chris@16 172 template <typename OutputIterator>
Chris@16 173 void get_list(OutputIterator out)
Chris@16 174 {
Chris@16 175 get_list_helper(out, value);
Chris@16 176 }
Chris@16 177
Chris@16 178 private:
Chris@16 179
Chris@16 180 template <typename OutputIterator>
Chris@16 181 void get_list_helper(OutputIterator o_itr,
Chris@16 182 type root,
Chris@16 183 bool flipped = false
Chris@16 184 )
Chris@16 185 {
Chris@16 186 if (!root)
Chris@16 187 return;
Chris@16 188
Chris@16 189 if (root->m_has_data)
Chris@16 190 *o_itr = root->m_data;
Chris@16 191
Chris@16 192 if ((flipped && !root->m_reversed) ||
Chris@16 193 (!flipped && root->m_reversed)
Chris@16 194 )
Chris@16 195 {
Chris@16 196 get_list_helper(o_itr, root->m_right_child, true);
Chris@16 197 get_list_helper(o_itr, root->m_left_child, true);
Chris@16 198 }
Chris@16 199 else
Chris@16 200 {
Chris@16 201 get_list_helper(o_itr, root->m_left_child, false);
Chris@16 202 get_list_helper(o_itr, root->m_right_child, false);
Chris@16 203 }
Chris@16 204
Chris@16 205 }
Chris@16 206
Chris@16 207 };
Chris@16 208
Chris@16 209
Chris@16 210
Chris@16 211
Chris@16 212
Chris@16 213 template <typename Edge>
Chris@16 214 struct edge_list_storage<std_list, Edge>
Chris@16 215 {
Chris@16 216 typedef std::list<Edge> type;
Chris@16 217 type value;
Chris@16 218
Chris@16 219 void push_back(Edge e)
Chris@16 220 {
Chris@16 221 value.push_back(e);
Chris@16 222 }
Chris@16 223
Chris@16 224 void push_front(Edge e)
Chris@16 225 {
Chris@16 226 value.push_front(e);
Chris@16 227 }
Chris@16 228
Chris@16 229 void reverse()
Chris@16 230 {
Chris@16 231 value.reverse();
Chris@16 232 }
Chris@16 233
Chris@16 234 void concat_front(edge_list_storage<std_list,Edge> other)
Chris@16 235 {
Chris@16 236 value.splice(value.begin(), other.value);
Chris@16 237 }
Chris@16 238
Chris@16 239 void concat_back(edge_list_storage<std_list, Edge> other)
Chris@16 240 {
Chris@16 241 value.splice(value.end(), other.value);
Chris@16 242 }
Chris@16 243
Chris@16 244 template <typename OutputIterator>
Chris@16 245 void get_list(OutputIterator out)
Chris@16 246 {
Chris@16 247 std::copy(value.begin(), value.end(), out);
Chris@16 248 }
Chris@16 249
Chris@16 250 };
Chris@16 251
Chris@16 252
Chris@16 253
Chris@16 254
Chris@16 255
Chris@16 256
Chris@16 257
Chris@16 258 template<typename Graph,
Chris@16 259 typename StoreOldHandlesPolicy,
Chris@16 260 typename StoreEmbeddingPolicy
Chris@16 261 >
Chris@16 262 struct face_handle_impl
Chris@16 263 {
Chris@16 264 typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
Chris@16 265 typedef typename graph_traits<Graph>::edge_descriptor edge_t;
Chris@16 266 typedef typename edge_list_storage<StoreEmbeddingPolicy, edge_t>::type
Chris@16 267 edge_list_storage_t;
Chris@16 268
Chris@16 269
Chris@16 270 face_handle_impl() :
Chris@16 271 cached_first_vertex(graph_traits<Graph>::null_vertex()),
Chris@16 272 cached_second_vertex(graph_traits<Graph>::null_vertex()),
Chris@16 273 true_first_vertex(graph_traits<Graph>::null_vertex()),
Chris@16 274 true_second_vertex(graph_traits<Graph>::null_vertex()),
Chris@16 275 anchor(graph_traits<Graph>::null_vertex())
Chris@16 276 {
Chris@16 277 initialize_old_vertices_dispatch(StoreOldHandlesPolicy());
Chris@16 278 }
Chris@16 279
Chris@16 280 void initialize_old_vertices_dispatch(store_old_handles)
Chris@16 281 {
Chris@16 282 old_handles.first_vertex = graph_traits<Graph>::null_vertex();
Chris@16 283 old_handles.second_vertex = graph_traits<Graph>::null_vertex();
Chris@16 284 }
Chris@16 285
Chris@16 286 void initialize_old_vertices_dispatch(no_old_handles) {}
Chris@16 287
Chris@16 288 vertex_t cached_first_vertex;
Chris@16 289 vertex_t cached_second_vertex;
Chris@16 290 vertex_t true_first_vertex;
Chris@16 291 vertex_t true_second_vertex;
Chris@16 292 vertex_t anchor;
Chris@16 293 edge_t cached_first_edge;
Chris@16 294 edge_t cached_second_edge;
Chris@16 295
Chris@16 296 edge_list_storage<StoreEmbeddingPolicy, edge_t> edge_list;
Chris@16 297 old_handles_storage<StoreOldHandlesPolicy, vertex_t, edge_t> old_handles;
Chris@16 298
Chris@16 299 };
Chris@16 300
Chris@16 301
Chris@16 302
Chris@16 303
Chris@16 304
Chris@16 305
Chris@16 306
Chris@16 307
Chris@16 308
Chris@16 309
Chris@16 310
Chris@16 311 template <typename Graph,
Chris@16 312 typename StoreOldHandlesPolicy = store_old_handles,
Chris@16 313 typename StoreEmbeddingPolicy = recursive_lazy_list
Chris@16 314 >
Chris@16 315 class face_handle
Chris@16 316 {
Chris@16 317 public:
Chris@16 318 typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
Chris@16 319 typedef typename graph_traits<Graph>::edge_descriptor edge_t;
Chris@16 320 typedef face_handle_impl
Chris@16 321 <Graph, StoreOldHandlesPolicy, StoreEmbeddingPolicy> impl_t;
Chris@16 322 typedef face_handle
Chris@16 323 <Graph, StoreOldHandlesPolicy, StoreEmbeddingPolicy> self_t;
Chris@16 324
Chris@16 325 face_handle(vertex_t anchor = graph_traits<Graph>::null_vertex()) :
Chris@16 326 pimpl(new impl_t())
Chris@16 327 {
Chris@16 328 pimpl->anchor = anchor;
Chris@16 329 }
Chris@16 330
Chris@16 331 face_handle(vertex_t anchor, edge_t initial_edge, const Graph& g) :
Chris@16 332 pimpl(new impl_t())
Chris@16 333 {
Chris@16 334 vertex_t s(source(initial_edge,g));
Chris@16 335 vertex_t t(target(initial_edge,g));
Chris@16 336 vertex_t other_vertex = s == anchor ? t : s;
Chris@16 337 pimpl->anchor = anchor;
Chris@16 338 pimpl->cached_first_edge = initial_edge;
Chris@16 339 pimpl->cached_second_edge = initial_edge;
Chris@16 340 pimpl->cached_first_vertex = other_vertex;
Chris@16 341 pimpl->cached_second_vertex = other_vertex;
Chris@16 342 pimpl->true_first_vertex = other_vertex;
Chris@16 343 pimpl->true_second_vertex = other_vertex;
Chris@16 344
Chris@16 345 pimpl->edge_list.push_back(initial_edge);
Chris@16 346 store_old_face_handles_dispatch(StoreOldHandlesPolicy());
Chris@16 347 }
Chris@16 348
Chris@16 349 //default copy construction, assignment okay.
Chris@16 350
Chris@16 351 void push_first(edge_t e, const Graph& g)
Chris@16 352 {
Chris@16 353 pimpl->edge_list.push_front(e);
Chris@16 354 pimpl->cached_first_vertex = pimpl->true_first_vertex =
Chris@16 355 source(e, g) == pimpl->anchor ? target(e,g) : source(e,g);
Chris@16 356 pimpl->cached_first_edge = e;
Chris@16 357 }
Chris@16 358
Chris@16 359 void push_second(edge_t e, const Graph& g)
Chris@16 360 {
Chris@16 361 pimpl->edge_list.push_back(e);
Chris@16 362 pimpl->cached_second_vertex = pimpl->true_second_vertex =
Chris@16 363 source(e, g) == pimpl->anchor ? target(e,g) : source(e,g);
Chris@16 364 pimpl->cached_second_edge = e;
Chris@16 365 }
Chris@16 366
Chris@16 367 inline void store_old_face_handles()
Chris@16 368 {
Chris@16 369 store_old_face_handles_dispatch(StoreOldHandlesPolicy());
Chris@16 370 }
Chris@16 371
Chris@16 372 inline vertex_t first_vertex() const
Chris@16 373 {
Chris@16 374 return pimpl->cached_first_vertex;
Chris@16 375 }
Chris@16 376
Chris@16 377 inline vertex_t second_vertex() const
Chris@16 378 {
Chris@16 379 return pimpl->cached_second_vertex;
Chris@16 380 }
Chris@16 381
Chris@16 382 inline vertex_t true_first_vertex() const
Chris@16 383 {
Chris@16 384 return pimpl->true_first_vertex;
Chris@16 385 }
Chris@16 386
Chris@16 387 inline vertex_t true_second_vertex() const
Chris@16 388 {
Chris@16 389 return pimpl->true_second_vertex;
Chris@16 390 }
Chris@16 391
Chris@16 392 inline vertex_t old_first_vertex() const
Chris@16 393 {
Chris@16 394 return pimpl->old_handles.first_vertex;
Chris@16 395 }
Chris@16 396
Chris@16 397 inline vertex_t old_second_vertex() const
Chris@16 398 {
Chris@16 399 return pimpl->old_handles.second_vertex;
Chris@16 400 }
Chris@16 401
Chris@16 402 inline edge_t old_first_edge() const
Chris@16 403 {
Chris@16 404 return pimpl->old_handles.first_edge;
Chris@16 405 }
Chris@16 406
Chris@16 407 inline edge_t old_second_edge() const
Chris@16 408 {
Chris@16 409 return pimpl->old_handles.second_edge;
Chris@16 410 }
Chris@16 411
Chris@16 412 inline edge_t first_edge() const
Chris@16 413 {
Chris@16 414 return pimpl->cached_first_edge;
Chris@16 415 }
Chris@16 416
Chris@16 417 inline edge_t second_edge() const
Chris@16 418 {
Chris@16 419 return pimpl->cached_second_edge;
Chris@16 420 }
Chris@16 421
Chris@16 422 inline vertex_t get_anchor() const
Chris@16 423 {
Chris@16 424 return pimpl->anchor;
Chris@16 425 }
Chris@16 426
Chris@16 427 void glue_first_to_second
Chris@16 428 (face_handle<Graph,StoreOldHandlesPolicy,StoreEmbeddingPolicy>& bottom)
Chris@16 429 {
Chris@16 430 pimpl->edge_list.concat_front(bottom.pimpl->edge_list);
Chris@16 431 pimpl->true_first_vertex = bottom.pimpl->true_first_vertex;
Chris@16 432 pimpl->cached_first_vertex = bottom.pimpl->cached_first_vertex;
Chris@16 433 pimpl->cached_first_edge = bottom.pimpl->cached_first_edge;
Chris@16 434 }
Chris@16 435
Chris@16 436 void glue_second_to_first
Chris@16 437 (face_handle<Graph,StoreOldHandlesPolicy,StoreEmbeddingPolicy>& bottom)
Chris@16 438 {
Chris@16 439 pimpl->edge_list.concat_back(bottom.pimpl->edge_list);
Chris@16 440 pimpl->true_second_vertex = bottom.pimpl->true_second_vertex;
Chris@16 441 pimpl->cached_second_vertex = bottom.pimpl->cached_second_vertex;
Chris@16 442 pimpl->cached_second_edge = bottom.pimpl->cached_second_edge;
Chris@16 443 }
Chris@16 444
Chris@16 445 void flip()
Chris@16 446 {
Chris@16 447 pimpl->edge_list.reverse();
Chris@16 448 std::swap(pimpl->true_first_vertex, pimpl->true_second_vertex);
Chris@16 449 std::swap(pimpl->cached_first_vertex, pimpl->cached_second_vertex);
Chris@16 450 std::swap(pimpl->cached_first_edge, pimpl->cached_second_edge);
Chris@16 451 }
Chris@16 452
Chris@16 453 template <typename OutputIterator>
Chris@16 454 void get_list(OutputIterator o_itr)
Chris@16 455 {
Chris@16 456 pimpl->edge_list.get_list(o_itr);
Chris@16 457 }
Chris@16 458
Chris@16 459 void reset_vertex_cache()
Chris@16 460 {
Chris@16 461 pimpl->cached_first_vertex = pimpl->true_first_vertex;
Chris@16 462 pimpl->cached_second_vertex = pimpl->true_second_vertex;
Chris@16 463 }
Chris@16 464
Chris@16 465 inline void set_first_vertex(vertex_t v)
Chris@16 466 {
Chris@16 467 pimpl->cached_first_vertex = v;
Chris@16 468 }
Chris@16 469
Chris@16 470 inline void set_second_vertex(vertex_t v)
Chris@16 471 {
Chris@16 472 pimpl->cached_second_vertex = v;
Chris@16 473 }
Chris@16 474
Chris@16 475 private:
Chris@16 476
Chris@16 477 void store_old_face_handles_dispatch(store_old_handles)
Chris@16 478 {
Chris@16 479 pimpl->old_handles.first_vertex = pimpl->true_first_vertex;
Chris@16 480 pimpl->old_handles.second_vertex = pimpl->true_second_vertex;
Chris@16 481 pimpl->old_handles.first_edge = pimpl->cached_first_edge;
Chris@16 482 pimpl->old_handles.second_edge = pimpl->cached_second_edge;
Chris@16 483 }
Chris@16 484
Chris@16 485 void store_old_face_handles_dispatch(no_old_handles) {}
Chris@16 486
Chris@16 487
Chris@16 488
Chris@16 489 boost::shared_ptr<impl_t> pimpl;
Chris@16 490
Chris@16 491 };
Chris@16 492
Chris@16 493
Chris@16 494 } /* namespace detail */ } /* namespace graph */ } /* namespace boost */
Chris@16 495
Chris@16 496
Chris@16 497 #endif //__FACE_HANDLES_HPP__