]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fusion/include/boost/fusion/algorithm/query/detail/count_if.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / fusion / include / boost / fusion / algorithm / query / detail / count_if.hpp
1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2007 Dan Marsden
4
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
10
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>
21
22 namespace boost { namespace fusion {
23 struct random_access_traversal_tag;
24 namespace detail
25 {
26 template <typename First, typename Last, typename F>
27 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
28 inline int
29 linear_count_if(First const&, Last const&, F const&, mpl::true_)
30 {
31 return 0;
32 }
33
34 template <typename First, typename Last, typename F>
35 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
36 inline int
37 linear_count_if(First const& first, Last const& last, F& f, mpl::false_)
38 {
39 int n =
40 detail::linear_count_if(
41 fusion::next(first)
42 , last
43 , f
44 , result_of::equal_to<typename result_of::next<First>::type, Last>());
45 if (f(*first))
46 ++n;
47 return n;
48 }
49
50 template <typename Sequence, typename F, typename Tag>
51 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
52 inline int
53 count_if(Sequence const& seq, F f, Tag)
54 {
55 return detail::linear_count_if(
56 fusion::begin(seq)
57 , fusion::end(seq)
58 , f
59 , result_of::equal_to<
60 typename result_of::begin<Sequence>::type
61 , typename result_of::end<Sequence>::type>());
62 }
63
64 template<int n>
65 struct unrolled_count_if
66 {
67 template<typename I0, typename F>
68 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
69 static int call(I0 const& i0, F f)
70 {
71 int ct = unrolled_count_if<n-4>::
72 call(fusion::advance_c<4>(i0), f);
73 if(f(*i0))
74 ++ct;
75
76 typedef typename result_of::next<I0>::type I1;
77 I1 i1(fusion::next(i0));
78 if(f(*i1))
79 ++ct;
80
81 typedef typename result_of::next<I1>::type I2;
82 I2 i2(fusion::next(i1));
83 if(f(*i2))
84 ++ct;
85
86 typedef typename result_of::next<I2>::type I3;
87 I3 i3(fusion::next(i2));
88 if(f(*i3))
89 ++ct;
90
91 return ct;
92 }
93 };
94
95 template<>
96 struct unrolled_count_if<3>
97 {
98 template<typename I0, typename F>
99 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
100 static int call(I0 const& i0, F f)
101 {
102 int ct = 0;
103 if(f(*i0))
104 ++ct;
105
106 typedef typename result_of::next<I0>::type I1;
107 I1 i1(fusion::next(i0));
108 if(f(*i1))
109 ++ct;
110
111 typedef typename result_of::next<I1>::type I2;
112 I2 i2(fusion::next(i1));
113 if(f(*i2))
114 ++ct;
115
116 return ct;
117 }
118 };
119
120 template<>
121 struct unrolled_count_if<2>
122 {
123 template<typename I0, typename F>
124 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
125 static int call(I0 const& i0, F f)
126 {
127 int ct = 0;
128
129 if(f(*i0))
130 ++ct;
131
132 typedef typename result_of::next<I0>::type I1;
133 I1 i1(fusion::next(i0));
134 if(f(*i1))
135 ++ct;
136
137 return ct;
138 }
139 };
140
141 template<>
142 struct unrolled_count_if<1>
143 {
144 template<typename I0, typename F>
145 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
146 static int call(I0 const& i0, F f)
147 {
148 int ct = 0;
149 if(f(*i0))
150 ++ct;
151 return ct;
152 }
153 };
154
155
156 template<>
157 struct unrolled_count_if<0>
158 {
159 template<typename I0, typename F>
160 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
161 static int call(I0 const&, F)
162 {
163 return 0;
164 }
165 };
166
167 template <typename Sequence, typename F>
168 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
169 inline int
170 count_if(Sequence const& seq, F f, random_access_traversal_tag)
171 {
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);
176 }
177 }}}
178
179 #endif
180