1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2007 Dan Marsden
4 Copyright (c) 2009 Christopher Schmidt
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 ==============================================================================*/
9 #if !defined(FUSION_FIND_IF_05052005_1107)
10 #define FUSION_FIND_IF_05052005_1107
12 #include <boost/fusion/support/config.hpp>
13 #include <boost/mpl/apply.hpp>
14 #include <boost/mpl/eval_if.hpp>
15 #include <boost/mpl/identity.hpp>
16 #include <boost/mpl/lambda.hpp>
17 #include <boost/mpl/or.hpp>
18 #include <boost/fusion/iterator/advance.hpp>
19 #include <boost/fusion/iterator/distance.hpp>
20 #include <boost/fusion/iterator/equal_to.hpp>
21 #include <boost/fusion/iterator/next.hpp>
22 #include <boost/fusion/sequence/intrinsic/begin.hpp>
23 #include <boost/fusion/sequence/intrinsic/end.hpp>
24 #include <boost/fusion/support/category_of.hpp>
26 namespace boost { namespace fusion {
27 struct random_access_traversal_tag;
30 template <typename Iterator, typename Pred>
33 typedef typename mpl::apply1<
34 Pred, Iterator>::type type;
35 BOOST_STATIC_CONSTANT(int, value = type::value);
38 template <typename First, typename Last, typename Pred>
41 template <typename First, typename Last, typename Pred>
42 struct recursive_find_if
46 typename result_of::next<First>::type, Last, Pred
51 template <typename First, typename Last, typename Pred>
55 result_of::equal_to<First, Last>
56 , apply_filter<First, Pred> >
62 , mpl::identity<First>
63 , recursive_find_if<First, Last, Pred>
69 typename First, typename Last,
71 struct choose_find_if;
73 template<typename First, typename Last, typename Pred>
74 struct choose_find_if<First, Last, Pred, false>
75 : main_find_if<First, Last, Pred>
78 template<typename Iter, typename Pred, int n, int unrolling>
81 template <typename Iter, typename Pred, int offset>
82 struct apply_offset_filter
84 typedef typename result_of::advance_c<Iter, offset>::type Shifted;
91 BOOST_STATIC_CONSTANT(int, value = type::value);
94 template<typename Iter, typename Pred, int n>
95 struct unrolled_find_if
97 typedef typename mpl::eval_if<
98 apply_filter<Iter, Pred>,
101 apply_offset_filter<Iter, Pred, 1>,
102 result_of::advance_c<Iter, 1>,
104 apply_offset_filter<Iter, Pred, 2>,
105 result_of::advance_c<Iter, 2>,
107 apply_offset_filter<Iter, Pred, 3>,
108 result_of::advance_c<Iter, 3>,
113 4> > > > >::type type;
116 template<typename Iter, typename Pred>
117 struct unrolled_find_if<Iter, Pred, 3>
119 typedef typename mpl::eval_if<
120 apply_filter<Iter, Pred>,
123 apply_offset_filter<Iter, Pred, 1>,
124 result_of::advance_c<Iter, 1>,
126 apply_offset_filter<Iter, Pred, 2>,
127 result_of::advance_c<Iter, 2>,
128 result_of::advance_c<Iter, 3> > > >::type type;
131 template<typename Iter, typename Pred>
132 struct unrolled_find_if<Iter, Pred, 2>
134 typedef typename mpl::eval_if<
135 apply_filter<Iter, Pred>,
138 apply_offset_filter<Iter, Pred, 1>,
139 result_of::advance_c<Iter, 1>,
140 result_of::advance_c<Iter, 2> > >::type type;
143 template<typename Iter, typename Pred>
144 struct unrolled_find_if<Iter, Pred, 1>
146 typedef typename mpl::eval_if<
147 apply_filter<Iter, Pred>,
149 result_of::advance_c<Iter, 1> >::type type;
152 template<typename Iter, typename Pred, int n, int unrolling>
155 typedef typename unrolled_find_if<
156 typename result_of::advance_c<Iter, unrolling>::type,
158 n-unrolling>::type type;
161 template<typename Iter, typename Pred>
162 struct unrolled_find_if<Iter, Pred, 0>
167 template<typename First, typename Last, typename Pred>
168 struct choose_find_if<First, Last, Pred, true>
170 typedef typename result_of::distance<First, Last>::type N;
171 typedef typename unrolled_find_if<First, Pred, N::value>::type type;
174 template <typename First, typename Last, typename Pred>
175 struct static_find_if
181 , typename mpl::lambda<Pred>::type
182 , is_base_of<random_access_traversal_tag, typename traits::category_of<First>::type>::value
186 template <typename Iterator>
187 BOOST_FUSION_GPU_ENABLED
189 recursive_call(Iterator const& iter, mpl::true_)
194 template <typename Iterator>
195 BOOST_FUSION_GPU_ENABLED
197 recursive_call(Iterator const& iter, mpl::false_)
199 return recursive_call(fusion::next(iter));
202 template <typename Iterator>
203 BOOST_FUSION_GPU_ENABLED
205 recursive_call(Iterator const& iter)
207 typedef result_of::equal_to<Iterator, type> found;
208 return recursive_call(iter, found());
211 template <typename Iterator, typename Tag>
212 BOOST_FUSION_GPU_ENABLED
214 choose_call(Iterator const& iter, Tag)
216 return recursive_call(iter);
219 template <typename Iterator>
220 BOOST_FUSION_GPU_ENABLED
222 choose_call(Iterator const& iter, random_access_traversal_tag)
224 typedef typename result_of::distance<Iterator, type>::type N;
225 return fusion::advance<N>(iter);
228 template <typename Iterator>
229 BOOST_FUSION_GPU_ENABLED
231 iter_call(Iterator const& iter)
233 return choose_call(iter, typename traits::category_of<Iterator>::type());
236 template <typename Sequence>
237 BOOST_FUSION_GPU_ENABLED
241 return iter_call(fusion::begin(seq));
245 template <typename Sequence, typename Pred>
246 struct result_of_find_if
250 typename result_of::begin<Sequence>::type
251 , typename result_of::end<Sequence>::type
256 typedef typename filter::type type;