1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2007 Dan Marsden
4 Copyright (c) 2009 Christopher Schmidt
5 Copyright (c) 2018 Kohei Takahashi
7 Distributed under the Boost Software License, Version 1.0. (See accompanying
8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 ==============================================================================*/
10 #if !defined(FUSION_FIND_IF_05052005_1107)
11 #define FUSION_FIND_IF_05052005_1107
13 #include <boost/fusion/support/config.hpp>
14 #include <boost/mpl/apply.hpp>
15 #include <boost/mpl/eval_if.hpp>
16 #include <boost/mpl/identity.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>
25 #include <boost/core/enable_if.hpp>
27 namespace boost { namespace fusion { namespace detail
29 template <typename Iterator, typename Pred>
32 typedef typename mpl::apply1<
33 Pred, Iterator>::type type;
34 BOOST_STATIC_CONSTANT(int, value = type::value);
37 template <typename First, typename Last, typename Pred>
40 template <typename First, typename Last, typename Pred>
41 struct recursive_find_if
45 typename result_of::next<First>::type, Last, Pred
50 template <typename First, typename Last, typename Pred>
54 result_of::equal_to<First, Last>
55 , apply_filter<First, Pred> >
61 , mpl::identity<First>
62 , recursive_find_if<First, Last, Pred>
68 typename First, typename Last,
70 struct choose_find_if;
72 template<typename First, typename Last, typename Pred>
73 struct choose_find_if<First, Last, Pred, false>
74 : main_find_if<First, Last, Pred>
77 template<typename Iter, typename Pred, int n, int unrolling>
80 template <typename Iter, typename Pred, int offset>
81 struct apply_offset_filter
83 typedef typename result_of::advance_c<Iter, offset>::type Shifted;
90 BOOST_STATIC_CONSTANT(int, value = type::value);
93 template<typename Iter, typename Pred, int n>
94 struct unrolled_find_if
96 typedef typename mpl::eval_if<
97 apply_filter<Iter, Pred>,
100 apply_offset_filter<Iter, Pred, 1>,
101 result_of::advance_c<Iter, 1>,
103 apply_offset_filter<Iter, Pred, 2>,
104 result_of::advance_c<Iter, 2>,
106 apply_offset_filter<Iter, Pred, 3>,
107 result_of::advance_c<Iter, 3>,
112 4> > > > >::type type;
115 template<typename Iter, typename Pred>
116 struct unrolled_find_if<Iter, Pred, 3>
118 typedef typename mpl::eval_if<
119 apply_filter<Iter, Pred>,
122 apply_offset_filter<Iter, Pred, 1>,
123 result_of::advance_c<Iter, 1>,
125 apply_offset_filter<Iter, Pred, 2>,
126 result_of::advance_c<Iter, 2>,
127 result_of::advance_c<Iter, 3> > > >::type type;
130 template<typename Iter, typename Pred>
131 struct unrolled_find_if<Iter, Pred, 2>
133 typedef typename mpl::eval_if<
134 apply_filter<Iter, Pred>,
137 apply_offset_filter<Iter, Pred, 1>,
138 result_of::advance_c<Iter, 1>,
139 result_of::advance_c<Iter, 2> > >::type type;
142 template<typename Iter, typename Pred>
143 struct unrolled_find_if<Iter, Pred, 1>
145 typedef typename mpl::eval_if<
146 apply_filter<Iter, Pred>,
148 result_of::advance_c<Iter, 1> >::type type;
151 template<typename Iter, typename Pred, int n, int unrolling>
154 typedef typename unrolled_find_if<
155 typename result_of::advance_c<Iter, unrolling>::type,
157 n-unrolling>::type type;
160 template<typename Iter, typename Pred>
161 struct unrolled_find_if<Iter, Pred, 0>
166 template<typename First, typename Last, typename Pred>
167 struct choose_find_if<First, Last, Pred, true>
169 typedef typename result_of::distance<First, Last>::type N;
170 typedef typename unrolled_find_if<First, Pred, N::value>::type type;
173 template <typename First, typename Last, typename Pred>
174 struct static_find_if
181 , traits::is_random_access<First>::value
185 template <typename Iterator>
186 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
188 recursive_call(Iterator const& iter, mpl::true_)
193 template <typename Iterator>
194 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
196 recursive_call(Iterator const& iter, mpl::false_)
198 return recursive_call(fusion::next(iter));
201 template <typename Iterator>
202 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
204 recursive_call(Iterator const& iter)
206 typedef result_of::equal_to<Iterator, type> found;
207 return recursive_call(iter, found());
210 template <typename Iterator>
211 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
212 static typename boost::disable_if<traits::is_random_access<Iterator>, type>::type
213 iter_call(Iterator const& iter)
215 return recursive_call(iter);
218 template <typename Iterator>
219 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
220 static typename boost::enable_if<traits::is_random_access<Iterator>, type>::type
221 iter_call(Iterator const& iter)
223 typedef typename result_of::distance<Iterator, type>::type N;
224 return fusion::advance<N>(iter);
227 template <typename Sequence>
228 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
232 return iter_call(fusion::begin(seq));
236 template <typename Sequence, typename Pred>
237 struct result_of_find_if
241 typename result_of::begin<Sequence>::type
242 , typename result_of::end<Sequence>::type
247 typedef typename filter::type type;