Project revived from Feb2017
[EroSomnia.git] / deps / boost_1_63_0 / boost / fusion / iterator / detail / segmented_next_impl.hpp
blob62502ceef5f274d35d820d132ba2a07b22a282f9
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;
26 namespace detail
28 template <typename Sequence, typename Stack>
29 struct segmented_begin_impl;
31 //bool is_invalid(stack)
32 //{
33 // return empty(car(stack));
34 //}
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
42 {};
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 //}
52 template <typename Stack>
53 struct pop_front_car
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
62 car_type;
64 typedef
65 cons<car_type, typename Stack::cdr_type>
66 type;
68 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
69 static type call(Stack const & stack)
71 return type(
72 car_type(fusion::next(stack.car.first), stack.car.last),
73 stack.cdr);
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;
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 //}
93 template <
94 typename Stack,
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);
127 // else
128 // return res;
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
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>
160 typedef Result type;
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))
174 // return next;
175 // else
176 // return segmented_next_impl_recurse(cdr(stack));
177 // else
178 // return segmented_next_impl_recurse2(next)
181 template <typename Stack, typename Next, bool IsInvalid, int StackSize>
182 struct segmented_next_impl_recurse
184 typedef
185 typename segmented_next_impl_recurse<typename Stack::cdr_type>::type
186 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>
198 typedef Next type;
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));
226 // else
227 // return next;
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
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>
249 typedef Next type;
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>
265 #endif