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_NEXT_IMPL_HPP_INCLUDED) |
8 | #define BOOST_FUSION_SEGMENTED_ITERATOR_NEXT_IMPL_HPP_INCLUDED |
9 | |
10 | #include <boost/fusion/support/config.hpp> |
11 | #include <boost/type_traits/add_const.hpp> |
12 | #include <boost/type_traits/remove_reference.hpp> |
13 | #include <boost/fusion/iterator/equal_to.hpp> |
14 | #include <boost/fusion/container/list/cons_fwd.hpp> |
15 | #include <boost/fusion/iterator/next.hpp> |
16 | #include <boost/fusion/iterator/deref.hpp> |
17 | |
18 | namespace boost { namespace fusion |
19 | { |
20 | template <typename First, typename Second> |
21 | struct iterator_range; |
22 | |
23 | template <typename Context> |
24 | struct segmented_iterator; |
25 | |
26 | namespace detail |
27 | { |
28 | template <typename Sequence, typename Stack> |
29 | struct segmented_begin_impl; |
30 | |
31 | //bool is_invalid(stack) |
32 | //{ |
33 | // return empty(car(stack)); |
34 | //} |
35 | |
36 | template <typename Stack> |
37 | struct is_invalid |
38 | : result_of::equal_to< |
39 | typename Stack::car_type::begin_type, |
40 | typename Stack::car_type::end_type |
41 | > |
42 | {}; |
43 | |
44 | ////Advance the first iterator in the seq at the |
45 | ////top of a stack of iterator ranges. Return the |
46 | ////new stack. |
47 | //auto pop_front_car(stack) |
48 | //{ |
49 | // return cons(iterator_range(next(begin(car(stack))), end(car(stack))), cdr(stack)); |
50 | //} |
51 | |
52 | template <typename Stack> |
53 | struct pop_front_car |
54 | { |
55 | typedef |
56 | iterator_range< |
57 | typename result_of::next< |
58 | typename Stack::car_type::begin_type |
59 | >::type |
60 | , typename Stack::car_type::end_type |
61 | > |
62 | car_type; |
63 | |
64 | typedef |
65 | cons<car_type, typename Stack::cdr_type> |
66 | type; |
67 | |
68 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
69 | static type call(Stack const & stack) |
70 | { |
71 | return type( |
72 | car_type(fusion::next(stack.car.first), stack.car.last), |
73 | stack.cdr); |
74 | } |
75 | }; |
76 | |
77 | template < |
78 | typename Stack, |
79 | typename Next = typename pop_front_car<Stack>::type, |
80 | bool IsInvalid = is_invalid<Next>::value, |
81 | int StackSize = Stack::size::value> |
82 | struct segmented_next_impl_recurse; |
83 | |
84 | // Handle the case where the top of the stack has no usable |
85 | //auto segmented_next_impl_recurse3(stack) |
86 | //{ |
87 | // if (size(stack) == 1) |
88 | // return cons(iterator_range(end(car(stack)), end(car(stack))), nil_); |
89 | // else |
90 | // return segmented_next_impl_recurse(stack.cdr); |
91 | //} |
92 | |
93 | template < |
94 | typename Stack, |
95 | int StackSize = Stack::size::value> |
96 | struct segmented_next_impl_recurse3 |
97 | { |
98 | typedef segmented_next_impl_recurse<typename Stack::cdr_type> impl; |
99 | typedef typename impl::type type; |
100 | |
101 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
102 | static type call(Stack const & stack) |
103 | { |
104 | return impl::call(stack.cdr); |
105 | } |
106 | }; |
107 | |
108 | template <typename Stack> |
109 | struct segmented_next_impl_recurse3<Stack, 1> |
110 | { |
111 | typedef typename Stack::car_type::end_type end_type; |
112 | typedef iterator_range<end_type, end_type> range_type; |
113 | typedef cons<range_type> type; |
114 | |
115 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
116 | static type call(Stack const & stack) |
117 | { |
118 | return type(range_type(stack.car.last, stack.car.last)); |
119 | } |
120 | }; |
121 | |
122 | //auto segmented_next_impl_recurse2(stack) |
123 | //{ |
124 | // auto res = segmented_begin_impl(front(car(stack)), stack); |
125 | // if (is_invalid(res)) |
126 | // return segmented_next_impl_recurse3(stack); |
127 | // else |
128 | // return res; |
129 | //} |
130 | |
131 | template < |
132 | typename Stack, |
133 | typename Sequence = |
134 | typename remove_reference< |
135 | typename add_const< |
136 | typename result_of::deref< |
137 | typename Stack::car_type::begin_type |
138 | >::type |
139 | >::type |
140 | >::type, |
141 | typename Result = |
142 | typename segmented_begin_impl<Sequence, Stack>::type, |
143 | bool IsInvalid = |
144 | is_invalid<Result>::value> |
145 | struct segmented_next_impl_recurse2 |
146 | { |
147 | typedef segmented_next_impl_recurse3<Stack> impl; |
148 | typedef typename impl::type type; |
149 | |
150 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
151 | static type call(Stack const & stack) |
152 | { |
153 | return impl::call(stack); |
154 | } |
155 | }; |
156 | |
157 | template <typename Stack, typename Sequence, typename Result> |
158 | struct segmented_next_impl_recurse2<Stack, Sequence, Result, false> |
159 | { |
160 | typedef Result type; |
161 | |
162 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
163 | static type call(Stack const & stack) |
164 | { |
165 | return segmented_begin_impl<Sequence, Stack>::call(*stack.car.first, stack); |
166 | } |
167 | }; |
168 | |
169 | //auto segmented_next_impl_recurse(stack) |
170 | //{ |
171 | // auto next = pop_front_car(stack); |
172 | // if (is_invalid(next)) |
173 | // if (1 == size(stack)) |
174 | // return next; |
175 | // else |
176 | // return segmented_next_impl_recurse(cdr(stack)); |
177 | // else |
178 | // return segmented_next_impl_recurse2(next) |
179 | //} |
180 | |
181 | template <typename Stack, typename Next, bool IsInvalid, int StackSize> |
182 | struct segmented_next_impl_recurse |
183 | { |
184 | typedef |
185 | typename segmented_next_impl_recurse<typename Stack::cdr_type>::type |
186 | type; |
187 | |
188 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
189 | static type call(Stack const& stack) |
190 | { |
191 | return segmented_next_impl_recurse<typename Stack::cdr_type>::call(stack.cdr); |
192 | } |
193 | }; |
194 | |
195 | template <typename Stack, typename Next> |
196 | struct segmented_next_impl_recurse<Stack, Next, true, 1> |
197 | { |
198 | typedef Next type; |
199 | |
200 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
201 | static type call(Stack const & stack) |
202 | { |
203 | return pop_front_car<Stack>::call(stack); |
204 | } |
205 | }; |
206 | |
207 | template <typename Stack, typename Next, int StackSize> |
208 | struct segmented_next_impl_recurse<Stack, Next, false, StackSize> |
209 | { |
210 | typedef segmented_next_impl_recurse2<Next> impl; |
211 | typedef typename impl::type type; |
212 | |
213 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
214 | static type call(Stack const & stack) |
215 | { |
216 | return impl::call(pop_front_car<Stack>::call(stack)); |
217 | } |
218 | }; |
219 | |
220 | //auto segmented_next_impl(stack) |
221 | //{ |
222 | // // car(stack) is a seq of values, not a seq of segments |
223 | // auto next = pop_front_car(stack); |
224 | // if (is_invalid(next)) |
225 | // return segmented_next_impl_recurse(cdr(next)); |
226 | // else |
227 | // return next; |
228 | //} |
229 | |
230 | template < |
231 | typename Stack, |
232 | typename Next = typename pop_front_car<Stack>::type, |
233 | bool IsInvalid = is_invalid<Next>::value> |
234 | struct segmented_next_impl_aux |
235 | { |
236 | typedef segmented_next_impl_recurse<typename Stack::cdr_type> impl; |
237 | typedef typename impl::type type; |
238 | |
239 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
240 | static type call(Stack const & stack) |
241 | { |
242 | return impl::call(stack.cdr); |
243 | } |
244 | }; |
245 | |
246 | template <typename Stack, typename Next> |
247 | struct segmented_next_impl_aux<Stack, Next, false> |
248 | { |
249 | typedef Next type; |
250 | |
251 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
252 | static type call(Stack const & stack) |
253 | { |
254 | return pop_front_car<Stack>::call(stack); |
255 | } |
256 | }; |
257 | |
258 | template <typename Stack> |
259 | struct segmented_next_impl |
260 | : segmented_next_impl_aux<Stack> |
261 | {}; |
262 | } |
263 | }} |
264 | |
265 | #endif |
266 | |