| // |
| //======================================================================= |
| // Copyright 1997, 1998, 1999, 2000 University of Notre Dame. |
| // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek |
| // |
| // Distributed under the Boost Software License, Version 1.0. (See |
| // accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| //======================================================================= |
| // |
| #ifndef BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP |
| #define BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP |
| |
| #include <iterator> |
| #include <utility> |
| #include <boost/detail/workaround.hpp> |
| |
| #if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) |
| # define BOOST_GRAPH_NO_OPTIONAL |
| #endif |
| |
| #ifdef BOOST_GRAPH_NO_OPTIONAL |
| # define BOOST_GRAPH_MEMBER . |
| #else |
| # define BOOST_GRAPH_MEMBER -> |
| # include <boost/optional.hpp> |
| #endif // ndef BOOST_GRAPH_NO_OPTIONAL |
| |
| namespace boost { |
| |
| namespace detail { |
| |
| template <class VertexIterator, class OutEdgeIterator, class Graph> |
| class adj_list_edge_iterator { |
| typedef adj_list_edge_iterator self; |
| public: |
| typedef std::forward_iterator_tag iterator_category; |
| typedef typename OutEdgeIterator::value_type value_type; |
| typedef typename OutEdgeIterator::reference reference; |
| typedef typename OutEdgeIterator::pointer pointer; |
| typedef typename OutEdgeIterator::difference_type difference_type; |
| typedef difference_type distance_type; |
| |
| inline adj_list_edge_iterator() {} |
| |
| inline adj_list_edge_iterator(const self& x) |
| : vBegin(x.vBegin), vCurr(x.vCurr), vEnd(x.vEnd), |
| edges(x.edges), m_g(x.m_g) { } |
| |
| template <class G> |
| inline adj_list_edge_iterator(VertexIterator b, |
| VertexIterator c, |
| VertexIterator e, |
| const G& g) |
| : vBegin(b), vCurr(c), vEnd(e), m_g(&g) { |
| if ( vCurr != vEnd ) { |
| while ( vCurr != vEnd && out_degree(*vCurr, *m_g) == 0 ) |
| ++vCurr; |
| if ( vCurr != vEnd ) |
| edges = out_edges(*vCurr, *m_g); |
| } |
| } |
| |
| /*Note: |
| In the directed graph cases, it is fine. |
| For undirected graphs, one edge go through twice. |
| */ |
| inline self& operator++() { |
| ++edges BOOST_GRAPH_MEMBER first; |
| if (edges BOOST_GRAPH_MEMBER first == edges BOOST_GRAPH_MEMBER second) |
| { |
| ++vCurr; |
| while ( vCurr != vEnd && out_degree(*vCurr, *m_g) == 0 ) |
| ++vCurr; |
| if ( vCurr != vEnd ) |
| edges = out_edges(*vCurr, *m_g); |
| } |
| return *this; |
| } |
| inline self operator++(int) { |
| self tmp = *this; |
| ++(*this); |
| return tmp; |
| } |
| inline value_type operator*() const |
| { return *edges BOOST_GRAPH_MEMBER first; } |
| inline bool operator==(const self& x) const { |
| return vCurr == x.vCurr |
| && (vCurr == vEnd |
| || edges BOOST_GRAPH_MEMBER first == x.edges BOOST_GRAPH_MEMBER first); |
| } |
| inline bool operator!=(const self& x) const { |
| return vCurr != x.vCurr |
| || (vCurr != vEnd |
| && edges BOOST_GRAPH_MEMBER first != x.edges BOOST_GRAPH_MEMBER first); |
| } |
| protected: |
| VertexIterator vBegin; |
| VertexIterator vCurr; |
| VertexIterator vEnd; |
| |
| #ifdef BOOST_GRAPH_NO_OPTIONAL |
| std::pair<OutEdgeIterator, OutEdgeIterator> edges; |
| #else |
| boost::optional<std::pair<OutEdgeIterator, OutEdgeIterator> > |
| edges; |
| #endif // ndef BOOST_GRAPH_NO_OPTIONAL |
| const Graph* m_g; |
| }; |
| |
| } // namespace detail |
| |
| } |
| |
| #undef BOOST_GRAPH_MEMBER |
| |
| #endif // BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP |