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::find_if`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Copyright Jason Rice 2017
0007 Distributed under the Boost Software License, Version 1.0.
0008 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
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     //! @cond
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     //! @endcond
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 }} // end namespace boost::hana
0128 
0129 #endif // !BOOST_HANA_FIND_IF_HPP