| /*============================================================================= |
| Copyright (c) 2001-2006 Joel de Guzman |
| |
| 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(FUSION_BOOST_TUPLE_ITERATOR_09262006_1851) |
| #define FUSION_BOOST_TUPLE_ITERATOR_09262006_1851 |
| |
| #include <boost/fusion/iterator/iterator_facade.hpp> |
| #include <boost/type_traits/is_const.hpp> |
| #include <boost/type_traits/add_const.hpp> |
| #include <boost/mpl/identity.hpp> |
| #include <boost/mpl/if.hpp> |
| #include <boost/mpl/eval_if.hpp> |
| #include <boost/mpl/or.hpp> |
| #include <boost/mpl/plus.hpp> |
| #include <boost/mpl/int.hpp> |
| #include <boost/mpl/apply.hpp> |
| #include <boost/tuple/tuple.hpp> |
| |
| namespace boost { namespace fusion |
| { |
| struct forward_traversal_tag; |
| |
| namespace detail |
| { |
| template <typename T> |
| struct boost_tuple_is_empty : mpl::false_ {}; |
| |
| template <> |
| struct boost_tuple_is_empty<tuples::null_type> : mpl::true_ {}; |
| |
| template <> |
| struct boost_tuple_is_empty<tuples::null_type const> : mpl::true_ {}; |
| |
| template <> |
| struct boost_tuple_is_empty<tuples::tuple<> > : mpl::true_ {}; |
| |
| template <> |
| struct boost_tuple_is_empty<tuples::tuple<> const> : mpl::true_ {}; |
| } |
| |
| template <typename Cons = tuples::null_type> |
| struct boost_tuple_iterator |
| : iterator_facade<boost_tuple_iterator<Cons>, forward_traversal_tag> |
| { |
| typedef Cons cons_type; |
| |
| explicit boost_tuple_iterator(Cons& in_cons) |
| : cons(in_cons) {} |
| Cons& cons; |
| |
| template <typename Iterator> |
| struct value_of : mpl::identity<typename Iterator::cons_type::head_type> {}; |
| |
| template <typename Iterator> |
| struct deref |
| { |
| typedef typename value_of<Iterator>::type element; |
| |
| typedef typename |
| mpl::if_< |
| is_const<typename Iterator::cons_type> |
| , typename tuples::access_traits<element>::const_type |
| , typename tuples::access_traits<element>::non_const_type |
| >::type |
| type; |
| |
| static type |
| call(Iterator const& iter) |
| { |
| return iter.cons.get_head(); |
| } |
| }; |
| |
| template <typename Iterator> |
| struct next |
| { |
| typedef typename Iterator::cons_type cons_type; |
| typedef typename cons_type::tail_type tail_type; |
| |
| typedef boost_tuple_iterator< |
| typename mpl::eval_if< |
| is_const<cons_type> |
| , add_const<tail_type> |
| , mpl::identity<tail_type> |
| >::type> |
| type; |
| |
| static type |
| call(Iterator const& iter) |
| { |
| return type(iter.cons.get_tail()); |
| } |
| }; |
| |
| template <typename I1, typename I2> |
| struct distance; |
| |
| // detail |
| template <typename I1, typename I2> |
| struct lazy_next_distance |
| { |
| typedef |
| typename mpl::plus< |
| mpl::int_<1>, |
| typename distance< |
| typename next<I1>::type, |
| I2 |
| >::type |
| >::type type; |
| }; |
| |
| template <typename I1, typename I2> |
| struct distance |
| { |
| typedef typename mpl::eval_if< |
| boost::is_same<I1, I2>, |
| mpl::int_<0>, |
| lazy_next_distance<I1, I2> |
| >::type type; |
| |
| static type |
| call(I1 const&, I2 const&) |
| { |
| return type(); |
| } |
| }; |
| |
| private: |
| // silence MSVC warning C4512: assignment operator could not be generated |
| boost_tuple_iterator& operator= (boost_tuple_iterator const&); |
| }; |
| |
| template <typename Null> |
| struct boost_tuple_null_iterator |
| : iterator_facade<boost_tuple_iterator<Null>, forward_traversal_tag> |
| { |
| typedef Null cons_type; |
| |
| template <typename I1, typename I2> |
| struct equal_to |
| : mpl::or_< |
| is_same<I1, I2> |
| , mpl::and_< |
| detail::boost_tuple_is_empty<typename I1::cons_type> |
| , detail::boost_tuple_is_empty<typename I2::cons_type> |
| > |
| > |
| {}; |
| }; |
| |
| template <> |
| struct boost_tuple_iterator<tuples::null_type> |
| : boost_tuple_null_iterator<tuples::null_type> |
| { |
| template <typename Cons> |
| explicit boost_tuple_iterator(Cons const&) {} |
| }; |
| |
| template <> |
| struct boost_tuple_iterator<tuples::null_type const> |
| : boost_tuple_null_iterator<tuples::null_type const> |
| { |
| template <typename Cons> |
| explicit boost_tuple_iterator(Cons const&) {} |
| }; |
| |
| template <> |
| struct boost_tuple_iterator<tuples::tuple<> > |
| : boost_tuple_null_iterator<tuples::tuple<> > |
| { |
| template <typename Cons> |
| explicit boost_tuple_iterator(Cons const&) {} |
| }; |
| |
| template <> |
| struct boost_tuple_iterator<tuples::tuple<> const> |
| : boost_tuple_null_iterator<tuples::tuple<> const> |
| { |
| template <typename Cons> |
| explicit boost_tuple_iterator(Cons const&) {} |
| }; |
| }} |
| |
| #endif |
| |
| |