1 /*=============================================================================
2 Copyright (c) 2011 Eric Niebler
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
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>
18 namespace boost
{ namespace fusion
20 template <typename First
, typename Second
>
21 struct iterator_range
;
23 template <typename Context
>
24 struct segmented_iterator
;
28 template <typename Sequence
, typename Stack
>
29 struct segmented_begin_impl
;
31 //bool is_invalid(stack)
33 // return empty(car(stack));
36 template <typename Stack
>
38 : result_of::equal_to
<
39 typename
Stack::car_type::begin_type
,
40 typename
Stack::car_type::end_type
44 ////Advance the first iterator in the seq at the
45 ////top of a stack of iterator ranges. Return the
47 //auto pop_front_car(stack)
49 // return cons(iterator_range(next(begin(car(stack))), end(car(stack))), cdr(stack));
52 template <typename Stack
>
57 typename
result_of::next
<
58 typename
Stack::car_type::begin_type
60 , typename
Stack::car_type::end_type
65 cons
<car_type
, typename
Stack::cdr_type
>
68 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
69 static type
call(Stack
const & stack
)
72 car_type(fusion::next(stack
.car
.first
), stack
.car
.last
),
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
;
84 // Handle the case where the top of the stack has no usable
85 //auto segmented_next_impl_recurse3(stack)
87 // if (size(stack) == 1)
88 // return cons(iterator_range(end(car(stack)), end(car(stack))), nil_);
90 // return segmented_next_impl_recurse(stack.cdr);
95 int StackSize
= Stack::size::value
>
96 struct segmented_next_impl_recurse3
98 typedef segmented_next_impl_recurse
<typename
Stack::cdr_type
> impl
;
99 typedef typename
impl::type type
;
101 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
102 static type
call(Stack
const & stack
)
104 return impl::call(stack
.cdr
);
108 template <typename Stack
>
109 struct segmented_next_impl_recurse3
<Stack
, 1>
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
;
115 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
116 static type
call(Stack
const & stack
)
118 return type(range_type(stack
.car
.last
, stack
.car
.last
));
122 //auto segmented_next_impl_recurse2(stack)
124 // auto res = segmented_begin_impl(front(car(stack)), stack);
125 // if (is_invalid(res))
126 // return segmented_next_impl_recurse3(stack);
134 typename remove_reference
<
136 typename
result_of::deref
<
137 typename
Stack::car_type::begin_type
142 typename segmented_begin_impl
<Sequence
, Stack
>::type
,
144 is_invalid
<Result
>::value
>
145 struct segmented_next_impl_recurse2
147 typedef segmented_next_impl_recurse3
<Stack
> impl
;
148 typedef typename
impl::type type
;
150 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
151 static type
call(Stack
const & stack
)
153 return impl::call(stack
);
157 template <typename Stack
, typename Sequence
, typename Result
>
158 struct segmented_next_impl_recurse2
<Stack
, Sequence
, Result
, false>
162 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
163 static type
call(Stack
const & stack
)
165 return segmented_begin_impl
<Sequence
, Stack
>::call(*stack
.car
.first
, stack
);
169 //auto segmented_next_impl_recurse(stack)
171 // auto next = pop_front_car(stack);
172 // if (is_invalid(next))
173 // if (1 == size(stack))
176 // return segmented_next_impl_recurse(cdr(stack));
178 // return segmented_next_impl_recurse2(next)
181 template <typename Stack
, typename Next
, bool IsInvalid
, int StackSize
>
182 struct segmented_next_impl_recurse
185 typename segmented_next_impl_recurse
<typename
Stack::cdr_type
>::type
188 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
189 static type
call(Stack
const& stack
)
191 return segmented_next_impl_recurse
<typename
Stack::cdr_type
>::call(stack
.cdr
);
195 template <typename Stack
, typename Next
>
196 struct segmented_next_impl_recurse
<Stack
, Next
, true, 1>
200 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
201 static type
call(Stack
const & stack
)
203 return pop_front_car
<Stack
>::call(stack
);
207 template <typename Stack
, typename Next
, int StackSize
>
208 struct segmented_next_impl_recurse
<Stack
, Next
, false, StackSize
>
210 typedef segmented_next_impl_recurse2
<Next
> impl
;
211 typedef typename
impl::type type
;
213 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
214 static type
call(Stack
const & stack
)
216 return impl::call(pop_front_car
<Stack
>::call(stack
));
220 //auto segmented_next_impl(stack)
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));
232 typename Next
= typename pop_front_car
<Stack
>::type
,
233 bool IsInvalid
= is_invalid
<Next
>::value
>
234 struct segmented_next_impl_aux
236 typedef segmented_next_impl_recurse
<typename
Stack::cdr_type
> impl
;
237 typedef typename
impl::type type
;
239 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
240 static type
call(Stack
const & stack
)
242 return impl::call(stack
.cdr
);
246 template <typename Stack
, typename Next
>
247 struct segmented_next_impl_aux
<Stack
, Next
, false>
251 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
252 static type
call(Stack
const & stack
)
254 return pop_front_car
<Stack
>::call(stack
);
258 template <typename Stack
>
259 struct segmented_next_impl
260 : segmented_next_impl_aux
<Stack
>