From c6f9a544e35b8e52ec9d85b491e8d3c4785fdb88 Mon Sep 17 00:00:00 2001 From: Denes Matetelki Date: Mon, 6 May 2013 20:25:55 +0200 Subject: [PATCH] Edge weight is a template parameter now --- graph.hpp | 157 +++++++++++++++++++++++++++--------------------------- 1 file changed, 79 insertions(+), 78 deletions(-) diff --git a/graph.hpp b/graph.hpp index b58fbf2..3e018b1 100644 --- a/graph.hpp +++ b/graph.hpp @@ -10,7 +10,8 @@ // directed, weighted /// @todo weight type as param too? -template +template class Graph { private: @@ -20,28 +21,28 @@ private: public: typedef size_t size_type; - typedef T value_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; + typedef V value_type; + typedef V* pointer; + typedef const V* const_pointer; + typedef V& reference; + typedef const V& const_reference; typedef std::ptrdiff_t difference_type; struct Edge { - Edge() : m_source(0), m_destination(0), m_weight(0) {} - Edge(pointer source, pointer destination, float weight); + Edge() : m_source(0), m_destination(0), m_weight() {} + Edge(pointer source, pointer destination, E weight); Edge(const Edge& o); Edge& operator=(Edge o) { swap(o); return *this; } void swap(Edge& o); pointer getSource() const { return m_source; } pointer getDestination() const { return m_destination; } - float getWeight() const { return m_weight; } + E getWeight() const { return m_weight; } pointer m_source; pointer m_destination; - float m_weight; + E m_weight; }; typedef Edge* edge_pointer; @@ -49,8 +50,8 @@ public: Graph(bool isdirected = true) : m_directed(isdirected), m_vertices() {} - Graph(const Graph& o) : m_directed(o.m_directed), m_vertices(o.m_vertices) {} - Graph& operator=(Graph o) { swap(o); return *this; } + Graph(const Graph& o) : m_directed(o.m_directed), m_vertices(o.m_vertices) {} + Graph& operator=(Graph o) { swap(o); return *this; } void swap(Graph& o) { std::swap (m_directed, o.m_directed); std::swap(m_vertices, o.m_vertices); } // Properties @@ -168,7 +169,7 @@ private: struct EdgeTo { - EdgeTo(const_reference destination, float weight = 0); + EdgeTo(const_reference destination, E weight = E()); EdgeTo(const EdgeTo& o) : m_destination(o.m_destination), m_weight(o.m_weight) {} EdgeTo& operator=(EdgeTo o) { swap(o); return *this; } void swap(EdgeTo& o); @@ -176,7 +177,7 @@ private: bool operator==(const EdgeTo& other) const; pointer m_destination; - float m_weight; + E m_weight; }; struct Vertex { @@ -188,8 +189,8 @@ private: bool operator==(const Vertex& other) const; - void addEdge(const_reference destination, float weight = 0); - void removeEdge(const_reference destination, float weight = 0); + void addEdge(const_reference destination, E weight = E()); + void removeEdge(const_reference destination, E weight = E()); void removeAllEdgesTo(const_reference destination); std::vector edges() const; @@ -207,22 +208,22 @@ private: // Edge -template -inline Graph::Edge::Edge(pointer source, pointer destination, float weight) +template +inline Graph::Edge::Edge(pointer source, pointer destination, E weight) : m_source(source) , m_destination(destination) , m_weight(weight) {} -template -inline Graph::Edge::Edge(const Edge& o) +template +inline Graph::Edge::Edge(const Edge& o) : m_source(o.m_source) , m_destination(o.m_destination) , m_weight(o.m_weight) {} -template -inline void Graph::Edge::swap(Edge& o) +template +inline void Graph::Edge::swap(Edge& o) { std::swap(m_source, o.m_source); std::swap(m_destination, o.m_destination); @@ -232,16 +233,16 @@ inline void Graph::Edge::swap(Edge& o) // edge iterator -template -inline Graph::edge_iterator::edge_iterator(const_reference_self_type o) +template +inline Graph::edge_iterator::edge_iterator(const_reference_self_type o) : m_vertices(o.m_vertices) , m_vertex_it(o.m_vertex_it) , m_edge_it(o.m_edge_it) , m_edge() {} -template -bool Graph::edge_iterator::operator==(const_reference_self_type o) const +template +bool Graph::edge_iterator::operator==(const_reference_self_type o) const { const bool this_is_at_end = m_vertex_it == m_vertices.end(); const bool other_is_at_end = o.m_vertex_it == o.m_vertices.end(); @@ -252,8 +253,8 @@ bool Graph::edge_iterator::operator==(const_reference_self_type o) const *m_edge_it == *(o.m_edge_it); } -template -inline void Graph::edge_iterator::swap(reference_self_type other) +template +inline void Graph::edge_iterator::swap(reference_self_type other) { std::swap(m_vertices, other.m_vertices); std::swap(m_vertex_it, other.m_vertex_it); @@ -261,8 +262,8 @@ inline void Graph::edge_iterator::swap(reference_self_type other) std::swap(m_edge, other.m_edge); } -template -inline Graph::edge_iterator::edge_iterator(std::vector vertices, bool begin) +template +inline Graph::edge_iterator::edge_iterator(std::vector vertices, bool begin) : m_vertices(vertices), m_vertex_it(), m_edge_it(), m_edge() { if (begin) { @@ -277,8 +278,8 @@ inline Graph::edge_iterator::edge_iterator(std::vector vertices, bool } } -template -inline void Graph::edge_iterator::resetEdge() +template +inline void Graph::edge_iterator::resetEdge() { if (m_vertex_it == m_vertices.end() || (*m_vertex_it).m_edges.empty()) { m_edge = Edge(); @@ -287,8 +288,8 @@ inline void Graph::edge_iterator::resetEdge() } } -template -void Graph::edge_iterator::advance(int n) +template +void Graph::edge_iterator::advance(int n) { while (n > 0 && m_vertex_it != m_vertices.end()) { const int edgesAhead = std::distance(m_edge_it, (*m_vertex_it).m_edges.end()) - 1; @@ -310,21 +311,21 @@ void Graph::edge_iterator::advance(int n) // EdgeTo -template -inline Graph::EdgeTo::EdgeTo(const_reference destination, float weight) +template +inline Graph::EdgeTo::EdgeTo(const_reference destination, E weight) : m_destination(const_cast(&destination)) , m_weight(weight) {} -template -inline void Graph::EdgeTo::swap(EdgeTo& o) +template +inline void Graph::EdgeTo::swap(EdgeTo& o) { std::swap(m_destination, o.m_destination); std::swap(m_weight, o.m_weight); } -template -inline bool Graph::EdgeTo::operator==(const EdgeTo& other) const +template +inline bool Graph::EdgeTo::operator==(const EdgeTo& other) const { return m_destination == other.m_destination && m_weight == other.m_weight; @@ -333,22 +334,22 @@ inline bool Graph::EdgeTo::operator==(const EdgeTo& other) const // Vertex -template -inline bool Graph::Vertex::operator==(const Vertex& other) const +template +inline bool Graph::Vertex::operator==(const Vertex& other) const { return m_data == other.m_data && m_edges.size() == other.m_edges.size() && m_edges == other.m_edges; } -template -inline void Graph::Vertex::addEdge(const_reference destination, float weight) +template +inline void Graph::Vertex::addEdge(const_reference destination, E weight) { m_edges.push_back(EdgeTo(destination, weight)); } -template -inline void Graph::Vertex::removeEdge(const_reference destination, float weight) +template +inline void Graph::Vertex::removeEdge(const_reference destination, E weight) { m_edges.erase(std::find_if(m_edges.begin(), m_edges.end(), [&destination, &weight](const EdgeTo& e) @@ -356,18 +357,18 @@ inline void Graph::Vertex::removeEdge(const_reference destination, float weig e.m_weight == weight;})); } -template -inline void Graph::Vertex::removeAllEdgesTo(const_reference destination) +template +inline void Graph::Vertex::removeAllEdgesTo(const_reference destination) { std::remove_if(m_edges.begin(), m_edges.end(), [&destination](const EdgeTo& e) { return *e.m_destination == destination; }); } -template -inline std::vector::Edge> Graph::Vertex::edges() const +template +inline std::vector::Edge> Graph::Vertex::edges() const { - std::vector::Edge> retval; + std::vector::Edge> retval; std::for_each(m_edges.begin(), m_edges.end(), [&retval, this](const EdgeTo& e) @@ -379,16 +380,16 @@ inline std::vector::Edge> Graph::Vertex::edges() const // Graph -template -inline typename Graph::size_type Graph::numberOfEdges() const +template +inline typename Graph::size_type Graph::numberOfEdges() const { return std::accumulate(m_vertices.begin(), m_vertices.end(), 0, [](int sum, const Vertex& v) { return sum + v.m_edges.size(); }); } -template -inline bool Graph::addVertex(const_reference data) +template +inline bool Graph::addVertex(const_reference data) { if (find(data) != m_vertices.end()) return false; @@ -397,8 +398,8 @@ inline bool Graph::addVertex(const_reference data) return true; } -template -inline bool Graph::removeVertex(const_reference data) +template +inline bool Graph::removeVertex(const_reference data) { typename std::vector::iterator it = find(data); if (it == m_vertices.end()) @@ -413,8 +414,8 @@ inline bool Graph::removeVertex(const_reference data) return true; } -template -bool Graph::addEdge(const_reference source, const_reference destination, float weight) +template +bool Graph::addEdge(const_reference source, const_reference destination, float weight) { typename std::vector::iterator source_it = find(source); if (source_it == m_vertices.end()) @@ -431,8 +432,8 @@ bool Graph::addEdge(const_reference source, const_reference destination, floa return true; } -template -inline bool Graph::removeEdge(const_reference source, const_reference destination, float weight) +template +inline bool Graph::removeEdge(const_reference source, const_reference destination, float weight) { typename std::vector::iterator source_it = find(source); if (source_it == m_vertices.end()) @@ -449,8 +450,8 @@ inline bool Graph::removeEdge(const_reference source, const_reference destina return true; } -template -inline bool Graph::removeAllEdges(const_reference source, const_reference destination) +template +inline bool Graph::removeAllEdges(const_reference source, const_reference destination) { typename std::vector::iterator source_it = find(source); if (source_it == m_vertices.end()) @@ -467,20 +468,20 @@ inline bool Graph::removeAllEdges(const_reference source, const_reference des return true; } -template -inline std::vector::pointer> Graph::vertices() const +template +inline std::vector::pointer> Graph::vertices() const { - std::vector retval; + std::vector retval; std::for_each(m_vertices.begin(), m_vertices.end(), [&retval](const Vertex& v) { retval.push_back(v.m_data); }); return retval; } -template -std::vector::pointer> Graph::neighboursOf(const_reference data) const +template +std::vector::pointer> Graph::neighboursOf(const_reference data) const { - typename std::vector retval; + typename std::vector retval; typename std::vector::const_iterator vertex_it = find(data); if (vertex_it == m_vertices.end()) return retval; @@ -492,8 +493,8 @@ std::vector::pointer> Graph::neighboursOf(const_reference d return retval; } -template -std::vector Graph::edgesBetween(const_reference source, const_reference destination) const +template +std::vector Graph::edgesBetween(const_reference source, const_reference destination) const { std::vector retval; typename std::vector::const_iterator vertex_it = find(source); @@ -508,10 +509,10 @@ std::vector Graph::edgesBetween(const_reference source, const_referenc return retval; } -template -inline std::vector::Edge> Graph::edges() const +template +inline std::vector::Edge> Graph::edges() const { - std::vector::Edge> retval; + std::vector::Edge> retval; std::for_each(m_vertices.begin(), m_vertices.end(), [&retval](const Vertex& v) @@ -523,16 +524,16 @@ inline std::vector::Edge> Graph::edges() const } -template -inline typename std::vector::Vertex >::const_iterator Graph::find(const_reference data) const +template +inline typename std::vector::Vertex >::const_iterator Graph::find(const_reference data) const { return std::find_if(m_vertices.begin(), m_vertices.end(), [&data](const Vertex& v) { return *(v.m_data) == data; }); } -template -inline typename std::vector::Vertex >::iterator Graph::find(const_reference data) +template +inline typename std::vector::Vertex >::iterator Graph::find(const_reference data) { return std::find_if(m_vertices.begin(), m_vertices.end(), [&data](const Vertex& v)