Move semantics: assigment ops use swap

for/release
Denes Matetelki 12 years ago
parent 9afcf3fc5b
commit d631f1eae5

@ -97,8 +97,8 @@ public:
self_type operator++(int) { self_type tmp(*this); ++(*this); return tmp; } 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) { self_type tmp(*this); tmp.pos_ += n; return tmp; }
self_type &operator+=(difference_type n) { m_it += n; return *this; } 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) const { 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 !(*this == o); }
private: private:
vertex_iterator(typename std::vector<Vertex>::iterator it) : m_it(it) {} vertex_iterator(typename std::vector<Vertex>::iterator it) : m_it(it) {}
@ -127,7 +127,8 @@ public:
edge_iterator(const_reference_self_type o) 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) {} : 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_reference operator*() { resetEdge(); return *m_edge; }
edge_pointer 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++(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) { self_type tmp(*this); tmp.pos_ += n; return tmp; }
self_type &operator+=(difference_type n) { advance(n); return *this; } self_type &operator+=(difference_type n) { advance(n); return *this; }
bool operator==(const_reference_self_type o) bool operator==(const_reference_self_type o) const
{ 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); } const bool this_is_at_end = m_vertex_it == m_vertices.end();
bool operator!=(const_reference_self_type o) { return !(*this == o); } 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: private:
edge_iterator(std::vector<Vertex> vertices, bool begin = true) edge_iterator(std::vector<Vertex> vertices, bool begin = true)
: m_vertices(vertices), m_vertex_it(), m_edge_it(), m_edge(0) { : m_vertices(vertices), m_vertex_it(), m_edge_it(), m_edge(0) {
if (begin) { if (begin) {
m_vertex_it = m_vertices.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 { } else {
m_vertex_it = m_vertices.end(); m_vertex_it = m_vertices.end();
} }
@ -172,6 +187,7 @@ private:
EdgeTo(const_reference destination, float weight = 0); EdgeTo(const_reference destination, float weight = 0);
EdgeTo(const EdgeTo& other); EdgeTo(const EdgeTo& other);
EdgeTo& operator=(const EdgeTo& other); EdgeTo& operator=(const EdgeTo& other);
bool operator==(const EdgeTo& other) const;
pointer m_destination; pointer m_destination;
float m_weight; float m_weight;
@ -182,6 +198,7 @@ private:
Vertex(const_reference data); Vertex(const_reference data);
Vertex(const Vertex& other); Vertex(const Vertex& other);
Vertex& operator=(const Vertex& other); Vertex& operator=(const Vertex& other);
bool operator==(const Vertex& other) const;
void addEdge(const_reference destination, float weight = 0); void addEdge(const_reference destination, float weight = 0);
void removeEdge(const_reference destination, float weight = 0); void removeEdge(const_reference destination, float weight = 0);
void removeAllEdgesTo(const_reference destination); void removeAllEdgesTo(const_reference destination);
@ -205,25 +222,28 @@ private:
template <typename T> template <typename T>
typename Graph<T>::edge_iterator::reference_self_type typename Graph<T>::edge_iterator::reference_self_type
Graph<T>::edge_iterator::operator=(const_reference_self_type o) Graph<T>::edge_iterator::operator=(self_type o)
{ {
if (this != &o) { swap(o);
m_vertices = o.m_vertices;
m_vertex_it = o.m_vertex_it;
m_edge_it = o.m_edge_it;
}
return *this; return *this;
} }
template <typename T>
void Graph<T>::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 <typename T> template <typename T>
void Graph<T>::edge_iterator::resetEdge() void Graph<T>::edge_iterator::resetEdge()
{ {
if (m_edge) delete m_edge; if (m_edge) delete m_edge;
if (m_vertex_it == m_vertices.end() || if (m_vertex_it == m_vertices.end() || (*m_vertex_it).m_edges.empty()) {
(*m_vertex_it).m_edges.empty()) {
m_edge = 0; m_edge = 0;
return; return;
} }
@ -235,6 +255,7 @@ void Graph<T>::edge_iterator::resetEdge()
m_edge = new Edge(source, destination, weight); m_edge = new Edge(source, destination, weight);
} }
/// @todo Rewrite it to be more simple
template <typename T> template <typename T>
void Graph<T>::edge_iterator::advance(int n) void Graph<T>::edge_iterator::advance(int n)
{ {
@ -292,6 +313,11 @@ typename Graph<T>::EdgeTo& Graph<T>::EdgeTo::operator=(const EdgeTo& other)
return *this; return *this;
} }
template <typename T>
bool Graph<T>::EdgeTo::operator==(const EdgeTo& other) const
{
return m_destination == other.m_destination && m_weight == other.m_weight;
}
// Vertex // Vertex
@ -316,13 +342,20 @@ typename Graph<T>::Vertex& Graph<T>::Vertex::operator=(const Vertex& other)
{ {
if (this != &other) { if (this != &other) {
m_data = other.m_data; m_data = other.m_data;
m_edges.clear();
m_edges = other.m_edges; m_edges = other.m_edges;
} }
return *this; return *this;
} }
template <typename T>
bool Graph<T>::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 <typename T> template <typename T>
void Graph<T>::Vertex::addEdge(const_reference destination, float weight) void Graph<T>::Vertex::addEdge(const_reference destination, float weight)
{ {

@ -63,12 +63,18 @@ int main()
assert(g.numberOfVertices() == 4); assert(g.numberOfVertices() == 4);
int vertices_array[] = {2, 5, 13, 1}; int vertices_array[] = {2, 5, 13, 1};
std::vector<int> v(vertices_array, vertices_array + sizeof(vertices_array) / sizeof(int) ); std::vector<int> v(vertices_array, vertices_array + sizeof(vertices_array) / sizeof(int) );
Graph<int>::vertex_iterator g_it; Graph<int>::vertex_iterator g_it2;
std::vector<int>::iterator v_it; std::vector<int>::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<int>::vertex_iterator g_it = g.vertex_begin();
g_it != g.vertex_end(); 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); assert(**g_it == *v_it);
} }
@ -83,11 +89,12 @@ int main()
int vertices_array2[] = {1, 2, 3, 4}; int vertices_array2[] = {1, 2, 3, 4};
std::vector<int> v2(vertices_array2, vertices_array2 + sizeof(vertices_array2) / sizeof(int) ); std::vector<int> 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<int>::vertex_iterator g_it = g2.vertex_begin();
g_it != g2.vertex_end(); g_it != g2.vertex_end();
g_it++, v_it++) { ++g_it, ++v_it) {
std::cout << "vector: " std::cout << "vector: "
<< *g_it << " " // << *g_it << " "
<< **g_it << **g_it
<< std::endl; << std::endl;
assert(**g_it == *v_it); assert(**g_it == *v_it);
@ -98,20 +105,53 @@ int main()
assert(g2.addEdge(1, 3) == true); assert(g2.addEdge(1, 3) == true);
assert(g2.addEdge(2, 4) == true); assert(g2.addEdge(2, 4) == true);
std::vector<Graph<int>::Edge> e = g2.edges(); std::vector<Graph<int>::Edge> e = g2.edges();
assert(e.size() == 3); assert(e.size() == 3);
for(Graph<int>::edge_iterator edge_it = g2.edge_begin(); Graph<int>::edge_iterator edge_it;
edge_it != g2.edge_end(); Graph<int>::edge_iterator beee = g2.edge_begin();
++edge_it) { edge_it = beee;
assert(edge_it == g2.edge_begin());
Graph<int>::pointer source = (*edge_it).getSource();
Graph<int>::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<int>::edge_iterator edge_it;
for(/*Graph<int>::edge_iterator*/ edge_it = g2.edge_begin(); edge_it != g2.edge_end(); ++edge_it) {
Graph<int>::pointer source = (*edge_it).getSource(); Graph<int>::pointer source = (*edge_it).getSource();
Graph<int>::pointer destination = (*edge_it).getDestination(); Graph<int>::pointer destination = (*edge_it).getDestination();
std::cout << "edge: " std::cout << "edge: "
<< source << " " << *source << " " // << source << " "
<< destination << " " << *destination << " " << *source << " "
// << destination << " "
<< *destination << " "
<< (*edge_it).getWeight() << std::endl; << (*edge_it).getWeight() << std::endl;
} }
Graph<int>::edge_iterator edge_it1 = g2.edge_begin();
edge_it1 += 10;
assert(edge_it1 == g2.edge_end());
Graph<int>::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; std::cout << "frankon vege" << std::endl;
return 0; return 0;
} }

Loading…
Cancel
Save