]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/fusion/iterator/detail/segmented_next_impl.hpp
Update to boost 1.72
[lyx.git] / 3rdparty / boost / boost / fusion / iterator / detail / segmented_next_impl.hpp
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