1 /*==============================================================================
2 Copyright (c) 2013 Jamboree
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 #ifndef BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED
8 #define BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED
11 #include <boost/fusion/support/config.hpp>
12 #include <boost/mpl/bool.hpp>
13 #include <boost/mpl/eval_if.hpp>
14 #include <boost/type_traits/remove_reference.hpp>
15 #include <boost/fusion/container/list/cons.hpp>
16 #include <boost/fusion/support/unused.hpp>
17 #include <boost/fusion/include/equal_to.hpp>
18 #include <boost/fusion/iterator/next.hpp>
19 #include <boost/fusion/iterator/deref.hpp>
20 #include <boost/fusion/iterator/value_of.hpp>
23 namespace boost { namespace fusion
25 struct forward_traversal_tag;
26 struct flatten_view_iterator_tag;
28 template<class First, class Base>
29 struct flatten_view_iterator
30 : iterator_base<flatten_view_iterator<First, Base> >
32 typedef flatten_view_iterator_tag fusion_tag;
33 typedef forward_traversal_tag category;
35 typedef convert_iterator<First> first_converter;
36 typedef typename first_converter::type first_type;
37 typedef Base base_type;
39 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
40 flatten_view_iterator(First const& first, Base const& base)
41 : first(first), base(base)
49 namespace boost { namespace fusion { namespace detail
51 template<class Iterator, class = void>
52 struct make_descent_cons
54 typedef cons<Iterator> type;
56 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
57 static inline type apply(Iterator const& it)
63 template<class Iterator>
64 struct make_descent_cons<Iterator,
65 typename enable_if<traits::is_sequence<
66 typename result_of::value_of<Iterator>::type> >::type>
68 // we use 'value_of' above for convenience, assuming the value won't be reference,
69 // while we must use the regular 'deref' here for const issues...
71 remove_reference<typename result_of::deref<Iterator>::type>::type
75 result_of::begin<sub_sequence>::type
78 typedef cons<Iterator, typename make_descent_cons<sub_begin>::type> type;
80 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
81 static inline type apply(Iterator const& it)
83 return type(it, make_descent_cons<sub_begin>::apply(
88 template<class Cons, class Base>
89 struct build_flatten_view_iterator;
91 template<class Car, class Base>
92 struct build_flatten_view_iterator<cons<Car>, Base>
94 typedef flatten_view_iterator<Car, Base> type;
96 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
97 static inline type apply(cons<Car> const& cons, Base const& base)
99 return type(cons.car, base);
103 template<class Car, class Cdr, class Base>
104 struct build_flatten_view_iterator<cons<Car, Cdr>, Base>
106 typedef flatten_view_iterator<Car, Base> next_base;
107 typedef build_flatten_view_iterator<Cdr, next_base> next;
108 typedef typename next::type type;
110 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
111 static inline type apply(cons<Car, Cdr> const& cons, Base const& base)
113 return next::apply(cons.cdr, next_base(cons.car, base));
117 template<class Base, class Iterator, class = void>
120 typedef make_descent_cons<Iterator> make_descent_cons_;
121 typedef typename make_descent_cons_::type cons_type;
123 build_flatten_view_iterator<cons_type, Base>
124 build_flatten_view_iterator_;
125 typedef typename build_flatten_view_iterator_::type type;
127 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
128 static inline type apply(Base const& base, Iterator const& it)
130 return build_flatten_view_iterator_::apply(
131 make_descent_cons_::apply(it), base);
135 template<class Base, class Iterator>
136 struct seek_descent<Base, Iterator,
138 result_of::equal_to<Iterator, typename result_of::end<
139 typename result_of::value_of<Base>::type>::type> >::type>
141 typedef typename result_of::next<Base>::type type;
143 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
144 static inline type apply(Base const& base, Iterator const&)
146 return fusion::next(base);
151 namespace boost { namespace fusion { namespace extension
154 struct next_impl<flatten_view_iterator_tag>
156 template<typename Iterator>
159 typedef typename Iterator::first_type first_type;
160 typedef typename Iterator::base_type base_type;
161 typedef typename result_of::next<first_type>::type next_type;
163 typedef detail::seek_descent<base_type, next_type> seek_descent;
164 typedef typename seek_descent::type type;
166 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
168 type call(Iterator const& it)
170 return seek_descent::apply(it.base, fusion::next(it.first));
176 struct deref_impl<flatten_view_iterator_tag>
178 template<typename Iterator>
182 result_of::deref<typename Iterator::first_type>::type
185 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
187 type call(Iterator const& it)
195 struct value_of_impl<flatten_view_iterator_tag>
197 template<typename Iterator>
201 result_of::value_of<typename Iterator::first_type>::type
207 #ifdef BOOST_FUSION_WORKAROUND_FOR_LWG_2408
210 template <typename First, typename Base>
211 struct iterator_traits< ::boost::fusion::flatten_view_iterator<First, Base> >