File indexing completed on 2025-07-30 08:46:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef __TBB_detail__hash_compare_H
0018 #define __TBB_detail__hash_compare_H
0019
0020 #include <functional>
0021
0022 #include "_containers_helpers.h"
0023
0024 namespace tbb {
0025 namespace detail {
0026 namespace d1 {
0027
0028 template <typename Key, typename Hash, typename KeyEqual>
0029 class hash_compare {
0030 using is_transparent_hash = has_transparent_key_equal<Key, Hash, KeyEqual>;
0031 public:
0032 using hasher = Hash;
0033 using key_equal = typename is_transparent_hash::type;
0034
0035 hash_compare() = default;
0036 hash_compare( hasher hash, key_equal equal ) : my_hasher(hash), my_equal(equal) {}
0037
0038 std::size_t operator()( const Key& key ) const {
0039 return std::size_t(my_hasher(key));
0040 }
0041
0042 bool operator()( const Key& key1, const Key& key2 ) const {
0043 return my_equal(key1, key2);
0044 }
0045
0046 template <typename K, typename = typename std::enable_if<is_transparent_hash::value, K>::type>
0047 std::size_t operator()( const K& key ) const {
0048 return std::size_t(my_hasher(key));
0049 }
0050
0051 template <typename K1, typename K2, typename = typename std::enable_if<is_transparent_hash::value, K1>::type>
0052 bool operator()( const K1& key1, const K2& key2 ) const {
0053 return my_equal(key1, key2);
0054 }
0055
0056 hasher hash_function() const {
0057 return my_hasher;
0058 }
0059
0060 key_equal key_eq() const {
0061 return my_equal;
0062 }
0063
0064
0065 private:
0066 hasher my_hasher;
0067 key_equal my_equal;
0068 };
0069
0070
0071 template <typename Key>
0072 class tbb_hash_compare {
0073 public:
0074 std::size_t hash( const Key& a ) const { return my_hash_func(a); }
0075 #if defined(_MSC_VER) && _MSC_VER <= 1900
0076 #pragma warning (push)
0077
0078 #pragma warning (disable: 4800)
0079 #endif
0080 bool equal( const Key& a, const Key& b ) const { return my_key_equal(a, b); }
0081 #if defined(_MSC_VER) && _MSC_VER <= 1900
0082 #pragma warning (pop)
0083 #endif
0084 private:
0085 std::hash<Key> my_hash_func;
0086 std::equal_to<Key> my_key_equal;
0087 };
0088
0089 }
0090 #if __TBB_CPP20_CONCEPTS_PRESENT
0091 inline namespace d0 {
0092
0093 template <typename HashCompare, typename Key>
0094 concept hash_compare = std::copy_constructible<HashCompare> &&
0095 requires( const std::remove_reference_t<HashCompare>& hc, const Key& key1, const Key& key2 ) {
0096 { hc.hash(key1) } -> std::same_as<std::size_t>;
0097 { hc.equal(key1, key2) } -> std::convertible_to<bool>;
0098 };
0099
0100 }
0101 #endif
0102 }
0103 }
0104
0105 #if TBB_DEFINE_STD_HASH_SPECIALIZATIONS
0106
0107 namespace std {
0108
0109 template <typename T, typename U>
0110 struct hash<std::pair<T, U>> {
0111 public:
0112 std::size_t operator()( const std::pair<T, U>& p ) const {
0113 return first_hash(p.first) ^ second_hash(p.second);
0114 }
0115
0116 private:
0117 std::hash<T> first_hash;
0118 std::hash<U> second_hash;
0119 };
0120
0121
0122 #if !(_LIBCPP_VERSION) && !(_CPPLIB_VER)
0123
0124 template <typename CharT, typename Traits, typename Allocator>
0125 struct hash<std::basic_string<CharT, Traits, Allocator>> {
0126 public:
0127 std::size_t operator()( const std::basic_string<CharT, Traits, Allocator>& s ) const {
0128 std::size_t h = 0;
0129 for ( const CharT* c = s.c_str(); *c; ++c ) {
0130 h = h * hash_multiplier ^ char_hash(*c);
0131 }
0132 return h;
0133 }
0134
0135 private:
0136 static constexpr std::size_t hash_multiplier = tbb::detail::select_size_t_constant<2654435769U, 11400714819323198485ULL>::value;
0137
0138 std::hash<CharT> char_hash;
0139 };
0140
0141 #endif
0142
0143 }
0144
0145 #endif
0146
0147 #endif