From 11ac1106537c9384d14bf869f8090795770ec7bb Mon Sep 17 00:00:00 2001 From: Denes Matetelki Date: Sun, 12 May 2013 13:50:28 +0200 Subject: [PATCH] Revert "reverting the allocator idea" This reverts commit 9a020e81e8768b1e10ee6e59f5c43700f9a43c12. --- graph.hpp | 169 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 69 deletions(-) diff --git a/graph.hpp b/graph.hpp index 6087332..859ef07 100644 --- a/graph.hpp +++ b/graph.hpp @@ -11,7 +11,8 @@ template + typename E = int, + typename Alloc = std::allocator > class Graph { private: @@ -49,10 +50,10 @@ public: typedef Edge& edge_reference; - 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; } - void swap(Graph& o) { std::swap (m_directed, o.m_directed); std::swap(m_vertices, o.m_vertices); } + Graph(bool isdirected = true) : m_directed(isdirected), m_vertices(), m_allocator(Alloc()) {} + Graph(const Graph& o) : m_directed(o.m_directed), m_vertices(o.m_vertices), m_allocator(o.m_allocator) {} + 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); std::swap(m_allocator, o.m_allocator);} // Properties bool directed() const { return m_directed; } @@ -183,10 +184,11 @@ private: struct Vertex { - Vertex(const_reference data) : m_data(m_data), m_edges() {} - Vertex(const Vertex& o) : m_data(o.m_data), m_edges(o.m_edges) {} + Vertex(const_reference data, Alloc allocator); + Vertex(const Vertex& o); + ~Vertex(); Vertex& operator=(Vertex o) { swap(o); return *this; } - void swap(Vertex& o) { std::swap(m_data, o.m_data); std::swap(m_edges, o.m_edges); } + void swap(Vertex& o) { std::swap(m_data, o.m_data); std::swap(m_edges, o.m_edges); std::swap(m_allocator, o.m_allocator);} bool operator==(const Vertex& other) const; @@ -197,6 +199,7 @@ private: pointer m_data; std::list m_edges; + Alloc& m_allocator; }; typename std::vector::const_iterator find(const_reference data) const; @@ -204,27 +207,28 @@ private: bool m_directed; std::vector m_vertices; + Alloc m_allocator; }; // Edge -template -inline Graph::Edge::Edge(pointer source, pointer destination, E 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); @@ -234,16 +238,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(); @@ -254,8 +258,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); @@ -263,8 +267,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) { @@ -279,8 +283,8 @@ inline Graph::edge_iterator::edge_iterator(std::vector vertices, b } } -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(); @@ -289,8 +293,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; @@ -312,21 +316,21 @@ void Graph::edge_iterator::advance(int n) // EdgeTo -template -inline Graph::EdgeTo::EdgeTo(const_reference destination, E 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; @@ -335,22 +339,49 @@ inline bool Graph::EdgeTo::operator==(const EdgeTo& other) const // Vertex -template -inline bool Graph::Vertex::operator==(const Vertex& other) const +template +inline Graph::Vertex::Vertex(const_reference data, Alloc allocator) + : m_data() + , m_edges() + , m_allocator(allocator) +{ + m_data = m_allocator.allocate(1); + m_allocator.construct(m_data, data); +} + +template +inline Graph::Vertex::Vertex(const Vertex& o) + : m_data() + , m_edges(o.m_edges) + , m_allocator(o.m_allocator) +{ + m_data = m_allocator.allocate(1); + m_allocator.construct(m_data, *(o.m_data)); +} + +template +inline Graph::Vertex::~Vertex() +{ + m_allocator.destroy(m_data); + m_allocator.deallocate(m_data, 1); +} + +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, E 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, E 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) @@ -358,18 +389,18 @@ inline void Graph::Vertex::removeEdge(const_reference destination, E weigh 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) @@ -381,26 +412,26 @@ inline std::vector::Edge> Graph::Vertex::edges() cons // 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; - m_vertices.push_back(Vertex(data)); + m_vertices.push_back(Vertex(data, m_allocator)); 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()) @@ -415,8 +446,8 @@ inline bool Graph::removeVertex(const_reference data) return true; } -template -bool Graph::addEdge(const_reference source, const_reference destination, E weight) +template +bool Graph::addEdge(const_reference source, const_reference destination, E weight) { typename std::vector::iterator source_it = find(source); if (source_it == m_vertices.end()) @@ -433,8 +464,8 @@ bool Graph::addEdge(const_reference source, const_reference destination, E return true; } -template -inline bool Graph::removeEdge(const_reference source, const_reference destination, E weight) +template +inline bool Graph::removeEdge(const_reference source, const_reference destination, E weight) { typename std::vector::iterator source_it = find(source); if (source_it == m_vertices.end()) @@ -451,8 +482,8 @@ inline bool Graph::removeEdge(const_reference source, const_reference dest 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()) @@ -469,8 +500,8 @@ inline bool Graph::removeAllEdges(const_reference source, const_reference return true; } -template -inline std::vector::pointer> Graph::vertices() const +template +inline std::vector::pointer> Graph::vertices() const { std::vector retval; std::for_each(m_vertices.begin(), m_vertices.end(), @@ -479,8 +510,8 @@ inline std::vector::pointer> Graph::vertices() const 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::const_iterator vertex_it = find(data); @@ -496,8 +527,8 @@ std::vector::pointer> Graph::neighboursOf(const_refer 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); @@ -512,10 +543,10 @@ std::vector Graph::edgesBetween(const_reference source, const_reference 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) @@ -527,16 +558,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)