segmented_next_impl.hpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*=============================================================================
  2. Copyright (c) 2011 Eric Niebler
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #if !defined(BOOST_FUSION_SEGMENTED_ITERATOR_NEXT_IMPL_HPP_INCLUDED)
  7. #define BOOST_FUSION_SEGMENTED_ITERATOR_NEXT_IMPL_HPP_INCLUDED
  8. #include <boost/fusion/support/config.hpp>
  9. #include <boost/type_traits/add_const.hpp>
  10. #include <boost/type_traits/remove_reference.hpp>
  11. #include <boost/fusion/iterator/equal_to.hpp>
  12. #include <boost/fusion/container/list/cons_fwd.hpp>
  13. #include <boost/fusion/iterator/next.hpp>
  14. #include <boost/fusion/iterator/deref.hpp>
  15. namespace boost { namespace fusion
  16. {
  17. template <typename First, typename Second>
  18. struct iterator_range;
  19. template <typename Context>
  20. struct segmented_iterator;
  21. namespace detail
  22. {
  23. template <typename Sequence, typename Stack>
  24. struct segmented_begin_impl;
  25. //bool is_invalid(stack)
  26. //{
  27. // return empty(car(stack));
  28. //}
  29. template <typename Stack>
  30. struct is_invalid
  31. : result_of::equal_to<
  32. typename Stack::car_type::begin_type,
  33. typename Stack::car_type::end_type
  34. >
  35. {};
  36. ////Advance the first iterator in the seq at the
  37. ////top of a stack of iterator ranges. Return the
  38. ////new stack.
  39. //auto pop_front_car(stack)
  40. //{
  41. // return cons(iterator_range(next(begin(car(stack))), end(car(stack))), cdr(stack));
  42. //}
  43. template <typename Stack>
  44. struct pop_front_car
  45. {
  46. typedef
  47. iterator_range<
  48. typename result_of::next<
  49. typename Stack::car_type::begin_type
  50. >::type
  51. , typename Stack::car_type::end_type
  52. >
  53. car_type;
  54. typedef
  55. cons<car_type, typename Stack::cdr_type>
  56. type;
  57. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  58. static type call(Stack const & stack)
  59. {
  60. return type(
  61. car_type(fusion::next(stack.car.first), stack.car.last),
  62. stack.cdr);
  63. }
  64. };
  65. template <
  66. typename Stack,
  67. typename Next = typename pop_front_car<Stack>::type,
  68. bool IsInvalid = is_invalid<Next>::value,
  69. int StackSize = Stack::size::value>
  70. struct segmented_next_impl_recurse;
  71. // Handle the case where the top of the stack has no usable
  72. //auto segmented_next_impl_recurse3(stack)
  73. //{
  74. // if (size(stack) == 1)
  75. // return cons(iterator_range(end(car(stack)), end(car(stack))), nil_);
  76. // else
  77. // return segmented_next_impl_recurse(stack.cdr);
  78. //}
  79. template <
  80. typename Stack,
  81. int StackSize = Stack::size::value>
  82. struct segmented_next_impl_recurse3
  83. {
  84. typedef segmented_next_impl_recurse<typename Stack::cdr_type> impl;
  85. typedef typename impl::type type;
  86. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  87. static type call(Stack const & stack)
  88. {
  89. return impl::call(stack.cdr);
  90. }
  91. };
  92. template <typename Stack>
  93. struct segmented_next_impl_recurse3<Stack, 1>
  94. {
  95. typedef typename Stack::car_type::end_type end_type;
  96. typedef iterator_range<end_type, end_type> range_type;
  97. typedef cons<range_type> type;
  98. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  99. static type call(Stack const & stack)
  100. {
  101. return type(range_type(stack.car.last, stack.car.last));
  102. }
  103. };
  104. //auto segmented_next_impl_recurse2(stack)
  105. //{
  106. // auto res = segmented_begin_impl(front(car(stack)), stack);
  107. // if (is_invalid(res))
  108. // return segmented_next_impl_recurse3(stack);
  109. // else
  110. // return res;
  111. //}
  112. template <
  113. typename Stack,
  114. typename Sequence =
  115. typename remove_reference<
  116. typename add_const<
  117. typename result_of::deref<
  118. typename Stack::car_type::begin_type
  119. >::type
  120. >::type
  121. >::type,
  122. typename Result =
  123. typename segmented_begin_impl<Sequence, Stack>::type,
  124. bool IsInvalid =
  125. is_invalid<Result>::value>
  126. struct segmented_next_impl_recurse2
  127. {
  128. typedef segmented_next_impl_recurse3<Stack> impl;
  129. typedef typename impl::type type;
  130. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  131. static type call(Stack const & stack)
  132. {
  133. return impl::call(stack);
  134. }
  135. };
  136. template <typename Stack, typename Sequence, typename Result>
  137. struct segmented_next_impl_recurse2<Stack, Sequence, Result, false>
  138. {
  139. typedef Result type;
  140. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  141. static type call(Stack const & stack)
  142. {
  143. return segmented_begin_impl<Sequence, Stack>::call(*stack.car.first, stack);
  144. }
  145. };
  146. //auto segmented_next_impl_recurse(stack)
  147. //{
  148. // auto next = pop_front_car(stack);
  149. // if (is_invalid(next))
  150. // if (1 == size(stack))
  151. // return next;
  152. // else
  153. // return segmented_next_impl_recurse(cdr(stack));
  154. // else
  155. // return segmented_next_impl_recurse2(next)
  156. //}
  157. template <typename Stack, typename Next, bool IsInvalid, int StackSize>
  158. struct segmented_next_impl_recurse
  159. {
  160. typedef
  161. typename segmented_next_impl_recurse<typename Stack::cdr_type>::type
  162. type;
  163. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  164. static type call(Stack const& stack)
  165. {
  166. return segmented_next_impl_recurse<typename Stack::cdr_type>::call(stack.cdr);
  167. }
  168. };
  169. template <typename Stack, typename Next>
  170. struct segmented_next_impl_recurse<Stack, Next, true, 1>
  171. {
  172. typedef Next type;
  173. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  174. static type call(Stack const & stack)
  175. {
  176. return pop_front_car<Stack>::call(stack);
  177. }
  178. };
  179. template <typename Stack, typename Next, int StackSize>
  180. struct segmented_next_impl_recurse<Stack, Next, false, StackSize>
  181. {
  182. typedef segmented_next_impl_recurse2<Next> impl;
  183. typedef typename impl::type type;
  184. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  185. static type call(Stack const & stack)
  186. {
  187. return impl::call(pop_front_car<Stack>::call(stack));
  188. }
  189. };
  190. //auto segmented_next_impl(stack)
  191. //{
  192. // // car(stack) is a seq of values, not a seq of segments
  193. // auto next = pop_front_car(stack);
  194. // if (is_invalid(next))
  195. // return segmented_next_impl_recurse(cdr(next));
  196. // else
  197. // return next;
  198. //}
  199. template <
  200. typename Stack,
  201. typename Next = typename pop_front_car<Stack>::type,
  202. bool IsInvalid = is_invalid<Next>::value>
  203. struct segmented_next_impl_aux
  204. {
  205. typedef segmented_next_impl_recurse<typename Stack::cdr_type> impl;
  206. typedef typename impl::type type;
  207. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  208. static type call(Stack const & stack)
  209. {
  210. return impl::call(stack.cdr);
  211. }
  212. };
  213. template <typename Stack, typename Next>
  214. struct segmented_next_impl_aux<Stack, Next, false>
  215. {
  216. typedef Next type;
  217. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  218. static type call(Stack const & stack)
  219. {
  220. return pop_front_car<Stack>::call(stack);
  221. }
  222. };
  223. template <typename Stack>
  224. struct segmented_next_impl
  225. : segmented_next_impl_aux<Stack>
  226. {};
  227. }
  228. }}
  229. #endif