1 /*============================================================================= 2 Copyright (c) 2011 Eric Niebler 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(BOOST_FUSION_SEGMENTED_ITERATOR_SEGMENTED_ITERATOR_HPP_INCLUDED) 8 #define BOOST_FUSION_SEGMENTED_ITERATOR_SEGMENTED_ITERATOR_HPP_INCLUDED 9 10 #include <boost/fusion/support/config.hpp> 11 #include <boost/mpl/bool.hpp> 12 #include <boost/fusion/sequence/intrinsic_fwd.hpp> 13 #include <boost/fusion/iterator/iterator_facade.hpp> 14 #include <boost/fusion/iterator/deref.hpp> 15 #include <boost/fusion/iterator/deref_data.hpp> 16 #include <boost/fusion/iterator/key_of.hpp> 17 #include <boost/fusion/iterator/value_of.hpp> 18 #include <boost/fusion/iterator/value_of_data.hpp> 19 #include <boost/fusion/iterator/detail/segmented_equal_to.hpp> 20 21 namespace boost { namespace fusion 22 { 23 struct nil_; 24 25 namespace detail 26 { 27 template <typename Stack> 28 struct segmented_next_impl; 29 } 30 31 // A segmented iterator wraps a "context", which is a cons list 32 // of ranges, the frontmost is range over values and the rest 33 // are ranges over internal segments. 34 template <typename Context> 35 struct segmented_iterator 36 : iterator_facade<segmented_iterator<Context>, forward_traversal_tag> 37 { segmented_iteratorboost::fusion::segmented_iterator38 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED explicit segmented_iterator(Context const& ctx) 39 : context(ctx) 40 {} 41 42 //auto deref(it) 43 //{ 44 // return deref(begin(car(it.context))) 45 //} 46 template <typename It> 47 struct deref 48 { 49 typedef 50 typename result_of::deref< 51 typename It::context_type::car_type::begin_type 52 >::type 53 type; 54 55 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED callboost::fusion::segmented_iterator::deref56 static type call(It const& it) 57 { 58 return *it.context.car.first; 59 } 60 }; 61 62 //auto deref_data(it) 63 //{ 64 // return deref_data(begin(car(it.context))) 65 //} 66 template <typename It> 67 struct deref_data 68 { 69 typedef 70 typename result_of::deref_data< 71 typename It::context_type::car_type::begin_type 72 >::type 73 type; 74 75 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED callboost::fusion::segmented_iterator::deref_data76 static type call(It const& it) 77 { 78 return fusion::deref_data(it.context.car.first); 79 } 80 }; 81 82 //auto key_of(it) 83 //{ 84 // return key_of(begin(car(it.context))) 85 //} 86 template <typename It> 87 struct key_of 88 : result_of::key_of<typename It::context_type::car_type::begin_type> 89 {}; 90 91 //auto value_of(it) 92 //{ 93 // return value_of(begin(car(it.context))) 94 //} 95 template <typename It> 96 struct value_of 97 : result_of::value_of<typename It::context_type::car_type::begin_type> 98 {}; 99 100 //auto value_of_data(it) 101 //{ 102 // return value_of_data(begin(car(it.context))) 103 //} 104 template <typename It> 105 struct value_of_data 106 : result_of::value_of_data<typename It::context_type::car_type::begin_type> 107 {}; 108 109 // Compare all the segment iterators in each stack, starting with 110 // the bottom-most. 111 template < 112 typename It1 113 , typename It2 114 , int Size1 = It1::context_type::size::value 115 , int Size2 = It2::context_type::size::value 116 > 117 struct equal_to 118 : mpl::false_ 119 {}; 120 121 template <typename It1, typename It2, int Size> 122 struct equal_to<It1, It2, Size, Size> 123 : detail::segmented_equal_to< 124 typename It1::context_type 125 , typename It2::context_type 126 > 127 {}; 128 129 template <typename It> 130 struct next 131 { 132 typedef detail::segmented_next_impl<typename It::context_type> impl; 133 typedef segmented_iterator<typename impl::type> type; 134 135 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED callboost::fusion::segmented_iterator::next136 static type call(It const& it) 137 { 138 return type(impl::call(it.context)); 139 } 140 }; 141 142 typedef Context context_type; 143 context_type context; 144 }; 145 146 }} 147 148 #endif 149