Chris@102
|
1 /*//////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
2 Copyright (c) 2013 Jamboree
|
Chris@102
|
3
|
Chris@102
|
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@102
|
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
6 //////////////////////////////////////////////////////////////////////////////*/
|
Chris@102
|
7 #ifndef BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED
|
Chris@102
|
8 #define BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED
|
Chris@102
|
9
|
Chris@102
|
10
|
Chris@102
|
11 #include <boost/fusion/support/config.hpp>
|
Chris@102
|
12 #include <boost/mpl/bool.hpp>
|
Chris@102
|
13 #include <boost/mpl/eval_if.hpp>
|
Chris@102
|
14 #include <boost/type_traits/remove_reference.hpp>
|
Chris@102
|
15 #include <boost/fusion/container/list/cons.hpp>
|
Chris@102
|
16 #include <boost/fusion/support/unused.hpp>
|
Chris@102
|
17 #include <boost/fusion/include/equal_to.hpp>
|
Chris@102
|
18 #include <boost/fusion/iterator/next.hpp>
|
Chris@102
|
19 #include <boost/fusion/iterator/deref.hpp>
|
Chris@102
|
20 #include <boost/fusion/iterator/value_of.hpp>
|
Chris@102
|
21
|
Chris@102
|
22
|
Chris@102
|
23 namespace boost { namespace fusion
|
Chris@102
|
24 {
|
Chris@102
|
25 struct forward_traversal_tag;
|
Chris@102
|
26 struct flatten_view_iterator_tag;
|
Chris@102
|
27
|
Chris@102
|
28 template<class First, class Base>
|
Chris@102
|
29 struct flatten_view_iterator
|
Chris@102
|
30 : iterator_base<flatten_view_iterator<First, Base> >
|
Chris@102
|
31 {
|
Chris@102
|
32 typedef flatten_view_iterator_tag fusion_tag;
|
Chris@102
|
33 typedef forward_traversal_tag category;
|
Chris@102
|
34
|
Chris@102
|
35 typedef convert_iterator<First> first_converter;
|
Chris@102
|
36 typedef typename first_converter::type first_type;
|
Chris@102
|
37 typedef Base base_type;
|
Chris@102
|
38
|
Chris@102
|
39 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
Chris@102
|
40 flatten_view_iterator(First const& first, Base const& base)
|
Chris@102
|
41 : first(first), base(base)
|
Chris@102
|
42 {}
|
Chris@102
|
43
|
Chris@102
|
44 first_type first;
|
Chris@102
|
45 base_type base;
|
Chris@102
|
46 };
|
Chris@102
|
47 }}
|
Chris@102
|
48
|
Chris@102
|
49 namespace boost { namespace fusion { namespace detail
|
Chris@102
|
50 {
|
Chris@102
|
51 template<class Iterator, class = void>
|
Chris@102
|
52 struct make_descent_cons
|
Chris@102
|
53 {
|
Chris@102
|
54 typedef cons<Iterator> type;
|
Chris@102
|
55
|
Chris@102
|
56 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
Chris@102
|
57 static inline type apply(Iterator const& it)
|
Chris@102
|
58 {
|
Chris@102
|
59 return type(it);
|
Chris@102
|
60 }
|
Chris@102
|
61 };
|
Chris@102
|
62
|
Chris@102
|
63 template<class Iterator>
|
Chris@102
|
64 struct make_descent_cons<Iterator,
|
Chris@102
|
65 typename enable_if<traits::is_sequence<
|
Chris@102
|
66 typename result_of::value_of<Iterator>::type> >::type>
|
Chris@102
|
67 {
|
Chris@102
|
68 // we use 'value_of' above for convenience, assuming the value won't be reference,
|
Chris@102
|
69 // while we must use the regular 'deref' here for const issues...
|
Chris@102
|
70 typedef typename
|
Chris@102
|
71 remove_reference<typename result_of::deref<Iterator>::type>::type
|
Chris@102
|
72 sub_sequence;
|
Chris@102
|
73
|
Chris@102
|
74 typedef typename
|
Chris@102
|
75 result_of::begin<sub_sequence>::type
|
Chris@102
|
76 sub_begin;
|
Chris@102
|
77
|
Chris@102
|
78 typedef cons<Iterator, typename make_descent_cons<sub_begin>::type> type;
|
Chris@102
|
79
|
Chris@102
|
80 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
Chris@102
|
81 static inline type apply(Iterator const& it)
|
Chris@102
|
82 {
|
Chris@102
|
83 return type(it, make_descent_cons<sub_begin>::apply(
|
Chris@102
|
84 fusion::begin(*it)));
|
Chris@102
|
85 }
|
Chris@102
|
86 };
|
Chris@102
|
87
|
Chris@102
|
88 template<class Cons, class Base>
|
Chris@102
|
89 struct build_flatten_view_iterator;
|
Chris@102
|
90
|
Chris@102
|
91 template<class Car, class Base>
|
Chris@102
|
92 struct build_flatten_view_iterator<cons<Car>, Base>
|
Chris@102
|
93 {
|
Chris@102
|
94 typedef flatten_view_iterator<Car, Base> type;
|
Chris@102
|
95
|
Chris@102
|
96 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
Chris@102
|
97 static inline type apply(cons<Car> const& cons, Base const& base)
|
Chris@102
|
98 {
|
Chris@102
|
99 return type(cons.car, base);
|
Chris@102
|
100 }
|
Chris@102
|
101 };
|
Chris@102
|
102
|
Chris@102
|
103 template<class Car, class Cdr, class Base>
|
Chris@102
|
104 struct build_flatten_view_iterator<cons<Car, Cdr>, Base>
|
Chris@102
|
105 {
|
Chris@102
|
106 typedef flatten_view_iterator<Car, Base> next_base;
|
Chris@102
|
107 typedef build_flatten_view_iterator<Cdr, next_base> next;
|
Chris@102
|
108 typedef typename next::type type;
|
Chris@102
|
109
|
Chris@102
|
110 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
Chris@102
|
111 static inline type apply(cons<Car, Cdr> const& cons, Base const& base)
|
Chris@102
|
112 {
|
Chris@102
|
113 return next::apply(cons.cdr, next_base(cons.car, base));
|
Chris@102
|
114 }
|
Chris@102
|
115 };
|
Chris@102
|
116
|
Chris@102
|
117 template<class Base, class Iterator, class = void>
|
Chris@102
|
118 struct seek_descent
|
Chris@102
|
119 {
|
Chris@102
|
120 typedef make_descent_cons<Iterator> make_descent_cons_;
|
Chris@102
|
121 typedef typename make_descent_cons_::type cons_type;
|
Chris@102
|
122 typedef
|
Chris@102
|
123 build_flatten_view_iterator<cons_type, Base>
|
Chris@102
|
124 build_flatten_view_iterator_;
|
Chris@102
|
125 typedef typename build_flatten_view_iterator_::type type;
|
Chris@102
|
126
|
Chris@102
|
127 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
Chris@102
|
128 static inline type apply(Base const& base, Iterator const& it)
|
Chris@102
|
129 {
|
Chris@102
|
130 return build_flatten_view_iterator_::apply(
|
Chris@102
|
131 make_descent_cons_::apply(it), base);
|
Chris@102
|
132 }
|
Chris@102
|
133 };
|
Chris@102
|
134
|
Chris@102
|
135 template<class Base, class Iterator>
|
Chris@102
|
136 struct seek_descent<Base, Iterator,
|
Chris@102
|
137 typename enable_if<
|
Chris@102
|
138 result_of::equal_to<Iterator, typename result_of::end<
|
Chris@102
|
139 typename result_of::value_of<Base>::type>::type> >::type>
|
Chris@102
|
140 {
|
Chris@102
|
141 typedef typename result_of::next<Base>::type type;
|
Chris@102
|
142
|
Chris@102
|
143 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
Chris@102
|
144 static inline type apply(Base const& base, Iterator const&)
|
Chris@102
|
145 {
|
Chris@102
|
146 return fusion::next(base);
|
Chris@102
|
147 }
|
Chris@102
|
148 };
|
Chris@102
|
149 }}}
|
Chris@102
|
150
|
Chris@102
|
151 namespace boost { namespace fusion { namespace extension
|
Chris@102
|
152 {
|
Chris@102
|
153 template<>
|
Chris@102
|
154 struct next_impl<flatten_view_iterator_tag>
|
Chris@102
|
155 {
|
Chris@102
|
156 template<typename Iterator>
|
Chris@102
|
157 struct apply
|
Chris@102
|
158 {
|
Chris@102
|
159 typedef typename Iterator::first_type first_type;
|
Chris@102
|
160 typedef typename Iterator::base_type base_type;
|
Chris@102
|
161 typedef typename result_of::next<first_type>::type next_type;
|
Chris@102
|
162
|
Chris@102
|
163 typedef detail::seek_descent<base_type, next_type> seek_descent;
|
Chris@102
|
164 typedef typename seek_descent::type type;
|
Chris@102
|
165
|
Chris@102
|
166 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
Chris@102
|
167 static inline
|
Chris@102
|
168 type call(Iterator const& it)
|
Chris@102
|
169 {
|
Chris@102
|
170 return seek_descent::apply(it.base, fusion::next(it.first));
|
Chris@102
|
171 }
|
Chris@102
|
172 };
|
Chris@102
|
173 };
|
Chris@102
|
174
|
Chris@102
|
175 template<>
|
Chris@102
|
176 struct deref_impl<flatten_view_iterator_tag>
|
Chris@102
|
177 {
|
Chris@102
|
178 template<typename Iterator>
|
Chris@102
|
179 struct apply
|
Chris@102
|
180 {
|
Chris@102
|
181 typedef typename
|
Chris@102
|
182 result_of::deref<typename Iterator::first_type>::type
|
Chris@102
|
183 type;
|
Chris@102
|
184
|
Chris@102
|
185 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
Chris@102
|
186 static inline
|
Chris@102
|
187 type call(Iterator const& it)
|
Chris@102
|
188 {
|
Chris@102
|
189 return *it.first;
|
Chris@102
|
190 }
|
Chris@102
|
191 };
|
Chris@102
|
192 };
|
Chris@102
|
193
|
Chris@102
|
194 template<>
|
Chris@102
|
195 struct value_of_impl<flatten_view_iterator_tag>
|
Chris@102
|
196 {
|
Chris@102
|
197 template<typename Iterator>
|
Chris@102
|
198 struct apply
|
Chris@102
|
199 {
|
Chris@102
|
200 typedef typename
|
Chris@102
|
201 result_of::value_of<typename Iterator::first_type>::type
|
Chris@102
|
202 type;
|
Chris@102
|
203 };
|
Chris@102
|
204 };
|
Chris@102
|
205 }}}
|
Chris@102
|
206
|
Chris@102
|
207 #ifdef BOOST_FUSION_WORKAROUND_FOR_LWG_2408
|
Chris@102
|
208 namespace std
|
Chris@102
|
209 {
|
Chris@102
|
210 template <typename First, typename Base>
|
Chris@102
|
211 struct iterator_traits< ::boost::fusion::flatten_view_iterator<First, Base> >
|
Chris@102
|
212 { };
|
Chris@102
|
213 }
|
Chris@102
|
214 #endif
|
Chris@102
|
215
|
Chris@102
|
216
|
Chris@102
|
217 #endif
|
Chris@102
|
218
|