From 4a0843ed82ba2b8ef23397bb3f2de56a1d2db9c5 Mon Sep 17 00:00:00 2001 From: dmatetelki Date: Fri, 9 May 2014 13:28:20 +0200 Subject: [PATCH] Removing the allocators. --- lib/graph/graph.hpp | 254 +++++++++++++++++++++----------------------- 1 file changed, 121 insertions(+), 133 deletions(-) diff --git a/lib/graph/graph.hpp b/lib/graph/graph.hpp index 1483546..2a63ae8 100644 --- a/lib/graph/graph.hpp +++ b/lib/graph/graph.hpp @@ -6,13 +6,13 @@ #include #include +#include // accumulate #include #include template > + typename E = int> class Graph { private: @@ -34,19 +34,19 @@ public: public: Edge() : m_source(0), m_destination(0), m_weight() {} - Edge(pointer source, pointer destination, E weight); + Edge(const_pointer source, const_pointer destination, const E& weight); Edge(const Edge& o); Edge& operator=(Edge o) { swap(o); return *this; } void swap(Edge& o); - reference getSource() const { return *m_source; } - reference getDestination() const { return *m_destination; } + const_reference getSource() const { return *m_source; } + const_reference getDestination() const { return *m_destination; } E getWeight() const { return m_weight; } private: - pointer m_source; - pointer m_destination; + const_pointer m_source; + const_pointer m_destination; E m_weight; }; @@ -54,10 +54,10 @@ public: typedef Edge& edge_reference; - 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);} + 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); } // Properties bool directed() const { return m_directed; } @@ -77,12 +77,14 @@ public: // Lookup bool contains(const_reference data) const { return find(data) != m_vertices.end(); } - std::vector vertices() const; - std::vector neighboursOf(const_reference data) const; + std::vector vertices() const; + std::vector neighboursOf(const_reference data) const; std::vector weightsBetween(const_reference source, const_reference destination) const; std::vector edges() const; // iterators + + /// @todo make it random access class vertex_iterator : public std::iterator() { return (*m_it).m_data; } + reference operator*() { return (*m_it).m_data; } + pointer operator->() { return &(*m_it).m_data; } self_type &operator++() { ++m_it; return *this; } self_type operator++(int) { self_type tmp(*this); ++(*this); return tmp; } self_type operator+(difference_type n) { self_type tmp(*this); tmp.pos_ += n; return tmp; } @@ -115,7 +117,8 @@ public: vertex_iterator(typename std::vector::iterator it) : m_it(it) {} vertex_iterator(typename std::vector::const_iterator it) : m_it(it) {} - typename std::vector::const_iterator m_it; +// typename std::vector::const_iterator m_it; + typename std::vector::iterator m_it; }; vertex_iterator vertex_begin() { return vertex_iterator(m_vertices.begin()); } @@ -173,7 +176,7 @@ private: struct EdgeTo { - EdgeTo(const_reference destination, E weight = E()); + EdgeTo(const_pointer 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); @@ -186,22 +189,20 @@ private: struct Vertex { - Vertex(const_reference data, Alloc allocator); - Vertex(const Vertex& o); - ~Vertex(); + Vertex(const_reference data) : m_data(data), m_edges() {} + Vertex(const Vertex& o) : m_data(o.m_data), m_edges(o.m_edges) {} 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); std::swap(m_allocator, o.m_allocator);} + void swap(Vertex& o) { std::swap(m_data, o.m_data); std::swap(m_edges, o.m_edges);} bool operator==(const Vertex& other) const; - void addEdge(const_reference destination, E weight = E()); + void addEdge(const_pointer destination, E weight = E()); void removeEdge(const_reference destination, E weight = E()); void removeAllEdgesTo(const_reference destination); std::vector edges() const; - pointer m_data; + value_type m_data; std::list m_edges; - Alloc& m_allocator; }; typename std::vector::const_iterator find(const_reference data) const; @@ -209,28 +210,27 @@ 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(const_pointer source, const_pointer destination, const 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); @@ -240,16 +240,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(); @@ -260,8 +260,8 @@ bool Graph::edge_iterator::operator==(const_reference_self_type o) *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); @@ -269,8 +269,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) { @@ -285,18 +285,18 @@ inline Graph::edge_iterator::edge_iterator(std::vector vert } } -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(); } else { - m_edge = Edge((*m_vertex_it).m_data, (*m_edge_it).m_destination, (*m_edge_it).m_weight); + m_edge = Edge( &(*m_vertex_it).m_data, (*m_edge_it).m_destination, (*m_edge_it).m_weight); } } -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; @@ -317,22 +317,21 @@ void Graph::edge_iterator::advance(int n) } // EdgeTo - -template -inline Graph::EdgeTo::EdgeTo(const_reference destination, E weight) - : m_destination(const_cast(&destination)) +template +inline Graph::EdgeTo::EdgeTo(const_pointer 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; @@ -341,49 +340,22 @@ inline bool Graph::EdgeTo::operator==(const EdgeTo& other) const // Vertex -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 +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_pointer 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) @@ -391,65 +363,80 @@ inline void Graph::Vertex::removeEdge(const_reference destination, 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; +#ifdef _GLIBCXX_PARALLEL + for (auto& e : m_edges) + retval.push_back(Edge( &m_data, e.m_destination, e.m_weight)); +#else std::for_each(m_edges.begin(), m_edges.end(), [&retval, this](const EdgeTo& e) - { retval.push_back(Edge(this->m_data, e.m_destination, e.m_weight)); }); - + { retval.push_back(Edge( &this->m_data, e.m_destination, e.m_weight)); }); +#endif return retval; } // Graph -template -inline typename Graph::size_type Graph::numberOfEdges() const +template +inline typename Graph::size_type Graph::numberOfEdges() const { +#ifdef _GLIBCXX_PARALLEL + + int sum = 0; + for (typename std::vector::const_iterator cit = m_vertices.begin(); cit != m_vertices.end(); ++cit) + sum += (*cit).m_edges.size(); + + return sum; + +#else + + /// @bug does not work with parallel mode return std::accumulate(m_vertices.begin(), m_vertices.end(), 0, [](int sum, const Vertex& v) { return sum + v.m_edges.size(); }); +#endif } -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_allocator)); + m_vertices.push_back(Vertex(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()) return false; - std::vector neighbours = neighboursOf(data); + std::vector neighbours = neighboursOf(data); std::for_each(neighbours.begin(), neighbours.end(), - [this, &data] (const_pointer vertex) - { this->removeAllEdges(*vertex, data); } ); + [this, &data] (const_reference vertex) + { this->removeAllEdges(vertex, data); } ); m_vertices.erase(it); 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()) @@ -459,15 +446,15 @@ bool Graph::addEdge(const_reference source, const_reference destina if (destination_it == m_vertices.end()) return false; - (*source_it).addEdge(destination, weight); + (*source_it).addEdge( &(*destination_it).m_data, weight); if (!m_directed) - (*destination_it).addEdge(source, weight); + (*destination_it).addEdge( &(*source_it).m_data, weight); 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()) @@ -484,8 +471,8 @@ inline bool Graph::removeEdge(const_reference source, const_referen 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()) @@ -502,35 +489,35 @@ inline bool Graph::removeAllEdges(const_reference source, const_ref return true; } -template -inline std::vector::const_pointer> Graph::vertices() const +template +inline std::vector::value_type> 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::const_pointer> Graph::neighboursOf(const_reference data) const +template +std::vector::value_type> 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; - std::set tmp; + std::set tmp; std::for_each((*vertex_it).m_edges.begin(), (*vertex_it).m_edges.end(), [&tmp, &retval](const EdgeTo& e) - { if (tmp.insert(e.m_destination).second) - retval.push_back(e.m_destination); }); + { if (tmp.insert(*e.m_destination).second) + retval.push_back(*e.m_destination); }); return retval; } -template -std::vector Graph::weightsBetween(const_reference source, const_reference destination) const +template +std::vector Graph::weightsBetween(const_reference source, const_reference destination) const { std::vector retval; typename std::vector::const_iterator vertex_it = find(source); @@ -545,10 +532,10 @@ std::vector Graph::weightsBetween(const_reference source, const_ 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) @@ -560,22 +547,23 @@ inline std::vector::Edge> Graph::edges( } -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; }); + { return v.m_data == data; }); } -template -inline typename std::vector::Vertex >::iterator -Graph::find(const_reference data) +/// @todo call the const it version +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) - { return *(v.m_data) == data; }); + { return v.m_data == data; }); }