File indexing completed on 2025-01-18 09:38:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_COUNT_IF_HPP
0011 #define BOOST_HANA_COUNT_IF_HPP
0012
0013 #include <boost/hana/fwd/count_if.hpp>
0014
0015 #include <boost/hana/concept/foldable.hpp>
0016 #include <boost/hana/config.hpp>
0017 #include <boost/hana/core/dispatch.hpp>
0018 #include <boost/hana/detail/algorithm.hpp>
0019 #include <boost/hana/detail/fast_and.hpp>
0020 #include <boost/hana/integral_constant.hpp>
0021 #include <boost/hana/unpack.hpp>
0022
0023 #include <cstddef>
0024 #include <type_traits>
0025 #include <utility>
0026
0027
0028 namespace boost { namespace hana {
0029
0030 template <typename Xs, typename Pred>
0031 constexpr auto count_if_t::operator()(Xs&& xs, Pred&& pred) const {
0032 using S = typename hana::tag_of<Xs>::type;
0033 using CountIf = BOOST_HANA_DISPATCH_IF(count_if_impl<S>,
0034 hana::Foldable<S>::value
0035 );
0036
0037 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0038 static_assert(hana::Foldable<S>::value,
0039 "hana::count_if(xs, pred) requires 'xs' to be Foldable");
0040 #endif
0041
0042 return CountIf::apply(static_cast<Xs&&>(xs),
0043 static_cast<Pred&&>(pred));
0044 }
0045
0046
0047 namespace detail {
0048 template <typename Pred>
0049 struct count_pred {
0050 Pred pred;
0051 template <typename ...Xs, typename = typename std::enable_if<
0052 detail::fast_and<
0053 Constant<decltype((*pred)(std::declval<Xs&&>()))>::value...
0054 >::value
0055 >::type>
0056 constexpr auto operator()(Xs&& ...xs) const {
0057 constexpr bool results[] = {false,
0058 static_cast<bool>(hana::value<decltype((*pred)(static_cast<Xs&&>(xs)))>())...
0059 };
0060 constexpr std::size_t total = detail::count(
0061 results, results + sizeof(results), true
0062 );
0063 return hana::size_c<total>;
0064 }
0065
0066 template <typename ...Xs, typename = void, typename = typename std::enable_if<
0067 !detail::fast_and<
0068 Constant<decltype((*pred)(std::declval<Xs&&>()))>::value...
0069 >::value
0070 >::type>
0071 constexpr auto operator()(Xs&& ...xs) const {
0072 std::size_t total = 0;
0073 using Swallow = std::size_t[];
0074 (void)Swallow{0, ((*pred)(static_cast<Xs&&>(xs)) ? ++total : 0)...};
0075 return total;
0076 }
0077 };
0078 }
0079
0080 template <typename T, bool condition>
0081 struct count_if_impl<T, when<condition>> : default_ {
0082 template <typename Xs, typename Pred>
0083 static constexpr decltype(auto) apply(Xs&& xs, Pred&& pred) {
0084
0085 return hana::unpack(static_cast<Xs&&>(xs),
0086 detail::count_pred<decltype(&pred)>{&pred}
0087 );
0088 }
0089 };
0090 }}
0091
0092 #endif