any.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2005 Eric Niebler
  4. Copyright (c) 2007 Dan Marsden
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. ==============================================================================*/
  8. #if !defined(FUSION_ANY_05052005_1229)
  9. #define FUSION_ANY_05052005_1229
  10. #include <boost/fusion/support/config.hpp>
  11. #include <boost/mpl/bool.hpp>
  12. #include <boost/fusion/sequence/intrinsic/begin.hpp>
  13. #include <boost/fusion/sequence/intrinsic/end.hpp>
  14. #include <boost/fusion/iterator/advance.hpp>
  15. #include <boost/fusion/iterator/equal_to.hpp>
  16. #include <boost/fusion/iterator/next.hpp>
  17. #include <boost/fusion/iterator/deref.hpp>
  18. #include <boost/fusion/iterator/distance.hpp>
  19. namespace boost { namespace fusion {
  20. struct random_access_traversal_tag;
  21. namespace detail
  22. {
  23. template <typename First, typename Last, typename F>
  24. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  25. inline bool
  26. linear_any(First const&, Last const&, F const&, mpl::true_)
  27. {
  28. return false;
  29. }
  30. template <typename First, typename Last, typename F>
  31. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  32. inline bool
  33. linear_any(First const& first, Last const& last, F& f, mpl::false_)
  34. {
  35. typename result_of::deref<First>::type x = *first;
  36. return f(x) ||
  37. detail::linear_any(
  38. fusion::next(first)
  39. , last
  40. , f
  41. , result_of::equal_to<typename result_of::next<First>::type, Last>());
  42. }
  43. template <typename Sequence, typename F, typename Tag>
  44. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  45. inline bool
  46. any(Sequence const& seq, F f, Tag)
  47. {
  48. return detail::linear_any(
  49. fusion::begin(seq)
  50. , fusion::end(seq)
  51. , f
  52. , result_of::equal_to<
  53. typename result_of::begin<Sequence>::type
  54. , typename result_of::end<Sequence>::type>());
  55. }
  56. template<int N>
  57. struct unrolled_any
  58. {
  59. template <typename It, typename F>
  60. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  61. static bool call(It const& it, F f)
  62. {
  63. return
  64. f(*it) ||
  65. f(*fusion::advance_c<1>(it))||
  66. f(*fusion::advance_c<2>(it)) ||
  67. f(*fusion::advance_c<3>(it)) ||
  68. detail::unrolled_any<N-4>::call(fusion::advance_c<4>(it), f);
  69. }
  70. };
  71. template<>
  72. struct unrolled_any<3>
  73. {
  74. template <typename It, typename F>
  75. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  76. static bool call(It const& it, F f)
  77. {
  78. return
  79. f(*it) ||
  80. f(*fusion::advance_c<1>(it)) ||
  81. f(*fusion::advance_c<2>(it));
  82. }
  83. };
  84. template<>
  85. struct unrolled_any<2>
  86. {
  87. template <typename It, typename F>
  88. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  89. static bool call(It const& it, F f)
  90. {
  91. return
  92. f(*it) ||
  93. f(*fusion::advance_c<1>(it));
  94. }
  95. };
  96. template<>
  97. struct unrolled_any<1>
  98. {
  99. template <typename It, typename F>
  100. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  101. static bool call(It const& it, F f)
  102. {
  103. return f(*it);
  104. }
  105. };
  106. template<>
  107. struct unrolled_any<0>
  108. {
  109. template <typename It, typename F>
  110. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  111. static bool call(It const&, F)
  112. {
  113. return false;
  114. }
  115. };
  116. template <typename Sequence, typename F>
  117. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  118. inline bool
  119. any(Sequence const& 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. return detail::unrolled_any<result_of::distance<begin, end>::type::value>::call(
  124. fusion::begin(seq), f);
  125. }
  126. }}}
  127. #endif