1 /*============================================================================= 2 Copyright (c) 2009 Christopher Schmidt 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 8 #ifndef BOOST_FUSION_ITERATOR_BASIC_ITERATOR_HPP 9 #define BOOST_FUSION_ITERATOR_BASIC_ITERATOR_HPP 10 11 #include <boost/fusion/support/config.hpp> 12 #include <boost/fusion/iterator/iterator_facade.hpp> 13 14 #include <boost/mpl/and.hpp> 15 #include <boost/mpl/equal_to.hpp> 16 #include <boost/mpl/minus.hpp> 17 #include <boost/mpl/int.hpp> 18 #include <boost/type_traits/is_same.hpp> 19 #include <boost/type_traits/remove_const.hpp> 20 21 namespace boost { namespace fusion 22 { 23 namespace extension 24 { 25 template <typename> 26 struct value_of_impl; 27 28 template <typename> 29 struct deref_impl; 30 31 template <typename> 32 struct value_of_data_impl; 33 34 template <typename> 35 struct key_of_impl; 36 37 template <typename> 38 struct deref_data_impl; 39 } 40 41 template<typename Tag, typename Category, typename Seq, int Index> 42 struct basic_iterator 43 : iterator_facade<basic_iterator<Tag, Category, Seq, Index>, Category> 44 { 45 typedef mpl::int_<Index> index; 46 typedef Seq seq_type; 47 48 template <typename It> 49 struct value_of 50 : extension::value_of_impl<Tag>::template apply<It> 51 {}; 52 53 template <typename It> 54 struct deref 55 : extension::deref_impl<Tag>::template apply<It> 56 {}; 57 58 template <typename It> 59 struct value_of_data 60 : extension::value_of_data_impl<Tag>::template apply<It> 61 {}; 62 63 template <typename It> 64 struct key_of 65 : extension::key_of_impl<Tag>::template apply<It> 66 {}; 67 68 template <typename It> 69 struct deref_data 70 : extension::deref_data_impl<Tag>::template apply<It> 71 {}; 72 73 template <typename It, typename N> 74 struct advance 75 { 76 typedef 77 basic_iterator<Tag, Category, Seq, Index + N::value> 78 type; 79 80 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 81 static type callboost::fusion::basic_iterator::advance82 call(It const& it) 83 { 84 return type(*it.seq,0); 85 } 86 }; 87 88 template <typename It> 89 struct next 90 : advance<It, mpl::int_<1> > 91 {}; 92 93 template <typename It> 94 struct prior 95 : advance<It, mpl::int_<-1> > 96 {}; 97 98 template <typename It1, typename It2> 99 struct distance 100 { 101 typedef mpl::minus<typename It2::index, typename It1::index> type; 102 103 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 104 static 105 type callboost::fusion::basic_iterator::distance106 call(It1 const&, It2 const&) 107 { 108 return type(); 109 } 110 }; 111 112 template <typename It1, typename It2> 113 struct equal_to 114 : mpl::and_< 115 is_same< 116 typename remove_const<typename It1::seq_type>::type 117 , typename remove_const<typename It2::seq_type>::type 118 > 119 , mpl::equal_to<typename It1::index,typename It2::index> 120 > 121 {}; 122 123 template<typename OtherSeq> 124 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED basic_iteratorboost::fusion::basic_iterator125 basic_iterator(basic_iterator<Tag,Category,OtherSeq,Index> const& it) 126 : seq(it.seq) 127 {} 128 129 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED basic_iteratorboost::fusion::basic_iterator130 basic_iterator(Seq& in_seq, int) 131 : seq(&in_seq) 132 {} 133 134 template<typename OtherSeq> 135 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED 136 basic_iterator& operator =boost::fusion::basic_iterator137 operator=(basic_iterator<Tag,Category,OtherSeq,Index> const& it) 138 { 139 seq=it.seq; 140 return *this; 141 } 142 143 Seq* seq; 144 }; 145 }} 146 147 #ifdef BOOST_FUSION_WORKAROUND_FOR_LWG_2408 148 namespace std 149 { 150 template <typename Tag, typename Category, typename Seq, int Index> 151 struct iterator_traits< ::boost::fusion::basic_iterator<Tag, Category, Seq, Index> > 152 { }; 153 } 154 #endif 155 156 #endif 157