From d631f1eae5fafb49ec1781edf258a398a5f3428b Mon Sep 17 00:00:00 2001 From: Denes Matetelki Date: Sun, 21 Apr 2013 20:58:38 +0200 Subject: [PATCH] Move semantics: assigment ops use swap --- graph.h | 69 +++++++++++++++++++++++++++++++++++++++++--------------- main.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 104 insertions(+), 31 deletions(-) diff --git a/graph.h b/graph.h index 291cb83..620a782 100644 --- a/graph.h +++ b/graph.h @@ -97,8 +97,8 @@ public: 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; } self_type &operator+=(difference_type n) { m_it += n; return *this; } - bool operator==(const_reference_self_type o) { return m_it == o.m_it; } - bool operator!=(const_reference_self_type o) { return !(*this == o); } + bool operator==(const_reference_self_type o) const { return m_it == o.m_it; } + bool operator!=(const_reference_self_type o) const { return !(*this == o); } private: vertex_iterator(typename std::vector::iterator it) : m_it(it) {} @@ -127,7 +127,8 @@ public: 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(0) {} - reference_self_type operator=(const_reference_self_type o); + + reference_self_type operator=(self_type o); edge_reference operator*() { resetEdge(); return *m_edge; } edge_pointer operator->() { resetEdge(); return m_edge; } @@ -136,17 +137,31 @@ public: self_type operator++(int) { self_type tmp(*this); advance(1); return tmp; } self_type operator+(difference_type n) { self_type tmp(*this); tmp.pos_ += n; return tmp; } self_type &operator+=(difference_type n) { advance(n); return *this; } - bool operator==(const_reference_self_type o) - { return (m_vertex_it == m_vertices.end() && o.m_vertex_it == o.m_vertices.end()) || - (m_vertex_it == o.m_vertex_it && m_edge_it == o.m_edge_it); } - bool operator!=(const_reference_self_type o) { return !(*this == o); } + bool 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(); + if ( this_is_at_end && other_is_at_end ) return true; + if ( this_is_at_end != other_is_at_end ) return false; + + return *m_vertex_it == *(o.m_vertex_it) && + *m_edge_it == *(o.m_edge_it); + + } + bool operator!=(const_reference_self_type o) const { return !(*this == o); } + + void swap(reference_self_type other); private: edge_iterator(std::vector vertices, bool begin = true) : m_vertices(vertices), m_vertex_it(), m_edge_it(), m_edge(0) { if (begin) { m_vertex_it = m_vertices.begin(); - if (!m_vertices.empty()) m_edge_it = (*m_vertex_it).m_edges.begin(); + while (m_vertex_it != m_vertices.end() && m_vertices.empty()) + ++m_vertex_it; + + if (m_vertex_it != m_vertices.end()) + m_edge_it = (*m_vertex_it).m_edges.begin(); } else { m_vertex_it = m_vertices.end(); } @@ -172,6 +187,7 @@ private: EdgeTo(const_reference destination, float weight = 0); EdgeTo(const EdgeTo& other); EdgeTo& operator=(const EdgeTo& other); + bool operator==(const EdgeTo& other) const; pointer m_destination; float m_weight; @@ -182,6 +198,7 @@ private: Vertex(const_reference data); Vertex(const Vertex& other); Vertex& operator=(const Vertex& other); + bool operator==(const Vertex& other) const; void addEdge(const_reference destination, float weight = 0); void removeEdge(const_reference destination, float weight = 0); void removeAllEdgesTo(const_reference destination); @@ -205,25 +222,28 @@ private: template typename Graph::edge_iterator::reference_self_type -Graph::edge_iterator::operator=(const_reference_self_type o) +Graph::edge_iterator::operator=(self_type o) { - if (this != &o) { - m_vertices = o.m_vertices; - m_vertex_it = o.m_vertex_it; - m_edge_it = o.m_edge_it; - } - + swap(o); return *this; } +template +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); + std::swap(m_edge_it, other.m_edge_it); + std::swap(m_edge, other.m_edge); +} + template void Graph::edge_iterator::resetEdge() { if (m_edge) delete m_edge; - if (m_vertex_it == m_vertices.end() || - (*m_vertex_it).m_edges.empty()) { + if (m_vertex_it == m_vertices.end() || (*m_vertex_it).m_edges.empty()) { m_edge = 0; return; } @@ -235,6 +255,7 @@ void Graph::edge_iterator::resetEdge() m_edge = new Edge(source, destination, weight); } +/// @todo Rewrite it to be more simple template void Graph::edge_iterator::advance(int n) { @@ -292,6 +313,11 @@ typename Graph::EdgeTo& Graph::EdgeTo::operator=(const EdgeTo& other) return *this; } +template +bool Graph::EdgeTo::operator==(const EdgeTo& other) const +{ + return m_destination == other.m_destination && m_weight == other.m_weight; +} // Vertex @@ -316,13 +342,20 @@ typename Graph::Vertex& Graph::Vertex::operator=(const Vertex& other) { if (this != &other) { m_data = other.m_data; - m_edges.clear(); m_edges = other.m_edges; } return *this; } +template +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 void Graph::Vertex::addEdge(const_reference destination, float weight) { diff --git a/main.cpp b/main.cpp index 6530062..3971291 100644 --- a/main.cpp +++ b/main.cpp @@ -63,12 +63,18 @@ int main() assert(g.numberOfVertices() == 4); int vertices_array[] = {2, 5, 13, 1}; std::vector v(vertices_array, vertices_array + sizeof(vertices_array) / sizeof(int) ); - Graph::vertex_iterator g_it; - std::vector::iterator v_it; + Graph::vertex_iterator g_it2; + std::vector::iterator v_it = v.begin(); + g_it2 = g.vertex_begin(); + assert(g_it2 == g.vertex_begin()); - for (g_it = g.vertex_begin(), v_it = v.begin(); + for (Graph::vertex_iterator g_it = g.vertex_begin(); g_it != g.vertex_end(); - g_it++, v_it++) { + ++g_it, ++v_it) { + std::cout << "victor: " +// << *g_it << " " + << **g_it + << std::endl; assert(**g_it == *v_it); } @@ -83,11 +89,12 @@ int main() int vertices_array2[] = {1, 2, 3, 4}; std::vector v2(vertices_array2, vertices_array2 + sizeof(vertices_array2) / sizeof(int) ); - for (g_it = g2.vertex_begin(), v_it = v2.begin(); + v_it = v2.begin(); + for (Graph::vertex_iterator g_it = g2.vertex_begin(); g_it != g2.vertex_end(); - g_it++, v_it++) { + ++g_it, ++v_it) { std::cout << "vector: " - << *g_it << " " +// << *g_it << " " << **g_it << std::endl; assert(**g_it == *v_it); @@ -98,20 +105,53 @@ int main() assert(g2.addEdge(1, 3) == true); assert(g2.addEdge(2, 4) == true); std::vector::Edge> e = g2.edges(); - assert(e.size() == 3); - for(Graph::edge_iterator edge_it = g2.edge_begin(); - edge_it != g2.edge_end(); - ++edge_it) { + Graph::edge_iterator edge_it; + Graph::edge_iterator beee = g2.edge_begin(); + edge_it = beee; + assert(edge_it == g2.edge_begin()); + Graph::pointer source = (*edge_it).getSource(); + Graph::pointer destination = (*edge_it).getDestination(); + assert (*source == 1); + assert (*destination == 2); + + ++edge_it; + source = (*edge_it).getSource(); + destination = (*edge_it).getDestination(); + assert (*source == 1); + assert (*destination == 3); + + ++edge_it; + source = (*edge_it).getSource(); + destination = (*edge_it).getDestination(); + assert (*source == 2); + assert (*destination == 4); + + int aasdads = 23; +// Graph::edge_iterator edge_it; + + for(/*Graph::edge_iterator*/ edge_it = g2.edge_begin(); edge_it != g2.edge_end(); ++edge_it) { Graph::pointer source = (*edge_it).getSource(); Graph::pointer destination = (*edge_it).getDestination(); std::cout << "edge: " - << source << " " << *source << " " - << destination << " " << *destination << " " +// << source << " " + << *source << " " +// << destination << " " + << *destination << " " << (*edge_it).getWeight() << std::endl; } + Graph::edge_iterator edge_it1 = g2.edge_begin(); + edge_it1 += 10; + assert(edge_it1 == g2.edge_end()); + + Graph::edge_iterator edge_it2 = g2.edge_begin(); + edge_it2 += 2; + assert(*((*edge_it2).getSource()) == 2); + assert(*((*edge_it2).getDestination()) == 4); + assert((*edge_it2).getWeight() == 0); + std::cout << "frankon vege" << std::endl; return 0; }