From a425bb9b7c6e6f53cf6cadfa80ceca4161732be5 Mon Sep 17 00:00:00 2001 From: Justin Viiret Date: Fri, 14 Jul 2017 14:51:53 +1000 Subject: [PATCH] ue2_graph: move descriptors out of graph struct --- src/util/ue2_graph.h | 150 ++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 73 deletions(-) diff --git a/src/util/ue2_graph.h b/src/util/ue2_graph.h index 138d7467..1409e091 100644 --- a/src/util/ue2_graph.h +++ b/src/util/ue2_graph.h @@ -168,7 +168,78 @@ struct default_vertex_property { size_t index; }; -} +template +class vertex_descriptor : totally_ordered> { + using vertex_node = typename Graph::vertex_node; +public: + vertex_descriptor() : p(nullptr), serial(0) {} + explicit vertex_descriptor(vertex_node *pp) : p(pp), serial(pp->serial) {} + + operator bool() const { return p; } + bool operator<(const vertex_descriptor b) const { + if (p && b.p) { + /* no vertices in the same graph can have the same serial */ + assert(p == b.p || serial != b.serial); + return serial < b.serial; + } else { + return p < b.p; + } + } + bool operator==(const vertex_descriptor b) const { return p == b.p; } + + friend size_t hash_value(vertex_descriptor v) { + using boost::hash_value; + return hash_value(v.serial); + } + +private: + vertex_node *raw(void) { return p; } + vertex_node *p; + u64a serial; + friend Graph; +}; + +template +class edge_descriptor : totally_ordered> { + using edge_node = typename Graph::edge_node; +public: + edge_descriptor() : p(nullptr), serial(0) {} + explicit edge_descriptor(edge_node *pp) : p(pp), serial(pp->serial) {} + + /* Convenience ctor to allow us to directly get an edge_descriptor from + * edge() and add_edge(). As we have null_edges and we always allow + * parallel edges, the bool component of the return from these functions is + * not required. */ + edge_descriptor(const std::pair &tup) + : p(tup.first.p), serial(tup.first.serial) { + assert(tup.second == (bool)tup.first); + } + + operator bool() const { return p; } + bool operator<(const edge_descriptor b) const { + if (p && b.p) { + /* no edges in the same graph can have the same serial */ + assert(p == b.p || serial != b.serial); + return serial < b.serial; + } else { + return p < b.p; + } + } + bool operator==(const edge_descriptor b) const { return p == b.p; } + + friend size_t hash_value(edge_descriptor e) { + using boost::hash_value; + return hash_value(e.serial); + } + +private: + edge_node *raw(void) { return p; } + edge_node *p; + u64a serial; + friend Graph; +}; + +} // namespace graph_detail template; + using edge_descriptor = graph_detail::edge_descriptor; + friend vertex_descriptor; + friend edge_descriptor; + using vertices_size_type = typename vertices_list_type::size_type; using degree_size_type = typename vertex_edge_list::size_type; @@ -293,78 +369,6 @@ public: using vertex_bundled = VertexPropertyType; using edge_bundled = EdgePropertyType; - class vertex_descriptor : totally_ordered { - public: - vertex_descriptor() : p(nullptr), serial(0) { } - explicit vertex_descriptor(vertex_node *pp) - : p(pp), serial(pp->serial) { } - - operator bool() const { return p; } - bool operator<(const vertex_descriptor b) const { - if (p && b.p) { - /* no vertices in the same graph can have the same serial */ - assert(p == b.p || serial != b.serial); - return serial < b.serial; - } else { - return p < b.p; - } - } - bool operator==(const vertex_descriptor b) const { - return p == b.p; - } - - friend size_t hash_value(vertex_descriptor v) { - using boost::hash_value; - return hash_value(v.serial); - } - - private: - vertex_node *raw(void) { return p; } - vertex_node *p; - u64a serial; - friend ue2_graph; - }; - - class edge_descriptor : totally_ordered { - public: - edge_descriptor() : p(nullptr), serial(0) { } - explicit edge_descriptor(edge_node *pp) : p(pp), serial(pp->serial) { } - - /* Convenice ctor to allow us to directly get an edge_descriptor from - * edge() and add_edge(). As we have null_edges and we always allow - * parallel edges, the bool component of the return from these functions - * is not required. */ - edge_descriptor(const std::pair &tup) - : p(tup.first.p), serial(tup.first.serial) { - assert(tup.second == (bool)tup.first); - } - - operator bool() const { return p; } - bool operator<(const edge_descriptor b) const { - if (p && b.p) { - /* no edges in the same graph can have the same serial */ - assert(p == b.p || serial != b.serial); - return serial < b.serial; - } else { - return p < b.p; - } - } - bool operator==(const edge_descriptor b) const { - return p == b.p; - } - - friend size_t hash_value(edge_descriptor e) { - using boost::hash_value; - return hash_value(e.serial); - } - - private: - edge_node *raw(void) { return p; } - edge_node *p; - u64a serial; - friend ue2_graph; - }; - private: /* Note: apparently, nested class templates cannot be fully specialised but * they can be partially specialised. Sigh, ... */