/Src/Dependencies/Boost/boost/fusion/algorithm/query/detail/find_if.hpp

http://hadesmem.googlecode.com/ · C++ Header · 232 lines · 199 code · 25 blank · 8 comment · 0 complexity · 39dc02829adb29a552af80f3f430e13e MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2001-2006 Joel de Guzman
  3. Copyright (c) 2007 Dan Marsden
  4. Copyright (c) 2009 Christopher Schmidt
  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_FIND_IF_05052005_1107)
  9. #define FUSION_FIND_IF_05052005_1107
  10. #include <boost/mpl/eval_if.hpp>
  11. #include <boost/mpl/or.hpp>
  12. #include <boost/mpl/lambda.hpp>
  13. #include <boost/mpl/apply.hpp>
  14. #include <boost/mpl/identity.hpp>
  15. #include <boost/fusion/iterator/equal_to.hpp>
  16. #include <boost/fusion/iterator/next.hpp>
  17. #include <boost/fusion/sequence/intrinsic/begin.hpp>
  18. #include <boost/fusion/iterator/advance.hpp>
  19. #include <boost/fusion/iterator/distance.hpp>
  20. #include <boost/fusion/support/category_of.hpp>
  21. #include <boost/mpl/eval_if.hpp>
  22. #include <boost/mpl/identity.hpp>
  23. namespace boost { namespace fusion {
  24. struct random_access_traversal_tag;
  25. namespace detail
  26. {
  27. template <typename Iterator, typename Pred>
  28. struct apply_filter
  29. {
  30. typedef typename mpl::apply1<
  31. Pred, Iterator>::type type;
  32. BOOST_STATIC_CONSTANT(int, value = type::value);
  33. };
  34. template <typename First, typename Last, typename Pred>
  35. struct main_find_if;
  36. template <typename First, typename Last, typename Pred>
  37. struct recursive_find_if
  38. {
  39. typedef typename
  40. main_find_if<
  41. typename result_of::next<First>::type, Last, Pred
  42. >::type
  43. type;
  44. };
  45. template <typename First, typename Last, typename Pred>
  46. struct main_find_if
  47. {
  48. typedef mpl::or_<
  49. result_of::equal_to<First, Last>
  50. , apply_filter<First, Pred> >
  51. filter;
  52. typedef typename
  53. mpl::eval_if<
  54. filter
  55. , mpl::identity<First>
  56. , recursive_find_if<First, Last, Pred>
  57. >::type
  58. type;
  59. };
  60. template<
  61. typename First, typename Last,
  62. typename Pred, bool>
  63. struct choose_find_if;
  64. template<typename First, typename Last, typename Pred>
  65. struct choose_find_if<First, Last, Pred, false>
  66. : main_find_if<First, Last, Pred>
  67. {};
  68. template<typename Iter, typename Pred, int n, int unrolling>
  69. struct unroll_again;
  70. template <typename Iter, typename Pred, int offset>
  71. struct apply_offset_filter
  72. {
  73. typedef typename result_of::advance_c<Iter, offset>::type Shifted;
  74. typedef typename
  75. mpl::apply1<
  76. Pred
  77. , Shifted
  78. >::type
  79. type;
  80. BOOST_STATIC_CONSTANT(int, value = type::value);
  81. };
  82. template<typename Iter, typename Pred, int n>
  83. struct unrolled_find_if
  84. {
  85. typedef typename mpl::eval_if<
  86. apply_filter<Iter, Pred>,
  87. mpl::identity<Iter>,
  88. mpl::eval_if<
  89. apply_offset_filter<Iter, Pred, 1>,
  90. result_of::advance_c<Iter, 1>,
  91. mpl::eval_if<
  92. apply_offset_filter<Iter, Pred, 2>,
  93. result_of::advance_c<Iter, 2>,
  94. mpl::eval_if<
  95. apply_offset_filter<Iter, Pred, 3>,
  96. result_of::advance_c<Iter, 3>,
  97. unroll_again<
  98. Iter,
  99. Pred,
  100. n,
  101. 4> > > > >::type type;
  102. };
  103. template<typename Iter, typename Pred>
  104. struct unrolled_find_if<Iter, Pred, 3>
  105. {
  106. typedef typename mpl::eval_if<
  107. apply_filter<Iter, Pred>,
  108. mpl::identity<Iter>,
  109. mpl::eval_if<
  110. apply_offset_filter<Iter, Pred, 1>,
  111. result_of::advance_c<Iter, 1>,
  112. mpl::eval_if<
  113. apply_offset_filter<Iter, Pred, 2>,
  114. result_of::advance_c<Iter, 2>,
  115. result_of::advance_c<Iter, 3> > > >::type type;
  116. };
  117. template<typename Iter, typename Pred>
  118. struct unrolled_find_if<Iter, Pred, 2>
  119. {
  120. typedef typename mpl::eval_if<
  121. apply_filter<Iter, Pred>,
  122. mpl::identity<Iter>,
  123. mpl::eval_if<
  124. apply_offset_filter<Iter, Pred, 1>,
  125. result_of::advance_c<Iter, 1>,
  126. result_of::advance_c<Iter, 2> > >::type type;
  127. };
  128. template<typename Iter, typename Pred>
  129. struct unrolled_find_if<Iter, Pred, 1>
  130. {
  131. typedef typename mpl::eval_if<
  132. apply_filter<Iter, Pred>,
  133. mpl::identity<Iter>,
  134. result_of::advance_c<Iter, 1> >::type type;
  135. };
  136. template<typename Iter, typename Pred, int n, int unrolling>
  137. struct unroll_again
  138. {
  139. typedef typename unrolled_find_if<
  140. typename result_of::advance_c<Iter, unrolling>::type,
  141. Pred,
  142. n-unrolling>::type type;
  143. };
  144. template<typename Iter, typename Pred>
  145. struct unrolled_find_if<Iter, Pred, 0>
  146. {
  147. typedef Iter type;
  148. };
  149. template<typename First, typename Last, typename Pred>
  150. struct choose_find_if<First, Last, Pred, true>
  151. {
  152. typedef typename result_of::distance<First, Last>::type N;
  153. typedef typename unrolled_find_if<First, Pred, N::value>::type type;
  154. };
  155. template <typename First, typename Last, typename Pred>
  156. struct static_find_if
  157. {
  158. typedef typename
  159. choose_find_if<
  160. First
  161. , Last
  162. , typename mpl::lambda<Pred>::type
  163. , is_base_of<random_access_traversal_tag, typename traits::category_of<First>::type>::value
  164. >::type
  165. type;
  166. template <typename Iterator>
  167. static type
  168. recursive_call(Iterator const& iter, mpl::true_)
  169. {
  170. return iter;
  171. }
  172. template <typename Iterator>
  173. static type
  174. recursive_call(Iterator const& iter, mpl::false_)
  175. {
  176. return recursive_call(fusion::next(iter));
  177. }
  178. template <typename Iterator>
  179. static type
  180. recursive_call(Iterator const& iter)
  181. {
  182. typedef result_of::equal_to<Iterator, type> found;
  183. return recursive_call(iter, found());
  184. }
  185. template <typename Iterator, typename Tag>
  186. static type
  187. choose_call(Iterator const& iter, Tag)
  188. {
  189. return recursive_call(iter);
  190. }
  191. template <typename Iterator>
  192. static type
  193. choose_call(Iterator const& iter, random_access_traversal_tag)
  194. {
  195. typedef typename result_of::distance<Iterator, type>::type N;
  196. return fusion::advance<N>(iter);
  197. }
  198. template <typename Iterator>
  199. static type
  200. call(Iterator const& iter)
  201. {
  202. return choose_call(iter, typename traits::category_of<Iterator>::type());
  203. }
  204. };
  205. }}}
  206. #endif