flatten_view_iterator.hpp 6.7 KB

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