flatten_view_iterator.hpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*==============================================================================
  2. Copyright (c) 2013 Jamboree
  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. #ifndef BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED
  7. #define BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED
  8. #include <boost/fusion/support/config.hpp>
  9. #include <boost/mpl/bool.hpp>
  10. #include <boost/mpl/eval_if.hpp>
  11. #include <boost/type_traits/remove_reference.hpp>
  12. #include <boost/fusion/container/list/cons.hpp>
  13. #include <boost/fusion/support/unused.hpp>
  14. #include <boost/fusion/include/equal_to.hpp>
  15. #include <boost/fusion/iterator/next.hpp>
  16. #include <boost/fusion/iterator/deref.hpp>
  17. #include <boost/fusion/iterator/value_of.hpp>
  18. namespace boost { namespace fusion
  19. {
  20. struct forward_traversal_tag;
  21. struct flatten_view_iterator_tag;
  22. template<class First, class Base>
  23. struct flatten_view_iterator
  24. : iterator_base<flatten_view_iterator<First, Base> >
  25. {
  26. typedef flatten_view_iterator_tag fusion_tag;
  27. typedef forward_traversal_tag category;
  28. typedef convert_iterator<First> first_converter;
  29. typedef typename first_converter::type first_type;
  30. typedef Base base_type;
  31. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  32. flatten_view_iterator(First const& first, Base const& base)
  33. : first(first), base(base)
  34. {}
  35. first_type first;
  36. base_type base;
  37. };
  38. }}
  39. namespace boost { namespace fusion { namespace detail
  40. {
  41. template<class Iterator, class = void>
  42. struct make_descent_cons
  43. {
  44. typedef cons<Iterator> type;
  45. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  46. static inline type apply(Iterator const& it)
  47. {
  48. return type(it);
  49. }
  50. };
  51. template<class Iterator>
  52. struct make_descent_cons<Iterator,
  53. typename enable_if<traits::is_sequence<
  54. typename result_of::value_of<Iterator>::type> >::type>
  55. {
  56. // we use 'value_of' above for convenience, assuming the value won't be reference,
  57. // while we must use the regular 'deref' here for const issues...
  58. typedef typename
  59. remove_reference<typename result_of::deref<Iterator>::type>::type
  60. sub_sequence;
  61. typedef typename
  62. result_of::begin<sub_sequence>::type
  63. sub_begin;
  64. typedef cons<Iterator, typename make_descent_cons<sub_begin>::type> type;
  65. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  66. static inline type apply(Iterator const& it)
  67. {
  68. return type(it, make_descent_cons<sub_begin>::apply(
  69. fusion::begin(*it)));
  70. }
  71. };
  72. template<class Cons, class Base>
  73. struct build_flatten_view_iterator;
  74. template<class Car, class Base>
  75. struct build_flatten_view_iterator<cons<Car>, Base>
  76. {
  77. typedef flatten_view_iterator<Car, Base> type;
  78. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  79. static inline type apply(cons<Car> const& cons, Base const& base)
  80. {
  81. return type(cons.car, base);
  82. }
  83. };
  84. template<class Car, class Cdr, class Base>
  85. struct build_flatten_view_iterator<cons<Car, Cdr>, Base>
  86. {
  87. typedef flatten_view_iterator<Car, Base> next_base;
  88. typedef build_flatten_view_iterator<Cdr, next_base> next;
  89. typedef typename next::type type;
  90. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  91. static inline type apply(cons<Car, Cdr> const& cons, Base const& base)
  92. {
  93. return next::apply(cons.cdr, next_base(cons.car, base));
  94. }
  95. };
  96. template<class Base, class Iterator, class = void>
  97. struct seek_descent
  98. {
  99. typedef make_descent_cons<Iterator> make_descent_cons_;
  100. typedef typename make_descent_cons_::type cons_type;
  101. typedef
  102. build_flatten_view_iterator<cons_type, Base>
  103. build_flatten_view_iterator_;
  104. typedef typename build_flatten_view_iterator_::type type;
  105. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  106. static inline type apply(Base const& base, Iterator const& it)
  107. {
  108. return build_flatten_view_iterator_::apply(
  109. make_descent_cons_::apply(it), base);
  110. }
  111. };
  112. template<class Base, class Iterator>
  113. struct seek_descent<Base, Iterator,
  114. typename enable_if<
  115. result_of::equal_to<Iterator, typename result_of::end<
  116. typename result_of::value_of<Base>::type>::type> >::type>
  117. {
  118. typedef typename result_of::next<Base>::type type;
  119. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  120. static inline type apply(Base const& base, Iterator const&)
  121. {
  122. return fusion::next(base);
  123. }
  124. };
  125. }}}
  126. namespace boost { namespace fusion { namespace extension
  127. {
  128. template<>
  129. struct next_impl<flatten_view_iterator_tag>
  130. {
  131. template<typename Iterator>
  132. struct apply
  133. {
  134. typedef typename Iterator::first_type first_type;
  135. typedef typename Iterator::base_type base_type;
  136. typedef typename result_of::next<first_type>::type next_type;
  137. typedef detail::seek_descent<base_type, next_type> seek_descent;
  138. typedef typename seek_descent::type type;
  139. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  140. static inline
  141. type call(Iterator const& it)
  142. {
  143. return seek_descent::apply(it.base, fusion::next(it.first));
  144. }
  145. };
  146. };
  147. template<>
  148. struct deref_impl<flatten_view_iterator_tag>
  149. {
  150. template<typename Iterator>
  151. struct apply
  152. {
  153. typedef typename
  154. result_of::deref<typename Iterator::first_type>::type
  155. type;
  156. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  157. static inline
  158. type call(Iterator const& it)
  159. {
  160. return *it.first;
  161. }
  162. };
  163. };
  164. template<>
  165. struct value_of_impl<flatten_view_iterator_tag>
  166. {
  167. template<typename Iterator>
  168. struct apply
  169. {
  170. typedef typename
  171. result_of::value_of<typename Iterator::first_type>::type
  172. type;
  173. };
  174. };
  175. }}}
  176. #ifdef BOOST_FUSION_WORKAROUND_FOR_LWG_2408
  177. namespace std
  178. {
  179. template <typename First, typename Base>
  180. struct iterator_traits< ::boost::fusion::flatten_view_iterator<First, Base> >
  181. { };
  182. }
  183. #endif
  184. #endif