1 /*============================================================================= 2 Copyright (c) 2001-2006 Joel de Guzman 3 4 Distributed under the Boost Software License, Version 1.0. (See accompanying 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 ==============================================================================*/ 7 #if !defined(FUSION_BOOST_TUPLE_ITERATOR_09262006_1851) 8 #define FUSION_BOOST_TUPLE_ITERATOR_09262006_1851 9 10 #include <boost/fusion/iterator/iterator_facade.hpp> 11 #include <boost/type_traits/is_const.hpp> 12 #include <boost/type_traits/add_const.hpp> 13 #include <boost/mpl/identity.hpp> 14 #include <boost/mpl/if.hpp> 15 #include <boost/mpl/eval_if.hpp> 16 #include <boost/mpl/or.hpp> 17 #include <boost/mpl/plus.hpp> 18 #include <boost/mpl/int.hpp> 19 #include <boost/mpl/apply.hpp> 20 #include <boost/tuple/tuple.hpp> 21 22 namespace boost { namespace fusion 23 { 24 struct forward_traversal_tag; 25 26 namespace detail 27 { 28 template <typename T> 29 struct boost_tuple_is_empty : mpl::false_ {}; 30 31 template <> 32 struct boost_tuple_is_empty<tuples::null_type> : mpl::true_ {}; 33 34 template <> 35 struct boost_tuple_is_empty<tuples::null_type const> : mpl::true_ {}; 36 37 template <> 38 struct boost_tuple_is_empty<tuples::tuple<> > : mpl::true_ {}; 39 40 template <> 41 struct boost_tuple_is_empty<tuples::tuple<> const> : mpl::true_ {}; 42 } 43 44 template <typename Cons = tuples::null_type> 45 struct boost_tuple_iterator 46 : iterator_facade<boost_tuple_iterator<Cons>, forward_traversal_tag> 47 { 48 typedef Cons cons_type; 49 boost_tuple_iteratorboost::fusion::boost_tuple_iterator50 explicit boost_tuple_iterator(Cons& in_cons) 51 : cons(in_cons) {} 52 Cons& cons; 53 54 template <typename Iterator> 55 struct value_of : mpl::identity<typename Iterator::cons_type::head_type> {}; 56 57 template <typename Iterator> 58 struct deref 59 { 60 typedef typename value_of<Iterator>::type element; 61 62 typedef typename 63 mpl::if_< 64 is_const<typename Iterator::cons_type> 65 , typename tuples::access_traits<element>::const_type 66 , typename tuples::access_traits<element>::non_const_type 67 >::type 68 type; 69 70 static type callboost::fusion::boost_tuple_iterator::deref71 call(Iterator const& iter) 72 { 73 return iter.cons.get_head(); 74 } 75 }; 76 77 template <typename Iterator> 78 struct next 79 { 80 typedef typename Iterator::cons_type cons_type; 81 typedef typename cons_type::tail_type tail_type; 82 83 typedef boost_tuple_iterator< 84 typename mpl::eval_if< 85 is_const<cons_type> 86 , add_const<tail_type> 87 , mpl::identity<tail_type> 88 >::type> 89 type; 90 91 static type callboost::fusion::boost_tuple_iterator::next92 call(Iterator const& iter) 93 { 94 return type(iter.cons.get_tail()); 95 } 96 }; 97 98 template <typename I1, typename I2> 99 struct distance; 100 101 // detail 102 template <typename I1, typename I2> 103 struct lazy_next_distance 104 { 105 typedef 106 typename mpl::plus< 107 mpl::int_<1>, 108 typename distance< 109 typename next<I1>::type, 110 I2 111 >::type 112 >::type type; 113 }; 114 115 template <typename I1, typename I2> 116 struct distance 117 { 118 typedef typename mpl::eval_if< 119 boost::is_same<I1, I2>, 120 mpl::int_<0>, 121 lazy_next_distance<I1, I2> 122 >::type type; 123 124 static type callboost::fusion::boost_tuple_iterator::distance125 call(I1 const&, I2 const&) 126 { 127 return type(); 128 } 129 }; 130 131 private: 132 // silence MSVC warning C4512: assignment operator could not be generated 133 boost_tuple_iterator& operator= (boost_tuple_iterator const&); 134 }; 135 136 template <typename Null> 137 struct boost_tuple_null_iterator 138 : iterator_facade<boost_tuple_iterator<Null>, forward_traversal_tag> 139 { 140 typedef Null cons_type; 141 142 template <typename I1, typename I2> 143 struct equal_to 144 : mpl::or_< 145 is_same<I1, I2> 146 , mpl::and_< 147 detail::boost_tuple_is_empty<typename I1::cons_type> 148 , detail::boost_tuple_is_empty<typename I2::cons_type> 149 > 150 > 151 {}; 152 }; 153 154 template <> 155 struct boost_tuple_iterator<tuples::null_type> 156 : boost_tuple_null_iterator<tuples::null_type> 157 { 158 template <typename Cons> boost_tuple_iteratorboost::fusion::boost_tuple_iterator159 explicit boost_tuple_iterator(Cons const&) {} 160 }; 161 162 template <> 163 struct boost_tuple_iterator<tuples::null_type const> 164 : boost_tuple_null_iterator<tuples::null_type const> 165 { 166 template <typename Cons> boost_tuple_iteratorboost::fusion::boost_tuple_iterator167 explicit boost_tuple_iterator(Cons const&) {} 168 }; 169 170 template <> 171 struct boost_tuple_iterator<tuples::tuple<> > 172 : boost_tuple_null_iterator<tuples::tuple<> > 173 { 174 template <typename Cons> 175 explicit boost_tuple_iterator(Cons const&) {} 176 }; 177 178 template <> 179 struct boost_tuple_iterator<tuples::tuple<> const> 180 : boost_tuple_null_iterator<tuples::tuple<> const> 181 { 182 template <typename Cons> 183 explicit boost_tuple_iterator(Cons const&) {} 184 }; 185 }} 186 187 #endif 188 189 190