any.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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/mpl/bool.hpp>
  11. #include <boost/fusion/sequence/intrinsic/begin.hpp>
  12. #include <boost/fusion/sequence/intrinsic/end.hpp>
  13. #include <boost/fusion/iterator/advance.hpp>
  14. #include <boost/fusion/iterator/equal_to.hpp>
  15. #include <boost/fusion/iterator/next.hpp>
  16. #include <boost/fusion/iterator/deref.hpp>
  17. #include <boost/fusion/iterator/distance.hpp>
  18. namespace boost { namespace fusion {
  19. struct random_access_traversal_tag;
  20. namespace detail
  21. {
  22. template <typename First, typename Last, typename F>
  23. inline bool
  24. linear_any(First const&, Last const&, F const&, mpl::true_)
  25. {
  26. return false;
  27. }
  28. template <typename First, typename Last, typename F>
  29. inline bool
  30. linear_any(First const& first, Last const& last, F& f, mpl::false_)
  31. {
  32. typename result_of::deref<First>::type x = *first;
  33. return f(x) ||
  34. detail::linear_any(
  35. fusion::next(first)
  36. , last
  37. , f
  38. , result_of::equal_to<typename result_of::next<First>::type, Last>());
  39. }
  40. template <typename Sequence, typename F, typename Tag>
  41. inline bool
  42. any(Sequence const& seq, F f, Tag)
  43. {
  44. return detail::linear_any(
  45. fusion::begin(seq)
  46. , fusion::end(seq)
  47. , f
  48. , result_of::equal_to<
  49. typename result_of::begin<Sequence>::type
  50. , typename result_of::end<Sequence>::type>());
  51. }
  52. template<int N>
  53. struct unrolled_any
  54. {
  55. template <typename It, typename F>
  56. static bool call(It const& it, F f)
  57. {
  58. return
  59. f(*it) ||
  60. f(*fusion::advance_c<1>(it))||
  61. f(*fusion::advance_c<2>(it)) ||
  62. f(*fusion::advance_c<3>(it)) ||
  63. detail::unrolled_any<N-4>::call(fusion::advance_c<4>(it), f);
  64. }
  65. };
  66. template<>
  67. struct unrolled_any<3>
  68. {
  69. template <typename It, typename F>
  70. static bool call(It const& it, F f)
  71. {
  72. return
  73. f(*it) ||
  74. f(*fusion::advance_c<1>(it)) ||
  75. f(*fusion::advance_c<2>(it));
  76. }
  77. };
  78. template<>
  79. struct unrolled_any<2>
  80. {
  81. template <typename It, typename F>
  82. static bool call(It const& it, F f)
  83. {
  84. return
  85. f(*it) ||
  86. f(*fusion::advance_c<1>(it));
  87. }
  88. };
  89. template<>
  90. struct unrolled_any<1>
  91. {
  92. template <typename It, typename F>
  93. static bool call(It const& it, F f)
  94. {
  95. return f(*it);
  96. }
  97. };
  98. template<>
  99. struct unrolled_any<0>
  100. {
  101. template <typename It, typename F>
  102. static bool call(It const&, F)
  103. {
  104. return false;
  105. }
  106. };
  107. template <typename Sequence, typename F>
  108. inline bool
  109. any(Sequence const& seq, F f, random_access_traversal_tag)
  110. {
  111. typedef typename result_of::begin<Sequence>::type begin;
  112. typedef typename result_of::end<Sequence>::type end;
  113. return detail::unrolled_any<result_of::distance<begin, end>::type::value>::call(
  114. fusion::begin(seq), f);
  115. }
  116. }}}
  117. #endif