segmented_find_if.hpp 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*=============================================================================
  2. Copyright (c) 2011 Eric Niebler
  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(BOOST_FUSION_SEGMENTED_FIND_IF_HPP_INCLUDED)
  7. #define BOOST_FUSION_SEGMENTED_FIND_IF_HPP_INCLUDED
  8. #include <boost/fusion/support/config.hpp>
  9. #include <boost/mpl/eval_if.hpp>
  10. #include <boost/mpl/identity.hpp>
  11. #include <boost/fusion/algorithm/query/find_if_fwd.hpp>
  12. #include <boost/fusion/iterator/equal_to.hpp>
  13. #include <boost/fusion/sequence/intrinsic/end.hpp>
  14. #include <boost/fusion/support/segmented_fold_until.hpp>
  15. namespace boost { namespace fusion { namespace detail
  16. {
  17. template <typename Pred>
  18. struct segmented_find_if_fun
  19. {
  20. template <typename Sequence, typename State, typename Context>
  21. struct apply
  22. {
  23. typedef
  24. typename result_of::find_if<Sequence, Pred>::type
  25. iterator_type;
  26. typedef
  27. typename result_of::equal_to<
  28. iterator_type
  29. , typename result_of::end<Sequence>::type
  30. >::type
  31. continue_type;
  32. typedef
  33. typename mpl::eval_if<
  34. continue_type
  35. , mpl::identity<State>
  36. , result_of::make_segmented_iterator<
  37. iterator_type
  38. , Context
  39. >
  40. >::type
  41. type;
  42. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  43. static type call(Sequence& seq, State const&state, Context const& context, segmented_find_if_fun)
  44. {
  45. return call_impl(seq, state, context, continue_type());
  46. }
  47. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  48. static type call_impl(Sequence&, State const&state, Context const&, mpl::true_)
  49. {
  50. return state;
  51. }
  52. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  53. static type call_impl(Sequence& seq, State const&, Context const& context, mpl::false_)
  54. {
  55. return fusion::make_segmented_iterator(fusion::find_if<Pred>(seq), context);
  56. }
  57. };
  58. };
  59. template <typename Sequence, typename Pred>
  60. struct result_of_segmented_find_if
  61. {
  62. struct filter
  63. {
  64. typedef
  65. typename result_of::segmented_fold_until<
  66. Sequence
  67. , typename result_of::end<Sequence>::type
  68. , segmented_find_if_fun<Pred>
  69. >::type
  70. type;
  71. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  72. static type call(Sequence& seq)
  73. {
  74. return fusion::segmented_fold_until(
  75. seq
  76. , fusion::end(seq)
  77. , segmented_find_if_fun<Pred>());
  78. }
  79. };
  80. typedef typename filter::type type;
  81. };
  82. }}}
  83. #endif