for_each.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  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(FUSION_FOR_EACH_05052005_1028)
  7. #define FUSION_FOR_EACH_05052005_1028
  8. #include <boost/fusion/support/config.hpp>
  9. #include <boost/fusion/sequence/intrinsic/begin.hpp>
  10. #include <boost/fusion/sequence/intrinsic/end.hpp>
  11. #include <boost/fusion/iterator/equal_to.hpp>
  12. #include <boost/fusion/iterator/next.hpp>
  13. #include <boost/fusion/iterator/deref.hpp>
  14. #include <boost/fusion/iterator/distance.hpp>
  15. #include <boost/fusion/support/category_of.hpp>
  16. #include <boost/mpl/bool.hpp>
  17. namespace boost { namespace fusion {
  18. namespace detail
  19. {
  20. template <typename First, typename Last, typename F>
  21. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  22. inline void
  23. for_each_linear(First const&, Last const&, F const&, mpl::true_)
  24. {
  25. }
  26. template <typename First, typename Last, typename F>
  27. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  28. inline void
  29. for_each_linear(First const& first, Last const& last, F& f, mpl::false_)
  30. {
  31. f(*first);
  32. detail::for_each_linear(fusion::next(first), last, f,
  33. result_of::equal_to<typename result_of::next<First>::type, Last>());
  34. }
  35. template <typename Sequence, typename F, typename Tag>
  36. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  37. inline void
  38. for_each_dispatch(Sequence& seq, F& f, Tag)
  39. {
  40. detail::for_each_linear(
  41. fusion::begin(seq)
  42. , fusion::end(seq)
  43. , f
  44. , result_of::equal_to<
  45. typename result_of::begin<Sequence>::type
  46. , typename result_of::end<Sequence>::type>());
  47. }
  48. template<int N>
  49. struct for_each_unrolled
  50. {
  51. template<typename I0, typename F>
  52. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  53. static void call(I0 const& i0, F& f)
  54. {
  55. f(*i0);
  56. typedef typename result_of::next<I0>::type I1;
  57. I1 i1(fusion::next(i0));
  58. f(*i1);
  59. typedef typename result_of::next<I1>::type I2;
  60. I2 i2(fusion::next(i1));
  61. f(*i2);
  62. typedef typename result_of::next<I2>::type I3;
  63. I3 i3(fusion::next(i2));
  64. f(*i3);
  65. for_each_unrolled<N-4>::call(fusion::next(i3), f);
  66. }
  67. };
  68. template<>
  69. struct for_each_unrolled<3>
  70. {
  71. template<typename I0, typename F>
  72. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  73. static void call(I0 const& i0, F& f)
  74. {
  75. f(*i0);
  76. typedef typename result_of::next<I0>::type I1;
  77. I1 i1(fusion::next(i0));
  78. f(*i1);
  79. typedef typename result_of::next<I1>::type I2;
  80. I2 i2(fusion::next(i1));
  81. f(*i2);
  82. }
  83. };
  84. template<>
  85. struct for_each_unrolled<2>
  86. {
  87. template<typename I0, typename F>
  88. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  89. static void call(I0 const& i0, F& f)
  90. {
  91. f(*i0);
  92. typedef typename result_of::next<I0>::type I1;
  93. I1 i1(fusion::next(i0));
  94. f(*i1);
  95. }
  96. };
  97. template<>
  98. struct for_each_unrolled<1>
  99. {
  100. template<typename I0, typename F>
  101. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  102. static void call(I0 const& i0, F& f)
  103. {
  104. f(*i0);
  105. }
  106. };
  107. template<>
  108. struct for_each_unrolled<0>
  109. {
  110. template<typename It, typename F>
  111. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  112. static void call(It const&, F const&)
  113. {
  114. }
  115. };
  116. template <typename Sequence, typename F>
  117. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  118. inline void
  119. for_each_dispatch(Sequence& seq, F& f, random_access_traversal_tag)
  120. {
  121. typedef typename result_of::begin<Sequence>::type begin;
  122. typedef typename result_of::end<Sequence>::type end;
  123. for_each_unrolled<result_of::distance<begin, end>::type::value>::call(fusion::begin(seq), f);
  124. }
  125. template <typename Sequence, typename F>
  126. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  127. inline void
  128. for_each(Sequence& seq, F& f, mpl::false_) // unsegmented implementation
  129. {
  130. detail::for_each_dispatch(seq, f, typename traits::category_of<Sequence>::type());
  131. }
  132. }}}
  133. #endif