Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*!
0002 @file
0003 Defines `boost::hana::any_of`.
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_ANY_OF_HPP
0011 #define BOOST_HANA_ANY_OF_HPP
0012 
0013 #include <boost/hana/fwd/any_of.hpp>
0014 
0015 #include <boost/hana/accessors.hpp>
0016 #include <boost/hana/at.hpp>
0017 #include <boost/hana/bool.hpp>
0018 #include <boost/hana/concept/searchable.hpp>
0019 #include <boost/hana/concept/sequence.hpp>
0020 #include <boost/hana/concept/struct.hpp>
0021 #include <boost/hana/config.hpp>
0022 #include <boost/hana/core/dispatch.hpp>
0023 #include <boost/hana/drop_front.hpp>
0024 #include <boost/hana/first.hpp>
0025 #include <boost/hana/front.hpp>
0026 #include <boost/hana/functional/compose.hpp>
0027 #include <boost/hana/if.hpp>
0028 #include <boost/hana/is_empty.hpp>
0029 #include <boost/hana/length.hpp>
0030 
0031 #include <cstddef>
0032 
0033 
0034 namespace boost { namespace hana {
0035     //! @cond
0036     template <typename Xs, typename Pred>
0037     constexpr auto any_of_t::operator()(Xs&& xs, Pred&& pred) const {
0038         using S = typename hana::tag_of<Xs>::type;
0039         using AnyOf = BOOST_HANA_DISPATCH_IF(any_of_impl<S>,
0040             hana::Searchable<S>::value
0041         );
0042 
0043     #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0044         static_assert(hana::Searchable<S>::value,
0045         "hana::any_of(xs, pred) requires 'xs' to be a Searchable");
0046     #endif
0047 
0048         return AnyOf::apply(static_cast<Xs&&>(xs), static_cast<Pred&&>(pred));
0049     }
0050     //! @endcond
0051 
0052     template <typename S, bool condition>
0053     struct any_of_impl<S, when<condition>> : default_ {
0054         template <typename ...Args>
0055         static constexpr auto apply(Args&& ...) = delete;
0056     };
0057 
0058     template <typename S>
0059     struct any_of_impl<S, when<Sequence<S>::value>> {
0060         //! @cond
0061         template <std::size_t k, std::size_t Len>
0062         struct any_of_helper {
0063             template <typename Xs, typename Pred>
0064             static constexpr auto apply(bool prev_cond, Xs&& xs, Pred&& pred) {
0065                 return prev_cond ? hana::true_c
0066                     : any_of_impl::any_of_helper<k + 1, Len>::apply(
0067                         hana::if_(pred(hana::at_c<k>(xs)), hana::true_c, hana::false_c),
0068                         static_cast<Xs&&>(xs),
0069                         static_cast<Pred&&>(pred)
0070                     );
0071             }
0072 
0073             template <typename Xs, typename Pred>
0074             static constexpr auto apply(hana::true_, Xs&&, Pred&&)
0075             { return hana::true_c; }
0076 
0077             template <typename Xs, typename Pred>
0078             static constexpr auto apply(hana::false_, Xs&& xs, Pred&& pred) {
0079                 auto cond = hana::if_(pred(hana::at_c<k>(xs)), hana::true_c,
0080                                                                hana::false_c);
0081                 return any_of_impl::any_of_helper<k + 1, Len>::apply(cond,
0082                                         static_cast<Xs&&>(xs),
0083                                         static_cast<Pred&&>(pred));
0084             }
0085         };
0086 
0087         template <std::size_t Len>
0088         struct any_of_helper<Len, Len> {
0089             template <typename Cond, typename Xs, typename Pred>
0090             static constexpr auto apply(Cond cond, Xs&&, Pred&&)
0091             { return cond; }
0092         };
0093 
0094         template <typename Xs, typename Pred>
0095         static constexpr auto apply(Xs&& xs, Pred&& pred) {
0096             constexpr std::size_t len = decltype(hana::length(xs))::value;
0097             return any_of_impl::any_of_helper<0, len>::apply(hana::false_c,
0098                                             static_cast<Xs&&>(xs),
0099                                             static_cast<Pred&&>(pred));
0100         }
0101         //! @endcond
0102     };
0103 
0104     template <typename It>
0105     struct any_of_impl<It, when<
0106         hana::Iterable<It>::value &&
0107         !Sequence<It>::value
0108     >> {
0109         template <typename Xs, typename Pred>
0110         static constexpr auto lazy_any_of_helper(hana::false_, bool prev_cond, Xs&& xs, Pred&& pred) {
0111             decltype(auto) tail = hana::drop_front(static_cast<Xs&&>(xs));
0112             constexpr bool done = decltype(hana::is_empty(tail))::value;
0113             return prev_cond ? hana::true_c
0114                 : lazy_any_of_helper(hana::bool_<done>{},
0115                     hana::if_(pred(hana::front(xs)), hana::true_{}, hana::false_{}),
0116                     static_cast<decltype(tail)&&>(tail),
0117                     static_cast<Pred&&>(pred)
0118                 );
0119         }
0120 
0121         template <typename Xs, typename Pred>
0122         static constexpr auto lazy_any_of_helper(hana::false_, hana::true_, Xs&&, Pred&&)
0123         { return hana::true_c; }
0124 
0125         template <typename Xs, typename Pred>
0126         static constexpr auto lazy_any_of_helper(hana::false_, hana::false_, Xs&& xs, Pred&& pred) {
0127             constexpr bool done = decltype(hana::is_empty(hana::drop_front(xs)))::value;
0128             return lazy_any_of_helper(hana::bool_c<done>,
0129                 hana::if_(pred(hana::front(xs)), hana::true_c, hana::false_c),
0130                 hana::drop_front(static_cast<Xs&&>(xs)),
0131                 static_cast<Pred&&>(pred)
0132             );
0133         }
0134 
0135         template <typename Cond, typename Xs, typename Pred>
0136         static constexpr auto lazy_any_of_helper(hana::true_, Cond cond, Xs&&, Pred&&)
0137         { return cond; }
0138 
0139         template <typename Xs, typename Pred>
0140         static constexpr auto apply(Xs&& xs, Pred&& pred) {
0141             constexpr bool done = decltype(hana::is_empty(xs))::value;
0142             return lazy_any_of_helper(hana::bool_c<done>, hana::false_c,
0143                                       static_cast<Xs&&>(xs),
0144                                       static_cast<Pred&&>(pred));
0145         }
0146     };
0147 
0148     template <typename T, std::size_t N>
0149     struct any_of_impl<T[N]> {
0150         template <typename Xs, typename Pred>
0151         static constexpr bool any_of_helper(bool cond, Xs&& xs, Pred&& pred) {
0152             if (cond) return true;
0153             for (std::size_t i = 1; i < N; ++i)
0154                 if (pred(static_cast<Xs&&>(xs)[i]))
0155                     return true;
0156             return false;
0157         }
0158 
0159         // Since an array contains homogeneous data, if the predicate returns
0160         // a compile-time logical at any index, it must do so at every index
0161         // (because the type of the elements won't change)! In this case, we
0162         // then only need to evaluate the predicate on the first element.
0163         template <typename Xs, typename Pred>
0164         static constexpr auto
0165         any_of_helper(hana::true_, Xs&& /*xs*/, Pred&&)
0166         { return hana::true_c; }
0167 
0168         template <typename Xs, typename Pred>
0169         static constexpr auto
0170         any_of_helper(hana::false_, Xs&&, Pred&&)
0171         { return hana::false_c; }
0172 
0173         template <typename Xs, typename Pred>
0174         static constexpr auto apply(Xs&& xs, Pred&& pred) {
0175             auto cond = hana::if_(pred(static_cast<Xs&&>(xs)[0]), hana::true_c,
0176                                                                   hana::false_c);
0177             return any_of_helper(cond, static_cast<Xs&&>(xs),
0178                                        static_cast<Pred&&>(pred));
0179         }
0180     };
0181 
0182     template <typename S>
0183     struct any_of_impl<S, when<hana::Struct<S>::value>> {
0184         template <typename X, typename Pred>
0185         static constexpr decltype(auto) apply(X const&, Pred&& pred) {
0186             return hana::any_of(hana::accessors<S>(),
0187                     hana::compose(static_cast<Pred&&>(pred), hana::first));
0188         }
0189     };
0190 }} // end namespace boost::hana
0191 
0192 #endif // !BOOST_HANA_ANY_OF_HPP