diff --git a/include/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp b/include/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp index 330d75e66..38b2cda1e 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp @@ -16,6 +16,8 @@ #include #include +#include + #include @@ -26,14 +28,18 @@ namespace detail { namespace is_valid { -template +template class graph_vertex { public: - typedef typename std::set - < - graph_vertex - >::const_iterator vertex_handle; + template + struct rebind + { + typedef graph_vertex other; + }; + +private: + typedef typename Graph::vertex_handle vertex_handle; struct vertex_handle_less { @@ -44,6 +50,8 @@ public: }; typedef std::set neighbor_container; + +public: typedef typename neighbor_container::const_iterator neighbor_iterator; graph_vertex(int id, TurnPoint const& dummy = TurnPoint()) @@ -51,7 +59,7 @@ public: , m_id(id) , m_turn_point(dummy) , m_neighbors() - , m_parent() + , m_parent_id(-1) , m_visited(false) {} @@ -60,49 +68,29 @@ public: , m_id(-1) , m_turn_point(turn_point) , m_neighbors() - , m_parent() + , m_parent_id(-1) , m_visited(false) {} - int id() const { return m_id; } - void id(int id) const { m_id = id; } - int parent_id() const - { - if ( m_parent.second ) - { - return m_parent.first->id(); - } - return -1; - } + inline int id() const { return m_id; } + inline void id(int id) const { m_id = id; } - // for DFS -- start - bool visited() const { return m_visited; } - void visited(bool value) const { m_visited = value; } - - vertex_handle parent() const { return m_parent.first; } - void parent(vertex_handle p) const { m_parent = std::make_pair(p, true); } - void initialize_parent() const - { - m_parent = std::make_pair(vertex_handle(), false); - } - // for DFS -- end - - void add_neighbor(vertex_handle v) const + inline void add_neighbor(vertex_handle v) const { m_neighbors.insert(v); } - neighbor_iterator neighbors_begin() const + inline neighbor_iterator neighbors_begin() const { return m_neighbors.begin(); } - neighbor_iterator neighbors_end() const + inline neighbor_iterator neighbors_end() const { return m_neighbors.end(); } - bool operator<(graph_vertex const& other) const + inline bool operator<(graph_vertex const& other) const { if ( m_is_ip && other.m_is_ip ) { @@ -118,6 +106,13 @@ public: return other.m_is_ip; } + // for DFS -- start + inline int parent_id() const { return m_parent_id; } + inline void parent_id(int id) const { m_parent_id = id; } + inline bool visited() const { return m_visited; } + inline void visited(bool value) const { m_visited = value; } + // for DFS -- end + private: // the following bool determines the type of the vertex // true : vertex corresponds to an IP @@ -127,16 +122,36 @@ private: mutable int m_id; TurnPoint const& m_turn_point; mutable neighbor_container m_neighbors; - mutable std::pair m_parent; // for DFS - mutable bool m_visited; // for DFS + + // for DFS + mutable int m_parent_id; // set to -1 for no parent + mutable bool m_visited; +}; + +template +struct graph_vertex +{ + struct vertex_handle {}; + + template + struct rebind + { + typedef graph_vertex other; + }; }; -template + +template class complement_graph { private: - typedef std::set vertex_container; + typedef typename graph_vertex::template rebind + < + complement_graph + >::other vertex; + + typedef std::set vertex_container; public: typedef typename vertex_container::const_iterator vertex_handle; @@ -153,14 +168,14 @@ private: stack.pop(); v->visited(true); - for (typename Vertex::neighbor_iterator nit = v->neighbors_begin(); + for (typename vertex::neighbor_iterator nit = v->neighbors_begin(); nit != v->neighbors_end(); ++nit) { if ( (*nit)->id() != v->parent_id() ) { if ( !(*nit)->visited() ) { - (*nit)->parent(v); + (*nit)->parent_id(v->id()); stack.push(*nit); } else @@ -181,19 +196,19 @@ public: , m_vertices() {} - // inserts a ring vertex in the graph and returns its id - vertex_handle add_vertex(int ring_id) + // inserts a ring vertex in the graph and returns its handle + // ring id's are zero-based (so the first interior ring has id 1) + vertex_handle add_vertex(std::size_t id) { - Vertex v(static_cast(ring_id + 1)); - return m_vertices.insert(v).first; + return m_vertices.insert(vertex(id)).first; } // inserts an IP in the graph and returns its id - template vertex_handle add_vertex(TurnPoint const& turn_point) { - Vertex v(turn_point); - std::pair res = m_vertices.insert(v); + std::pair res + = m_vertices.insert(vertex(turn_point)); + if ( res.second ) { // a new element is inserted @@ -213,13 +228,15 @@ public: bool has_cycles() const { + // initialize all vertices as non-visited and with no parent set for (vertex_handle it = m_vertices.begin(); it != m_vertices.end(); ++it) { it->visited(false); - it->initialize_parent(); + it->parent_id(-1); } + // for each non-visited vertex, start a DFS from that vertex for (vertex_handle it = m_vertices.begin(); it != m_vertices.end(); ++it) { @@ -231,9 +248,9 @@ public: return false; } - template + template friend inline - void debug_print_complement_graph(OStream&, complement_graph const&); + void debug_print_complement_graph(OStream&, complement_graph const&); private: std::size_t m_num_rings, m_num_turns; diff --git a/include/boost/geometry/algorithms/detail/is_valid/debug_complement_graph.hpp b/include/boost/geometry/algorithms/detail/is_valid/debug_complement_graph.hpp index 83997a675..ec2a84e96 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/debug_complement_graph.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/debug_complement_graph.hpp @@ -22,11 +22,12 @@ namespace detail { namespace is_valid #ifdef BOOST_GEOMETRY_TEST_DEBUG -template -inline void debug_print_complement_graph(OutputStream& os, - complement_graph const& graph) +template +inline void +debug_print_complement_graph(OutputStream& os, + complement_graph const& graph) { - typedef typename complement_graph::vertex_handle vertex_handle; + typedef typename complement_graph::vertex_handle vertex_handle; os << "num rings: " << graph.m_num_rings << std::endl; os << "vertex ids: {"; @@ -41,7 +42,8 @@ inline void debug_print_complement_graph(OutputStream& os, it != graph.m_vertices.end(); ++it) { os << "neighbors of " << it->id() << ": {"; - for (typename Vertex::neighbor_iterator nit = it->neighbors_begin(); + for (typename complement_graph::vertex::neighbor_iterator + nit = it->neighbors_begin(); nit != it->neighbors_end(); ++nit) { os << " " << (*nit)->id(); @@ -50,9 +52,9 @@ inline void debug_print_complement_graph(OutputStream& os, } } #else -template +template void debug_print_complement_graph(OutputStream&, - complement_graph const&) + complement_graph const&) { } #endif