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