blob: ad3ebe18672c1581c67fb0cd66709a2d0a8c78a7 [file] [log] [blame]
//
//=======================================================================
// 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