blob: 2179c36f4c8027ae01ff1f157103301c984396dd [file] [log] [blame]
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Copyright (c) 2005-2006 Dan Marsden
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)
==============================================================================*/
#if !defined(BOOST_FUSION_DEQUE_ITERATOR_26112006_2154)
#define BOOST_FUSION_DEQUE_ITERATOR_26112006_2154
#include <boost/fusion/iterator/iterator_facade.hpp>
#include <boost/fusion/container/deque/detail/keyed_element.hpp>
#include <boost/mpl/minus.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/type_traits/is_const.hpp>
namespace boost { namespace fusion {
struct bidirectional_traversal_tag;
template<typename Seq, int Pos>
struct deque_iterator
: iterator_facade<deque_iterator<Seq, Pos>, bidirectional_traversal_tag>
{
typedef Seq sequence;
typedef mpl::int_<Pos> index;
deque_iterator(Seq& seq)
: seq_(seq)
{}
template<typename Iterator>
struct value_of
: detail::keyed_element_value_at<
typename Iterator::sequence, typename Iterator::index>
{};
template<typename Iterator>
struct deref
{
typedef typename detail::keyed_element_value_at<
typename Iterator::sequence, typename Iterator::index>::type element_type;
typedef typename add_reference<
typename mpl::eval_if<
is_const<typename Iterator::sequence>,
add_const<element_type>,
mpl::identity<element_type> >::type>::type type;
static type
call(Iterator const& it)
{
return it.seq_.get(typename Iterator::index());
}
};
template <typename Iterator, typename N>
struct advance
{
typedef typename Iterator::index index;
typedef typename Iterator::sequence sequence;
typedef deque_iterator<sequence, index::value + N::value> type;
static type
call(Iterator const& i)
{
return type(i.seq_);
}
};
template<typename Iterator>
struct next
: advance<Iterator, mpl::int_<1> >
{};
template<typename Iterator>
struct prior
: advance<Iterator, mpl::int_<-1> >
{};
template <typename I1, typename I2>
struct distance : mpl::minus<typename I2::index, typename I1::index>
{
typedef typename
mpl::minus<
typename I2::index, typename I1::index
>::type
type;
static type
call(I1 const&, I2 const&)
{
return type();
}
};
template<typename I1, typename I2>
struct equal_to
: mpl::equal_to<typename I1::index, typename I2::index>
{};
Seq& seq_;
private:
// silence MSVC warning C4512: assignment operator could not be generated
deque_iterator& operator= (deque_iterator const&);
};
}}
#endif