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
18namespace 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

source code of include/boost/fusion/iterator/detail/segmented_next_impl.hpp