1/*!
2@file
3Defines `boost::hana::at_key`.
4
5Copyright Louis Dionne 2013-2022
6Copyright Jason Rice 2017
7Distributed 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_AT_KEY_HPP
12#define BOOST_HANA_AT_KEY_HPP
13
14#include <boost/hana/fwd/at_key.hpp>
15
16#include <boost/hana/accessors.hpp>
17#include <boost/hana/at.hpp>
18#include <boost/hana/concept/searchable.hpp>
19#include <boost/hana/concept/struct.hpp>
20#include <boost/hana/config.hpp>
21#include <boost/hana/core/dispatch.hpp>
22#include <boost/hana/detail/decay.hpp>
23#include <boost/hana/equal.hpp>
24#include <boost/hana/find.hpp>
25#include <boost/hana/find_if.hpp>
26#include <boost/hana/first.hpp>
27#include <boost/hana/functional/on.hpp>
28#include <boost/hana/index_if.hpp>
29#include <boost/hana/length.hpp>
30#include <boost/hana/optional.hpp>
31#include <boost/hana/second.hpp>
32
33#include <cstddef>
34#include <utility>
35
36
37namespace boost { namespace hana {
38 //! @cond
39 template <typename Xs, typename Key>
40 constexpr decltype(auto) at_key_t::operator()(Xs&& xs, Key const& key) const {
41 using S = typename hana::tag_of<Xs>::type;
42 using AtKey = BOOST_HANA_DISPATCH_IF(at_key_impl<S>,
43 hana::Searchable<S>::value
44 );
45
46 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
47 static_assert(hana::Searchable<S>::value,
48 "hana::at_key(xs, key) requires 'xs' to be Searchable");
49 #endif
50
51 return AtKey::apply(static_cast<Xs&&>(xs), key);
52 }
53 //! @endcond
54
55 template <typename S, bool condition>
56 struct at_key_impl<S, when<condition>> : default_ {
57 template <typename Xs, typename Key>
58 static constexpr auto apply(Xs&& xs, Key const& key) {
59 return hana::find(static_cast<Xs&&>(xs), key).value();
60 }
61 };
62
63 namespace at_key_detail {
64 template <typename T>
65 struct equal_to {
66 T const& t;
67 template <typename U>
68 constexpr auto operator()(U const& u) const {
69 return hana::equal(t, u);
70 }
71 };
72 }
73
74 template <typename S>
75 struct at_key_impl<S, when<hana::Sequence<S>::value>> {
76 template <typename Xs, typename Key>
77 static constexpr decltype(auto) apply(Xs&& xs, Key const& key) {
78 using Result = decltype(hana::index_if(
79 static_cast<Xs&&>(xs), at_key_detail::equal_to<Key>{key}));
80
81 return hana::at(static_cast<Xs&&>(xs), Result{}.value());
82 }
83 };
84
85 template <typename S>
86 struct at_key_impl<S, when<hana::Struct<S>::value>> {
87 template <typename X, typename Key>
88 static constexpr decltype(auto) apply(X&& x, Key const& key) {
89 auto accessor = hana::second(*hana::find_if(hana::accessors<S>(),
90 hana::equal.to(key) ^hana::on^ hana::first
91 ));
92 return accessor(static_cast<X&&>(x));
93 }
94 };
95}} // end namespace boost::hana
96
97#endif // !BOOST_HANA_AT_KEY_HPP
98

source code of boost/libs/hana/include/boost/hana/at_key.hpp