diff --git a/graph.h b/graph.h index 72fd132..a23cac2 100644 --- a/graph.h +++ b/graph.h @@ -77,13 +77,14 @@ public: pointer, reference> { + friend class Graph; + public: typedef vertex_iterator self_type; typedef vertex_iterator& reference_self_type; typedef const vertex_iterator& const_reference_self_type; vertex_iterator() : m_it() {} - vertex_iterator(typename std::vector::iterator it) : m_it(it) {} ~vertex_iterator() {} vertex_iterator(const_reference_self_type o) : m_it(o.m_it) {} reference_self_type operator=(const_reference_self_type o) @@ -100,6 +101,8 @@ public: bool operator!=(const_reference_self_type o) { return !(*this == o); } private: + vertex_iterator(typename std::vector::iterator it) : m_it(it) {} + typename std::vector::iterator m_it; }; @@ -112,24 +115,22 @@ public: edge_pointer, edge_reference> { + friend class Graph; + public: typedef edge_iterator self_type; typedef edge_iterator& reference_self_type; typedef const edge_iterator& const_reference_self_type; - edge_iterator() : m_vertex_it(), m_edge_it(), m_edge(0) {} - edge_iterator(typename std::vector::iterator vertex_it, - typename std::list::iterator edge_it) - : m_vertex_it(vertex_it), m_edge_it(edge_it) {} + edge_iterator() : m_vertices(), m_vertex_it(), m_edge_it(), m_edge(0) {} ~edge_iterator() { if (m_edge) delete m_edge; } edge_iterator(const_reference_self_type o) - : m_vertex_it(o.m_vertex_it), m_edge_it(o.m_edge_it) {} - reference_self_type operator=(const_reference_self_type o) - { if (this != &o) { m_vertex_it = o.m_vertex_it; m_edge_it = o.m_edge_it; } return *this; } + : 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); - edge_reference operator*() { if (!m_edge) { initEdge(); } return *m_edge; } - edge_pointer operator->() { if (!m_edge) { initEdge(); } return m_edge; } + edge_reference operator*() { resetEdge(); return *m_edge; } + edge_pointer operator->() { resetEdge(); return m_edge; } self_type &operator++() { advance(1); return *this; } self_type operator++(int) { self_type tmp(*this); advance(1); return tmp; } @@ -140,23 +141,20 @@ public: bool operator!=(const_reference_self_type o) { return !(*this == o); } private: - void initEdge() - { m_edge = new Edge(*m_vertex_it, (*m_edge_it).m_destination, (*m_edge_it).m_weight); } - void invalidateEdge() { if (m_edge) delete m_edge; } - - void advance(int n) - { - invalidateEdge(); - /// @todo Do the stepping - } + edge_iterator(std::vector vertices) + : m_vertices(vertices), m_vertex_it(m_vertices.begin()), m_edge_it(), m_edge(0) {} + + void resetEdge(); + void advance(int n); + std::vector m_vertices; typename std::vector::iterator m_vertex_it; typename std::list::iterator m_edge_it; edge_pointer m_edge; }; - edge_iterator edge_begin() { return edge_iterator(m_vertices.begin()); } - edge_iterator edge_end() { return edge_iterator(m_vertices.end()); } + edge_iterator edge_begin() { return edge_iterator(m_vertices); } + edge_iterator edge_end() { return edge_iterator(m_vertices); } private: @@ -195,7 +193,62 @@ private: }; -// Edge +// edge iterator + +template +typename Graph::edge_iterator::reference_self_type +Graph::edge_iterator::operator=(const_reference_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; + } + + return *this; +} + + +template +void Graph::edge_iterator::resetEdge() +{ + if (m_edge) delete m_edge; + + if (m_vertex_it == m_vertices.end()) { + m_edge = 0; + } else { + m_edge = new Edge( (*m_vertex_it).m_data, (*m_edge_it).m_destination, (*m_edge_it).m_weight); + } +} + +template +void Graph::edge_iterator::advance(int n) +{ + if (m_vertex_it == m_vertices.end()) + return; + + std::list::EdgeTo> edges = (*m_vertex_it).m_edges; + const int remaining = std::distance(m_edge_it, edges.end()); + if (remaining < n) { + std::advance(m_edge_it, n); + return; + } + + int counter = n - remaining; + ++m_vertex_it; + while (counter > 0 && m_vertex_it != m_vertices.end()) { + const int number_of_edges = (*m_vertex_it).m_edges.size(); + if (counter < number_of_edges) { + m_edge_it = (*m_vertex_it).m_edges.begin(); + std::advance(m_edge_it, counter); + return; + } + counter -= number_of_edges; + ++m_vertex_it; + } +} + +// EdgeTo template Graph::EdgeTo::EdgeTo(const_reference destination, float weight) diff --git a/main.cpp b/main.cpp index c9e3534..1f51abb 100644 --- a/main.cpp +++ b/main.cpp @@ -91,6 +91,12 @@ int main() assert(e.size() == 3); + for(Graph::edge_iterator edge_it = g.edge_begin(); edge_it != g.edge_end(); ++edge_it) { + std::cout << (*edge_it).getSource() << " " + << (*edge_it).getDestination() << " " + << (*edge_it).getWeight() << std::endl; + } + return 0; }