File indexing completed on 2025-01-31 09:41:54
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED
0008 #define BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED
0009
0010
0011 #include <boost/fusion/support/config.hpp>
0012 #include <boost/mpl/bool.hpp>
0013 #include <boost/mpl/eval_if.hpp>
0014 #include <boost/type_traits/remove_reference.hpp>
0015 #include <boost/fusion/container/list/cons.hpp>
0016 #include <boost/fusion/support/unused.hpp>
0017 #include <boost/fusion/include/equal_to.hpp>
0018 #include <boost/fusion/iterator/next.hpp>
0019 #include <boost/fusion/iterator/deref.hpp>
0020 #include <boost/fusion/iterator/value_of.hpp>
0021
0022 #ifdef _MSC_VER
0023 # pragma warning(push)
0024 # pragma warning(disable: 4512)
0025 #endif
0026
0027 namespace boost { namespace fusion
0028 {
0029 struct forward_traversal_tag;
0030 struct flatten_view_iterator_tag;
0031
0032 template<class First, class Base>
0033 struct flatten_view_iterator
0034 : iterator_base<flatten_view_iterator<First, Base> >
0035 {
0036 typedef flatten_view_iterator_tag fusion_tag;
0037 typedef forward_traversal_tag category;
0038
0039 typedef convert_iterator<First> first_converter;
0040 typedef typename first_converter::type first_type;
0041 typedef Base base_type;
0042
0043 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0044 flatten_view_iterator(First const& first, Base const& base)
0045 : first(first), base(base)
0046 {}
0047
0048 first_type first;
0049 base_type base;
0050 };
0051 }}
0052
0053 #ifdef _MSC_VER
0054 # pragma warning(pop)
0055 #endif
0056
0057 namespace boost { namespace fusion { namespace detail
0058 {
0059 template<class Iterator, class = void>
0060 struct make_descent_cons
0061 {
0062 typedef cons<Iterator> type;
0063
0064 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0065 static inline type apply(Iterator const& it)
0066 {
0067 return type(it);
0068 }
0069 };
0070
0071 template<class Iterator>
0072 struct make_descent_cons<Iterator,
0073 typename enable_if<traits::is_sequence<
0074 typename result_of::value_of<Iterator>::type> >::type>
0075 {
0076
0077
0078 typedef typename
0079 remove_reference<typename result_of::deref<Iterator>::type>::type
0080 sub_sequence;
0081
0082 typedef typename
0083 result_of::begin<sub_sequence>::type
0084 sub_begin;
0085
0086 typedef cons<Iterator, typename make_descent_cons<sub_begin>::type> type;
0087
0088 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0089 static inline type apply(Iterator const& it)
0090 {
0091 return type(it, make_descent_cons<sub_begin>::apply(
0092 fusion::begin(*it)));
0093 }
0094 };
0095
0096 template<class Cons, class Base>
0097 struct build_flatten_view_iterator;
0098
0099 template<class Car, class Base>
0100 struct build_flatten_view_iterator<cons<Car>, Base>
0101 {
0102 typedef flatten_view_iterator<Car, Base> type;
0103
0104 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0105 static inline type apply(cons<Car> const& cons, Base const& base)
0106 {
0107 return type(cons.car, base);
0108 }
0109 };
0110
0111 template<class Car, class Cdr, class Base>
0112 struct build_flatten_view_iterator<cons<Car, Cdr>, Base>
0113 {
0114 typedef flatten_view_iterator<Car, Base> next_base;
0115 typedef build_flatten_view_iterator<Cdr, next_base> next;
0116 typedef typename next::type type;
0117
0118 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0119 static inline type apply(cons<Car, Cdr> const& cons, Base const& base)
0120 {
0121 return next::apply(cons.cdr, next_base(cons.car, base));
0122 }
0123 };
0124
0125 template<class Base, class Iterator, class = void>
0126 struct seek_descent
0127 {
0128 typedef make_descent_cons<Iterator> make_descent_cons_;
0129 typedef typename make_descent_cons_::type cons_type;
0130 typedef
0131 build_flatten_view_iterator<cons_type, Base>
0132 build_flatten_view_iterator_;
0133 typedef typename build_flatten_view_iterator_::type type;
0134
0135 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0136 static inline type apply(Base const& base, Iterator const& it)
0137 {
0138 return build_flatten_view_iterator_::apply(
0139 make_descent_cons_::apply(it), base);
0140 }
0141 };
0142
0143 template<class Base, class Iterator>
0144 struct seek_descent<Base, Iterator,
0145 typename enable_if<
0146 result_of::equal_to<Iterator, typename result_of::end<
0147 typename result_of::value_of<Base>::type>::type> >::type>
0148 {
0149 typedef typename result_of::next<Base>::type type;
0150
0151 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0152 static inline type apply(Base const& base, Iterator const&)
0153 {
0154 return fusion::next(base);
0155 }
0156 };
0157 }}}
0158
0159 namespace boost { namespace fusion { namespace extension
0160 {
0161 template<>
0162 struct next_impl<flatten_view_iterator_tag>
0163 {
0164 template<typename Iterator>
0165 struct apply
0166 {
0167 typedef typename Iterator::first_type first_type;
0168 typedef typename Iterator::base_type base_type;
0169 typedef typename result_of::next<first_type>::type next_type;
0170
0171 typedef detail::seek_descent<base_type, next_type> seek_descent;
0172 typedef typename seek_descent::type type;
0173
0174 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0175 static inline
0176 type call(Iterator const& it)
0177 {
0178 return seek_descent::apply(it.base, fusion::next(it.first));
0179 }
0180 };
0181 };
0182
0183 template<>
0184 struct deref_impl<flatten_view_iterator_tag>
0185 {
0186 template<typename Iterator>
0187 struct apply
0188 {
0189 typedef typename
0190 result_of::deref<typename Iterator::first_type>::type
0191 type;
0192
0193 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0194 static inline
0195 type call(Iterator const& it)
0196 {
0197 return *it.first;
0198 }
0199 };
0200 };
0201
0202 template<>
0203 struct value_of_impl<flatten_view_iterator_tag>
0204 {
0205 template<typename Iterator>
0206 struct apply
0207 {
0208 typedef typename
0209 result_of::value_of<typename Iterator::first_type>::type
0210 type;
0211 };
0212 };
0213 }}}
0214
0215 #ifdef BOOST_FUSION_WORKAROUND_FOR_LWG_2408
0216 namespace std
0217 {
0218 template <typename First, typename Base>
0219 struct iterator_traits< ::boost::fusion::flatten_view_iterator<First, Base> >
0220 { };
0221 }
0222 #endif
0223
0224
0225 #endif
0226