1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2007 Dan Marsden
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(BOOST_FUSION_COUNT_IF_09162005_0141)
9 #define BOOST_FUSION_COUNT_IF_09162005_0141
11 #include <boost/fusion/support/config.hpp>
12 #include <boost/mpl/bool.hpp>
13 #include <boost/fusion/sequence/intrinsic/begin.hpp>
14 #include <boost/fusion/sequence/intrinsic/end.hpp>
15 #include <boost/fusion/iterator/equal_to.hpp>
16 #include <boost/fusion/iterator/next.hpp>
17 #include <boost/fusion/iterator/deref.hpp>
18 #include <boost/fusion/iterator/equal_to.hpp>
19 #include <boost/fusion/iterator/distance.hpp>
20 #include <boost/fusion/iterator/advance.hpp>
22 namespace boost { namespace fusion {
23 struct random_access_traversal_tag;
26 template <typename First, typename Last, typename F>
27 BOOST_FUSION_GPU_ENABLED
29 linear_count_if(First const&, Last const&, F const&, mpl::true_)
34 template <typename First, typename Last, typename F>
35 BOOST_FUSION_GPU_ENABLED
37 linear_count_if(First const& first, Last const& last, F& f, mpl::false_)
40 detail::linear_count_if(
44 , result_of::equal_to<typename result_of::next<First>::type, Last>());
50 template <typename Sequence, typename F, typename Tag>
51 BOOST_FUSION_GPU_ENABLED
53 count_if(Sequence const& seq, F f, Tag)
55 return detail::linear_count_if(
59 , result_of::equal_to<
60 typename result_of::begin<Sequence>::type
61 , typename result_of::end<Sequence>::type>());
65 struct unrolled_count_if
67 template<typename I0, typename F>
68 BOOST_FUSION_GPU_ENABLED
69 static int call(I0 const& i0, F f)
71 int ct = unrolled_count_if<n-4>::
72 call(fusion::advance_c<4>(i0), f);
76 typedef typename result_of::next<I0>::type I1;
77 I1 i1(fusion::next(i0));
81 typedef typename result_of::next<I1>::type I2;
82 I2 i2(fusion::next(i1));
86 typedef typename result_of::next<I2>::type I3;
87 I3 i3(fusion::next(i2));
96 struct unrolled_count_if<3>
98 template<typename I0, typename F>
99 BOOST_FUSION_GPU_ENABLED
100 static int call(I0 const& i0, F f)
106 typedef typename result_of::next<I0>::type I1;
107 I1 i1(fusion::next(i0));
111 typedef typename result_of::next<I1>::type I2;
112 I2 i2(fusion::next(i1));
121 struct unrolled_count_if<2>
123 template<typename I0, typename F>
124 BOOST_FUSION_GPU_ENABLED
125 static int call(I0 const& i0, F f)
132 typedef typename result_of::next<I0>::type I1;
133 I1 i1(fusion::next(i0));
142 struct unrolled_count_if<1>
144 template<typename I0, typename F>
145 BOOST_FUSION_GPU_ENABLED
146 static int call(I0 const& i0, F f)
157 struct unrolled_count_if<0>
159 template<typename I0, typename F>
160 BOOST_FUSION_GPU_ENABLED
161 static int call(I0 const&, F)
167 template <typename Sequence, typename F>
168 BOOST_FUSION_GPU_ENABLED
170 count_if(Sequence const& seq, F f, random_access_traversal_tag)
172 typedef typename result_of::begin<Sequence>::type begin;
173 typedef typename result_of::end<Sequence>::type end;
174 return detail::unrolled_count_if<result_of::distance<begin, end>::type::value>::
175 call(fusion::begin(seq), f);