Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:02

0001 /*!
0002 @file
0003 Defines `boost::hana::count_if`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
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     //! @cond
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     //! @endcond
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, // <-- avoid empty array
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             // We use a pointer instead of a reference to avoid a Clang ICE.
0085             return hana::unpack(static_cast<Xs&&>(xs),
0086                 detail::count_pred<decltype(&pred)>{&pred}
0087             );
0088         }
0089     };
0090 }} // end namespace boost::hana
0091 
0092 #endif // !BOOST_HANA_COUNT_IF_HPP