//
|
//=======================================================================
|
// 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
|