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/type_traits/add_const.hpp>
11 #include <boost/type_traits/remove_reference.hpp>
12 #include <boost/fusion/iterator/equal_to.hpp>
13 #include <boost/fusion/container/list/cons_fwd.hpp>
14 #include <boost/fusion/iterator/next.hpp>
15 #include <boost/fusion/iterator/deref.hpp>
17 namespace boost { namespace fusion
19 template <typename First, typename Second>
20 struct iterator_range;
22 template <typename Context>
23 struct segmented_iterator;
27 template <typename Sequence, typename Stack>
28 struct segmented_begin_impl;
30 //bool is_invalid(stack)
32 // return empty(car(stack));
35 template <typename Stack>
37 : result_of::equal_to<
38 typename Stack::car_type::begin_type,
39 typename Stack::car_type::end_type
43 ////Advance the first iterator in the seq at the
44 ////top of a stack of iterator ranges. Return the
46 //auto pop_front_car(stack)
48 // return cons(iterator_range(next(begin(car(stack))), end(car(stack))), cdr(stack));
51 template <typename Stack>
56 typename result_of::next<
57 typename Stack::car_type::begin_type
59 , typename Stack::car_type::end_type
64 cons<car_type, typename Stack::cdr_type>
67 static type call(Stack const & stack)
70 car_type(fusion::next(stack.car.first), stack.car.last),
77 typename Next = typename pop_front_car<Stack>::type,
78 bool IsInvalid = is_invalid<Next>::value,
79 int StackSize = Stack::size::value>
80 struct segmented_next_impl_recurse;
82 // Handle the case where the top of the stack has no usable
83 //auto segmented_next_impl_recurse3(stack)
85 // if (size(stack) == 1)
86 // return cons(iterator_range(end(car(stack)), end(car(stack))), nil_);
88 // return segmented_next_impl_recurse(stack.cdr);
93 int StackSize = Stack::size::value>
94 struct segmented_next_impl_recurse3
96 typedef segmented_next_impl_recurse<typename Stack::cdr_type> impl;
97 typedef typename impl::type type;
99 static type call(Stack const & stack)
101 return impl::call(stack.cdr);
105 template <typename Stack>
106 struct segmented_next_impl_recurse3<Stack, 1>
108 typedef typename Stack::car_type::end_type end_type;
109 typedef iterator_range<end_type, end_type> range_type;
110 typedef cons<range_type> type;
112 static type call(Stack const & stack)
114 return type(range_type(stack.car.last, stack.car.last));
118 //auto segmented_next_impl_recurse2(stack)
120 // auto res = segmented_begin_impl(front(car(stack)), stack);
121 // if (is_invalid(res))
122 // return segmented_next_impl_recurse3(stack);
130 typename remove_reference<
132 typename result_of::deref<
133 typename Stack::car_type::begin_type
138 typename segmented_begin_impl<Sequence, Stack>::type,
140 is_invalid<Result>::value>
141 struct segmented_next_impl_recurse2
143 typedef segmented_next_impl_recurse3<Stack> impl;
144 typedef typename impl::type type;
146 static type call(Stack const & stack)
148 return impl::call(stack);
152 template <typename Stack, typename Sequence, typename Result>
153 struct segmented_next_impl_recurse2<Stack, Sequence, Result, false>
157 static type call(Stack const & stack)
159 return segmented_begin_impl<Sequence, Stack>::call(*stack.car.first, stack);
163 //auto segmented_next_impl_recurse(stack)
165 // auto next = pop_front_car(stack);
166 // if (is_invalid(next))
167 // if (1 == size(stack))
170 // return segmented_next_impl_recurse(cdr(stack));
172 // return segmented_next_impl_recurse2(next)
175 template <typename Stack, typename Next, bool IsInvalid, int StackSize>
176 struct segmented_next_impl_recurse
179 typename segmented_next_impl_recurse<typename Stack::cdr_type>::type
182 static type call(Stack const& stack)
184 return segmented_next_impl_recurse<typename Stack::cdr_type>::call(stack.cdr);
188 template <typename Stack, typename Next>
189 struct segmented_next_impl_recurse<Stack, Next, true, 1>
193 static type call(Stack const & stack)
195 return pop_front_car<Stack>::call(stack);
199 template <typename Stack, typename Next, int StackSize>
200 struct segmented_next_impl_recurse<Stack, Next, false, StackSize>
202 typedef segmented_next_impl_recurse2<Next> impl;
203 typedef typename impl::type type;
205 static type call(Stack const & stack)
207 return impl::call(pop_front_car<Stack>::call(stack));
211 //auto segmented_next_impl(stack)
213 // // car(stack) is a seq of values, not a seq of segments
214 // auto next = pop_front_car(stack);
215 // if (is_invalid(next))
216 // return segmented_next_impl_recurse(cdr(next));
223 typename Next = typename pop_front_car<Stack>::type,
224 bool IsInvalid = is_invalid<Next>::value>
225 struct segmented_next_impl_aux
227 typedef segmented_next_impl_recurse<typename Stack::cdr_type> impl;
228 typedef typename impl::type type;
230 static type call(Stack const & stack)
232 return impl::call(stack.cdr);
236 template <typename Stack, typename Next>
237 struct segmented_next_impl_aux<Stack, Next, false>
241 static type call(Stack const & stack)
243 return pop_front_car<Stack>::call(stack);
247 template <typename Stack>
248 struct segmented_next_impl
249 : segmented_next_impl_aux<Stack>