File indexing completed on 2025-01-30 09:43:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_HANA_AT_KEY_HPP
0012 #define BOOST_HANA_AT_KEY_HPP
0013
0014 #include <boost/hana/fwd/at_key.hpp>
0015
0016 #include <boost/hana/accessors.hpp>
0017 #include <boost/hana/at.hpp>
0018 #include <boost/hana/concept/searchable.hpp>
0019 #include <boost/hana/concept/struct.hpp>
0020 #include <boost/hana/config.hpp>
0021 #include <boost/hana/core/dispatch.hpp>
0022 #include <boost/hana/detail/decay.hpp>
0023 #include <boost/hana/equal.hpp>
0024 #include <boost/hana/find.hpp>
0025 #include <boost/hana/find_if.hpp>
0026 #include <boost/hana/first.hpp>
0027 #include <boost/hana/functional/on.hpp>
0028 #include <boost/hana/index_if.hpp>
0029 #include <boost/hana/length.hpp>
0030 #include <boost/hana/optional.hpp>
0031 #include <boost/hana/second.hpp>
0032
0033 #include <cstddef>
0034 #include <utility>
0035
0036
0037 namespace boost { namespace hana {
0038
0039 template <typename Xs, typename Key>
0040 constexpr decltype(auto) at_key_t::operator()(Xs&& xs, Key const& key) const {
0041 using S = typename hana::tag_of<Xs>::type;
0042 using AtKey = BOOST_HANA_DISPATCH_IF(at_key_impl<S>,
0043 hana::Searchable<S>::value
0044 );
0045
0046 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0047 static_assert(hana::Searchable<S>::value,
0048 "hana::at_key(xs, key) requires 'xs' to be Searchable");
0049 #endif
0050
0051 return AtKey::apply(static_cast<Xs&&>(xs), key);
0052 }
0053
0054
0055 template <typename S, bool condition>
0056 struct at_key_impl<S, when<condition>> : default_ {
0057 template <typename Xs, typename Key>
0058 static constexpr auto apply(Xs&& xs, Key const& key) {
0059 return hana::find(static_cast<Xs&&>(xs), key).value();
0060 }
0061 };
0062
0063 namespace at_key_detail {
0064 template <typename T>
0065 struct equal_to {
0066 T const& t;
0067 template <typename U>
0068 constexpr auto operator()(U const& u) const {
0069 return hana::equal(t, u);
0070 }
0071 };
0072 }
0073
0074 template <typename S>
0075 struct at_key_impl<S, when<hana::Sequence<S>::value>> {
0076 template <typename Xs, typename Key>
0077 static constexpr decltype(auto) apply(Xs&& xs, Key const& key) {
0078 using Result = decltype(hana::index_if(
0079 static_cast<Xs&&>(xs), at_key_detail::equal_to<Key>{key}));
0080
0081 return hana::at(static_cast<Xs&&>(xs), Result{}.value());
0082 }
0083 };
0084
0085 template <typename S>
0086 struct at_key_impl<S, when<hana::Struct<S>::value>> {
0087 template <typename X, typename Key>
0088 static constexpr decltype(auto) apply(X&& x, Key const& key) {
0089 auto accessor = hana::second(*hana::find_if(hana::accessors<S>(),
0090 hana::equal.to(key) ^hana::on^ hana::first
0091 ));
0092 return accessor(static_cast<X&&>(x));
0093 }
0094 };
0095 }}
0096
0097 #endif