1 /*============================================================================= 2 Copyright (c) 2005-2013 Joel de Guzman 3 Copyright (c) 2005-2006 Dan Marsden 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 ==============================================================================*/ 8 #if !defined(BOOST_FUSION_MAP_ITERATOR_02042013_0835) 9 #define BOOST_FUSION_MAP_ITERATOR_02042013_0835 10 11 #include <boost/fusion/support/config.hpp> 12 #include <boost/fusion/iterator/iterator_facade.hpp> 13 #include <boost/mpl/minus.hpp> 14 #include <boost/mpl/equal_to.hpp> 15 #include <boost/mpl/if.hpp> 16 #include <boost/utility/declval.hpp> 17 #include <boost/type_traits/is_const.hpp> 18 #include <boost/type_traits/add_const.hpp> 19 20 namespace boost { namespace fusion 21 { 22 struct random_access_traversal_tag; 23 24 template <typename Seq, int Pos> 25 struct map_iterator 26 : iterator_facade< 27 map_iterator<Seq, Pos> 28 , typename Seq::category> 29 { 30 typedef Seq sequence; 31 typedef mpl::int_<Pos> index; 32 33 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED map_iteratorboost::fusion::map_iterator34 map_iterator(Seq& seq) 35 : seq_(seq) 36 {} 37 38 template<typename Iterator> 39 struct value_of 40 { 41 typedef typename Iterator::sequence sequence; 42 typedef typename Iterator::index index; 43 typedef 44 decltype(boost::declval<sequence>().get_val(index())) 45 type; 46 }; 47 48 template<typename Iterator> 49 struct value_of_data 50 { 51 typedef typename Iterator::sequence sequence; 52 typedef typename Iterator::index index; 53 typedef 54 decltype(boost::declval<sequence>().get_val(index()).second) 55 type; 56 }; 57 58 template<typename Iterator> 59 struct key_of 60 { 61 typedef typename Iterator::sequence sequence; 62 typedef typename Iterator::index index; 63 typedef decltype(boost::declval<sequence>().get_key(index())) key_identity_type; 64 typedef typename key_identity_type::type type; 65 }; 66 67 template<typename Iterator> 68 struct deref 69 { 70 typedef typename Iterator::sequence sequence; 71 typedef typename Iterator::index index; 72 typedef 73 decltype(boost::declval<sequence>().get(index())) 74 type; 75 76 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 77 static type callboost::fusion::map_iterator::deref78 call(Iterator const& it) 79 { 80 return it.seq_.get(typename Iterator::index()); 81 } 82 }; 83 84 template<typename Iterator> 85 struct deref_data 86 { 87 typedef typename Iterator::sequence sequence; 88 typedef typename Iterator::index index; 89 90 typedef decltype(boost::declval<sequence>().get(index()).second) second_type_; 91 92 typedef typename 93 mpl::if_< 94 is_const<sequence> 95 , typename add_const<second_type_>::type 96 , second_type_ 97 >::type 98 second_type; 99 100 typedef typename add_reference<second_type>::type type; 101 102 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 103 static type callboost::fusion::map_iterator::deref_data104 call(Iterator const& it) 105 { 106 return it.seq_.get(typename Iterator::index()).second; 107 } 108 }; 109 110 template <typename Iterator, typename N> 111 struct advance 112 { 113 typedef typename Iterator::index index; 114 typedef typename Iterator::sequence sequence; 115 typedef map_iterator<sequence, index::value + N::value> type; 116 117 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 118 static type callboost::fusion::map_iterator::advance119 call(Iterator const& i) 120 { 121 return type(i.seq_); 122 } 123 }; 124 125 template<typename Iterator> 126 struct next 127 : advance<Iterator, mpl::int_<1> > 128 {}; 129 130 template<typename Iterator> 131 struct prior 132 : advance<Iterator, mpl::int_<-1> > 133 {}; 134 135 template <typename I1, typename I2> 136 struct distance 137 { 138 typedef typename 139 mpl::minus< 140 typename I2::index, typename I1::index 141 >::type 142 type; 143 144 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 145 static type callboost::fusion::map_iterator::distance146 call(I1 const&, I2 const&) 147 { 148 return type(); 149 } 150 }; 151 152 template<typename I1, typename I2> 153 struct equal_to 154 : mpl::equal_to<typename I1::index, typename I2::index> 155 {}; 156 157 Seq& seq_; 158 159 // silence MSVC warning C4512: assignment operator could not be generated 160 BOOST_DELETED_FUNCTION(map_iterator& operator= (map_iterator const&)) 161 }; 162 163 }} 164 165 #ifdef BOOST_FUSION_WORKAROUND_FOR_LWG_2408 166 namespace std 167 { 168 template <typename Seq, int Pos> 169 struct iterator_traits< ::boost::fusion::map_iterator<Seq, Pos> > 170 { }; 171 } 172 #endif 173 174 #endif 175