/*============================================================================= | |
Copyright (c) 2009 Christopher Schmidt | |
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_FUSION_ITERATOR_BASIC_ITERATOR_HPP | |
#define BOOST_FUSION_ITERATOR_BASIC_ITERATOR_HPP | |
#include <boost/fusion/iterator/iterator_facade.hpp> | |
#include <boost/mpl/and.hpp> | |
#include <boost/mpl/equal_to.hpp> | |
#include <boost/mpl/minus.hpp> | |
#include <boost/mpl/int.hpp> | |
#include <boost/type_traits/is_same.hpp> | |
#include <boost/type_traits/remove_const.hpp> | |
namespace boost { namespace fusion | |
{ | |
namespace extension | |
{ | |
template <typename> | |
struct value_of_impl; | |
template <typename> | |
struct deref_impl; | |
template <typename> | |
struct value_of_data_impl; | |
template <typename> | |
struct key_of_impl; | |
template <typename> | |
struct deref_data_impl; | |
} | |
template<typename Tag, typename Category, typename Seq, int Index> | |
struct basic_iterator | |
: iterator_facade<basic_iterator<Tag,Category,Seq,Index>, Category> | |
{ | |
typedef mpl::int_<Index> index; | |
typedef Seq seq_type; | |
template <typename It> | |
struct value_of | |
: extension::value_of_impl<Tag>::template apply<It> | |
{}; | |
template <typename It> | |
struct deref | |
: extension::deref_impl<Tag>::template apply<It> | |
{}; | |
template <typename It> | |
struct value_of_data | |
: extension::value_of_data_impl<Tag>::template apply<It> | |
{}; | |
template <typename It> | |
struct key_of | |
: extension::key_of_impl<Tag>::template apply<It> | |
{}; | |
template <typename It> | |
struct deref_data | |
: extension::deref_data_impl<Tag>::template apply<It> | |
{}; | |
template <typename It, typename N> | |
struct advance | |
{ | |
typedef | |
basic_iterator<Tag, Category, Seq, Index + N::value> | |
type; | |
static type | |
call(It const& it) | |
{ | |
return type(*it.seq,0); | |
} | |
}; | |
template <typename It> | |
struct next | |
: advance<It, mpl::int_<1> > | |
{}; | |
template <typename It> | |
struct prior | |
: advance<It, mpl::int_<-1> > | |
{}; | |
template <typename It1, typename It2> | |
struct distance | |
{ | |
typedef mpl::minus<typename It2::index, typename It1::index> type; | |
static | |
type | |
call(It1 const&, It2 const&) | |
{ | |
return type(); | |
} | |
}; | |
template <typename It1, typename It2> | |
struct equal_to | |
: mpl::and_< | |
is_same< | |
typename remove_const<typename It1::seq_type>::type | |
, typename remove_const<typename It2::seq_type>::type | |
> | |
, mpl::equal_to<typename It1::index,typename It2::index> | |
> | |
{}; | |
template<typename OtherSeq> | |
basic_iterator(basic_iterator<Tag,Category,OtherSeq,Index> const& it) | |
: seq(it.seq) | |
{} | |
basic_iterator(Seq& in_seq, int) | |
: seq(&in_seq) | |
{} | |
template<typename OtherSeq> | |
basic_iterator& | |
operator=(basic_iterator<Tag,Category,OtherSeq,Index> const& it) | |
{ | |
seq=it.seq; | |
return *this; | |
} | |
Seq* seq; | |
}; | |
}} | |
#endif |