File indexing completed on 2025-12-15 09:52:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_HANA_DETAIL_HASH_TABLE_HPP
0012 #define BOOST_HANA_DETAIL_HASH_TABLE_HPP
0013
0014 #include <boost/hana/equal.hpp>
0015 #include <boost/hana/ext/std/integer_sequence.hpp>
0016 #include <boost/hana/ext/std/integral_constant.hpp>
0017 #include <boost/hana/find_if.hpp>
0018 #include <boost/hana/fold_left.hpp>
0019 #include <boost/hana/hash.hpp>
0020 #include <boost/hana/optional.hpp>
0021 #include <boost/hana/range.hpp>
0022 #include <boost/hana/type.hpp>
0023 #include <boost/hana/value.hpp>
0024
0025 #include <cstddef>
0026 #include <type_traits>
0027 #include <utility>
0028
0029
0030 namespace boost { namespace hana { namespace detail {
0031 template <typename Hash, std::size_t ...i>
0032 struct bucket { };
0033
0034 template <typename ...Buckets>
0035 struct hash_table
0036 : Buckets...
0037 { };
0038
0039
0040
0041
0042 template <typename Hash, std::size_t ...i>
0043 std::index_sequence<i...> find_indices_impl(bucket<Hash, i...> const&);
0044
0045 template <typename Hash>
0046 std::index_sequence<> find_indices_impl(...);
0047
0048 template <typename Map, typename Key>
0049 struct find_indices {
0050 using Hash = typename decltype(hana::hash(std::declval<Key>()))::type;
0051 using type = decltype(detail::find_indices_impl<Hash>(std::declval<Map>()));
0052 };
0053
0054
0055
0056
0057
0058
0059 template <template <std::size_t> class KeyAtIndex, typename Key>
0060 struct find_pred {
0061 template <typename Index>
0062 auto operator()(Index const&) const -> decltype(
0063 hana::equal(std::declval<KeyAtIndex<Index::value>>(),
0064 std::declval<Key>())
0065 );
0066 };
0067
0068 template <typename Indices, typename Key, template <std::size_t> class KeyAtIndex>
0069 struct find_index_impl {
0070 using type = decltype(hana::find_if(Indices{}, find_pred<KeyAtIndex, Key>{}));
0071 };
0072
0073
0074
0075
0076
0077 template <std::size_t i, typename Key, template <std::size_t> class KeyAtIndex>
0078 struct find_index_impl<std::index_sequence<i>, Key, KeyAtIndex> {
0079 using Equal = decltype(
0080 hana::equal(std::declval<KeyAtIndex<i>>(),
0081 std::declval<Key>())
0082 );
0083 using type = typename std::conditional<Equal::value,
0084 hana::optional<std::integral_constant<std::size_t, i>>,
0085 hana::optional<>
0086 >::type;
0087 };
0088
0089 template <typename Map, typename Key, template <std::size_t> class KeyAtIndex>
0090 struct find_index {
0091 using Indices = typename find_indices<Map, Key>::type;
0092 using type = typename find_index_impl<Indices, Key, KeyAtIndex>::type;
0093 };
0094
0095
0096
0097
0098 template <typename Bucket, typename Hash, std::size_t Index>
0099 struct update_bucket {
0100 using type = Bucket;
0101 };
0102
0103 template <std::size_t ...i, typename Hash, std::size_t Index>
0104 struct update_bucket<bucket<Hash, i...>, Hash, Index> {
0105 using type = bucket<Hash, i..., Index>;
0106 };
0107
0108 template <typename Map, typename Key, std::size_t Index, bool =
0109 (find_indices<Map, Key>::type::size() > 0)
0110 >
0111 struct bucket_insert;
0112
0113 template <typename ...Buckets, typename Key, std::size_t Index>
0114 struct bucket_insert<hash_table<Buckets...>, Key, Index, true> {
0115
0116 using Hash = typename decltype(hana::hash(std::declval<Key>()))::type;
0117 using type = hash_table<typename update_bucket<Buckets, Hash, Index>::type...>;
0118 };
0119
0120 template <typename ...Buckets, typename Key, std::size_t Index>
0121 struct bucket_insert<hash_table<Buckets...>, Key, Index, false> {
0122
0123 using Hash = typename decltype(hana::hash(std::declval<Key>()))::type;
0124 using type = hash_table<Buckets..., bucket<Hash, Index>>;
0125 };
0126
0127
0128
0129
0130
0131
0132
0133 template <template <std::size_t> class KeyAtIndex, std::size_t N,
0134 typename Indices = std::make_index_sequence<N>>
0135 struct make_hash_table;
0136
0137 template <template <std::size_t> class KeyAtIndex, std::size_t N, std::size_t ...i>
0138 struct make_hash_table<KeyAtIndex, N, std::index_sequence<i...>> {
0139 using type = hash_table<
0140 bucket<typename decltype(hana::hash(std::declval<KeyAtIndex<i>>()))::type, i>...
0141 >;
0142 };
0143 } }}
0144
0145 #endif