//=======================================================================
// Copyright 2002 Indiana University.
// 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_ADJACENCY_ITERATOR_HPP
#define BOOST_ADJACENCY_ITERATOR_HPP

#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/graph/graph_traits.hpp>

namespace boost
{

  template <class Graph, class Vertex, class OutEdgeIter, class Difference>
  struct adjacency_iterator
    : iterator_adaptor<
          adjacency_iterator<Graph,Vertex,OutEdgeIter,Difference>
        , OutEdgeIter
        , Vertex
        , use_default
        , Vertex
        , Difference
      >
  {
      typedef iterator_adaptor<
          adjacency_iterator<Graph,Vertex,OutEdgeIter,Difference>
        , OutEdgeIter
        , Vertex
        , use_default
        , Vertex
        , Difference
      > super_t;
      
      inline adjacency_iterator() {}
      inline adjacency_iterator(OutEdgeIter const& i, const Graph* g) : super_t(i), m_g(g) { }

      inline Vertex
      dereference() const
        { return target(*this->base(), *m_g); }

      const Graph* m_g;
  };

  template <class Graph,
            class Vertex = typename graph_traits<Graph>::vertex_descriptor,
            class OutEdgeIter=typename graph_traits<Graph>::out_edge_iterator>
  class adjacency_iterator_generator
  {
    typedef typename boost::detail::iterator_traits<OutEdgeIter>
      ::difference_type difference_type;
  public:
      typedef adjacency_iterator<Graph,Vertex,OutEdgeIter,difference_type> type;
  };

  template <class Graph, class Vertex, class InEdgeIter, class Difference>
  struct inv_adjacency_iterator
    : iterator_adaptor<
          inv_adjacency_iterator<Graph,Vertex,InEdgeIter,Difference>
        , InEdgeIter
        , Vertex
        , use_default
        , Vertex
        , Difference
      >
    {
      typedef iterator_adaptor<
                  inv_adjacency_iterator<Graph,Vertex,InEdgeIter,Difference>
                , InEdgeIter
                , Vertex
                , use_default
                , Vertex
                , Difference
              > super_t;

      inline inv_adjacency_iterator() { }
      inline inv_adjacency_iterator(InEdgeIter const& i, const Graph* g) : super_t(i), m_g(g) { }

      inline Vertex
      dereference() const
        { return source(*this->base(), *m_g); }

      const Graph* m_g;
    };

  template <class Graph,
            class Vertex = typename graph_traits<Graph>::vertex_descriptor,
            class InEdgeIter = typename graph_traits<Graph>::in_edge_iterator>
  class inv_adjacency_iterator_generator {
    typedef typename boost::detail::iterator_traits<InEdgeIter>
      ::difference_type difference_type;
  public:
      typedef inv_adjacency_iterator<Graph, Vertex, InEdgeIter, difference_type> type;
  };

} // namespace boost

#endif // BOOST_DETAIL_ADJACENCY_ITERATOR_HPP
