/Src/Dependencies/Boost/boost/fusion/algorithm/query/ext_/find_if_s.hpp

http://hadesmem.googlecode.com/ · C++ Header · 222 lines · 187 code · 28 blank · 7 comment · 0 complexity · 287d16238a9249fc1c5e564db8b889de MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2006 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(FIND_IF_S_05152006_1027)
  7. #define FIND_IF_S_05152006_1027
  8. #include <boost/mpl/not.hpp>
  9. #include <boost/mpl/assert.hpp>
  10. #include <boost/mpl/eval_if.hpp>
  11. #include <boost/type_traits/is_const.hpp>
  12. #include <boost/utility/enable_if.hpp>
  13. #include <boost/type_traits/is_same.hpp>
  14. #include <boost/fusion/algorithm/query/find_if.hpp>
  15. #include <boost/fusion/container/list/cons.hpp>
  16. #include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
  17. #include <boost/fusion/view/ext_/segmented_iterator.hpp>
  18. #include <boost/fusion/view/ext_/segmented_iterator_range.hpp>
  19. #include <boost/fusion/support/ext_/is_segmented.hpp>
  20. // fwd declarations
  21. namespace boost { namespace fusion
  22. {
  23. namespace detail
  24. {
  25. template<typename Sequence, typename Pred, bool IsSegmented = traits::is_segmented<Sequence>::value>
  26. struct static_find_if_s_recurse;
  27. }
  28. namespace result_of
  29. {
  30. template <typename Sequence, typename Pred>
  31. struct find_if_s;
  32. }
  33. }}
  34. namespace boost { namespace fusion { namespace detail
  35. {
  36. template<typename Sequence, typename Where, bool IsSegmented = traits::is_segmented<Sequence>::value>
  37. struct is_found
  38. : mpl::not_<result_of::equal_to<Where, typename result_of::end<Sequence>::type> >
  39. {};
  40. template<typename Sequence, typename Cons>
  41. struct is_found<Sequence, Cons, true>
  42. : mpl::not_<is_same<nil, Cons> >
  43. {};
  44. template<
  45. typename SegmentedRange
  46. , typename Where
  47. , typename Sequence = typename remove_reference<
  48. typename result_of::deref<
  49. typename SegmentedRange::iterator_type
  50. >::type
  51. >::type
  52. , bool IsSegmented = traits::is_segmented<Sequence>::value
  53. >
  54. struct as_segmented_cons
  55. {
  56. typedef cons<
  57. SegmentedRange
  58. , cons<segmented_range<Sequence, Where, false> >
  59. > type;
  60. static type call(SegmentedRange const &range, Where const &where)
  61. {
  62. return fusion::make_cons(
  63. range
  64. , fusion::make_cons(
  65. segmented_range<Sequence, Where, false>(*fusion::begin(range), where)
  66. )
  67. );
  68. }
  69. };
  70. template<
  71. typename SegmentedRange
  72. , typename Where
  73. , typename Sequence
  74. >
  75. struct as_segmented_cons<SegmentedRange, Where, Sequence, true>
  76. {
  77. typedef cons<SegmentedRange, Where> type;
  78. static type call(SegmentedRange const &range, Where const &where)
  79. {
  80. return fusion::make_cons(range, where);
  81. }
  82. };
  83. template<
  84. typename SegmentedRange
  85. , typename Pred
  86. , bool IsEmpty = is_empty<SegmentedRange>::value
  87. >
  88. struct static_find_if_s_seg
  89. {
  90. typedef typename SegmentedRange::iterator_type first;
  91. typedef typename result_of::deref<first>::type segment_ref;
  92. typedef typename remove_reference<segment_ref>::type segment;
  93. typedef static_find_if_s_recurse<segment, Pred> where;
  94. typedef range_next<SegmentedRange> next;
  95. typedef is_found<segment, typename where::type> is_found;
  96. typedef as_segmented_cons<SegmentedRange, typename where::type> found;
  97. typedef static_find_if_s_seg<typename next::type, Pred> not_found;
  98. typedef typename mpl::eval_if<is_found, found, not_found>::type type;
  99. static type call(SegmentedRange const &range)
  100. {
  101. return call_(range, is_found());
  102. }
  103. private:
  104. static type call_(SegmentedRange const &range, mpl::true_)
  105. {
  106. return found::call(range, where::call(*range.where_));
  107. }
  108. static type call_(SegmentedRange const &range, mpl::false_)
  109. {
  110. return not_found::call(next::call(range));
  111. }
  112. };
  113. template<
  114. typename SegmentedRange
  115. , typename Pred
  116. >
  117. struct static_find_if_s_seg<SegmentedRange, Pred, true>
  118. {
  119. typedef nil type;
  120. static type call(SegmentedRange const &)
  121. {
  122. return nil();
  123. }
  124. };
  125. template<typename Sequence, typename Pred>
  126. struct static_find_if_s_recurse<Sequence, Pred, true>
  127. {
  128. typedef typename as_segmented_range<Sequence>::type range;
  129. typedef static_find_if_s_seg<range, Pred> find_if;
  130. typedef typename find_if::type type;
  131. static type call(Sequence &seq)
  132. {
  133. return find_if::call(range(fusion::segments(seq)));
  134. }
  135. };
  136. template<typename Sequence, typename Pred>
  137. struct static_find_if_s_recurse<Sequence, Pred, false>
  138. {
  139. typedef typename result_of::find_if<Sequence, Pred>::type type;
  140. static type call(Sequence &seq)
  141. {
  142. return fusion::find_if<Pred>(seq);
  143. }
  144. };
  145. template<typename Sequence, typename Pred, bool IsSegmented = traits::is_segmented<Sequence>::value>
  146. struct static_find_if_s
  147. : static_find_if_s_recurse<Sequence, Pred, IsSegmented>
  148. {};
  149. template<typename Sequence, typename Pred>
  150. struct static_find_if_s<Sequence, Pred, true>
  151. {
  152. typedef typename as_segmented_range<Sequence>::type range;
  153. typedef static_find_if_s_recurse<Sequence, Pred> find_if;
  154. typedef typename find_if::type found;
  155. typedef segmented_iterator<typename reverse_cons<found>::type> type;
  156. static type call(Sequence &seq)
  157. {
  158. return type(reverse_cons<found>::call(find_if::call(seq)));
  159. }
  160. };
  161. }}}
  162. namespace boost { namespace fusion
  163. {
  164. namespace result_of
  165. {
  166. template <typename Sequence, typename Pred>
  167. struct find_if_s
  168. {
  169. typedef typename
  170. detail::static_find_if_s<
  171. Sequence
  172. , Pred
  173. >::type
  174. type;
  175. };
  176. }
  177. template <typename Pred, typename Sequence>
  178. typename lazy_disable_if<
  179. is_const<Sequence>
  180. , result_of::find_if_s<Sequence, Pred>
  181. >::type
  182. find_if_s(Sequence& seq)
  183. {
  184. return detail::static_find_if_s<Sequence, Pred>::call(seq);
  185. }
  186. template <typename Pred, typename Sequence>
  187. typename result_of::find_if_s<Sequence const, Pred>::type
  188. find_if_s(Sequence const& seq)
  189. {
  190. return detail::static_find_if_s<Sequence const, Pred>::call(seq);
  191. }
  192. }}
  193. #endif