File indexing completed on 2025-01-18 09:38:01
0001
0002
0003
0004
0005
0006
0007
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
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
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
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
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
0160
0161
0162
0163 template <typename Xs, typename Pred>
0164 static constexpr auto
0165 any_of_helper(hana::true_, 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 }}
0191
0192 #endif