File indexing completed on 2025-01-18 09:38:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_HANA_FIND_IF_HPP
0012 #define BOOST_HANA_FIND_IF_HPP
0013
0014 #include <boost/hana/fwd/find_if.hpp>
0015
0016 #include <boost/hana/accessors.hpp>
0017 #include <boost/hana/at.hpp>
0018 #include <boost/hana/bool.hpp>
0019 #include <boost/hana/concept/iterable.hpp>
0020 #include <boost/hana/concept/searchable.hpp>
0021 #include <boost/hana/concept/struct.hpp>
0022 #include <boost/hana/config.hpp>
0023 #include <boost/hana/core/dispatch.hpp>
0024 #include <boost/hana/first.hpp>
0025 #include <boost/hana/functional/compose.hpp>
0026 #include <boost/hana/index_if.hpp>
0027 #include <boost/hana/second.hpp>
0028 #include <boost/hana/transform.hpp>
0029
0030 #include <cstddef>
0031 #include <utility>
0032
0033
0034 namespace boost { namespace hana {
0035
0036 template <typename Xs, typename Pred>
0037 constexpr auto find_if_t::operator()(Xs&& xs, Pred&& pred) const {
0038 using S = typename hana::tag_of<Xs>::type;
0039 using FindIf = BOOST_HANA_DISPATCH_IF(find_if_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::find_if(xs, pred) requires 'xs' to be a Searchable");
0046 #endif
0047
0048 return FindIf::apply(static_cast<Xs&&>(xs), static_cast<Pred&&>(pred));
0049 }
0050
0051
0052 template <typename S, bool condition>
0053 struct find_if_impl<S, when<condition>> : default_ {
0054 template <typename ...Args>
0055 static constexpr auto apply(Args&& ...) = delete;
0056 };
0057
0058 namespace detail {
0059 template <typename Xs>
0060 struct partial_at {
0061 Xs const& xs;
0062
0063 template <typename I>
0064 constexpr decltype(auto) operator()(I i) const {
0065 return hana::at(xs, i);
0066 }
0067 };
0068 }
0069
0070 template <typename Tag>
0071 struct find_if_impl<Tag, when<Iterable<Tag>::value>> {
0072 template <typename Xs, typename Pred>
0073 static constexpr auto apply(Xs&& xs, Pred&& pred) {
0074 using Result = decltype(hana::index_if(
0075 static_cast<Xs&&>(xs), static_cast<Pred&&>(pred)));
0076
0077 return hana::transform(Result{},
0078 detail::partial_at<std::decay_t<Xs>>{static_cast<Xs&&>(xs)});
0079 }
0080 };
0081
0082 template <typename T, std::size_t N>
0083 struct find_if_impl<T[N]> {
0084 template <typename Xs>
0085 static constexpr auto find_if_helper(Xs&&, hana::false_)
0086 { return hana::nothing; }
0087
0088 template <typename Xs>
0089 static constexpr auto find_if_helper(Xs&& xs, hana::true_)
0090 { return hana::just(static_cast<Xs&&>(xs)[0]); }
0091
0092 template <typename Xs, typename Pred>
0093 static constexpr auto apply(Xs&& xs, Pred&& pred) {
0094 return find_if_helper(static_cast<Xs&&>(xs),
0095 hana::bool_c<decltype(
0096 static_cast<Pred&&>(pred)(static_cast<Xs&&>(xs)[0])
0097 )::value>
0098 );
0099 }
0100 };
0101
0102 namespace struct_detail {
0103 template <typename X>
0104 struct get_member {
0105 X x;
0106 template <typename Member>
0107 constexpr decltype(auto) operator()(Member&& member) && {
0108 return hana::second(static_cast<Member&&>(member))(
0109 static_cast<X&&>(x)
0110 );
0111 }
0112 };
0113 }
0114
0115 template <typename S>
0116 struct find_if_impl<S, when<hana::Struct<S>::value>> {
0117 template <typename X, typename Pred>
0118 static constexpr decltype(auto) apply(X&& x, Pred&& pred) {
0119 return hana::transform(
0120 hana::find_if(hana::accessors<S>(),
0121 hana::compose(static_cast<Pred&&>(pred), hana::first)
0122 ),
0123 struct_detail::get_member<X>{static_cast<X&&>(x)}
0124 );
0125 }
0126 };
0127 }}
0128
0129 #endif