]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/hana/find_if.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / hana / find_if.hpp
1 /*!
2 @file
3 Defines `boost::hana::find_if`.
4
5 @copyright Louis Dionne 2013-2017
6 @copyright Jason Rice 2017
7 Distributed under the Boost Software License, Version 1.0.
8 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
9 */
10
11 #ifndef BOOST_HANA_FIND_IF_HPP
12 #define BOOST_HANA_FIND_IF_HPP
13
14 #include <boost/hana/fwd/find_if.hpp>
15
16 #include <boost/hana/accessors.hpp>
17 #include <boost/hana/at.hpp>
18 #include <boost/hana/bool.hpp>
19 #include <boost/hana/concept/iterable.hpp>
20 #include <boost/hana/concept/searchable.hpp>
21 #include <boost/hana/concept/struct.hpp>
22 #include <boost/hana/config.hpp>
23 #include <boost/hana/core/dispatch.hpp>
24 #include <boost/hana/first.hpp>
25 #include <boost/hana/functional/compose.hpp>
26 #include <boost/hana/index_if.hpp>
27 #include <boost/hana/second.hpp>
28 #include <boost/hana/transform.hpp>
29
30 #include <cstddef>
31 #include <utility>
32
33
34 BOOST_HANA_NAMESPACE_BEGIN
35 //! @cond
36 template <typename Xs, typename Pred>
37 constexpr auto find_if_t::operator()(Xs&& xs, Pred&& pred) const {
38 using S = typename hana::tag_of<Xs>::type;
39 using FindIf = BOOST_HANA_DISPATCH_IF(find_if_impl<S>,
40 hana::Searchable<S>::value
41 );
42
43 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
44 static_assert(hana::Searchable<S>::value,
45 "hana::find_if(xs, pred) requires 'xs' to be a Searchable");
46 #endif
47
48 return FindIf::apply(static_cast<Xs&&>(xs), static_cast<Pred&&>(pred));
49 }
50 //! @endcond
51
52 template <typename S, bool condition>
53 struct find_if_impl<S, when<condition>> : default_ {
54 template <typename ...Args>
55 static constexpr auto apply(Args&& ...) = delete;
56 };
57
58 namespace detail {
59 template <typename Xs>
60 struct partial_at {
61 Xs const& xs;
62
63 template <typename I>
64 constexpr decltype(auto) operator()(I i) const {
65 return hana::at(xs, i);
66 }
67 };
68 }
69
70 template <typename Tag>
71 struct find_if_impl<Tag, when<Iterable<Tag>::value>> {
72 template <typename Xs, typename Pred>
73 static constexpr auto apply(Xs&& xs, Pred&& pred) {
74 using Result = decltype(hana::index_if(
75 static_cast<Xs&&>(xs), static_cast<Pred&&>(pred)));
76
77 return hana::transform(Result{},
78 detail::partial_at<std::decay_t<Xs>>{static_cast<Xs&&>(xs)});
79 }
80 };
81
82 template <typename T, std::size_t N>
83 struct find_if_impl<T[N]> {
84 template <typename Xs>
85 static constexpr auto find_if_helper(Xs&&, hana::false_)
86 { return hana::nothing; }
87
88 template <typename Xs>
89 static constexpr auto find_if_helper(Xs&& xs, hana::true_)
90 { return hana::just(static_cast<Xs&&>(xs)[0]); }
91
92 template <typename Xs, typename Pred>
93 static constexpr auto apply(Xs&& xs, Pred&& pred) {
94 return find_if_helper(static_cast<Xs&&>(xs),
95 hana::bool_c<decltype(
96 static_cast<Pred&&>(pred)(static_cast<Xs&&>(xs)[0])
97 )::value>
98 );
99 }
100 };
101
102 namespace struct_detail {
103 template <typename X>
104 struct get_member {
105 X x;
106 template <typename Member>
107 constexpr decltype(auto) operator()(Member&& member) && {
108 return hana::second(static_cast<Member&&>(member))(
109 static_cast<X&&>(x)
110 );
111 }
112 };
113 }
114
115 template <typename S>
116 struct find_if_impl<S, when<hana::Struct<S>::value>> {
117 template <typename X, typename Pred>
118 static constexpr decltype(auto) apply(X&& x, Pred&& pred) {
119 return hana::transform(
120 hana::find_if(hana::accessors<S>(),
121 hana::compose(static_cast<Pred&&>(pred), hana::first)
122 ),
123 struct_detail::get_member<X>{static_cast<X&&>(x)}
124 );
125 }
126 };
127 BOOST_HANA_NAMESPACE_END
128
129 #endif // !BOOST_HANA_FIND_IF_HPP