File indexing completed on 2025-01-18 09:27:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 #ifndef ABSL_CONTAINER_INTERNAL_HASH_FUNCTION_DEFAULTS_H_
0046 #define ABSL_CONTAINER_INTERNAL_HASH_FUNCTION_DEFAULTS_H_
0047
0048 #include <cstddef>
0049 #include <functional>
0050 #include <memory>
0051 #include <string>
0052 #include <type_traits>
0053
0054 #include "absl/base/config.h"
0055 #include "absl/container/internal/common.h"
0056 #include "absl/hash/hash.h"
0057 #include "absl/meta/type_traits.h"
0058 #include "absl/strings/cord.h"
0059 #include "absl/strings/string_view.h"
0060
0061 #ifdef ABSL_HAVE_STD_STRING_VIEW
0062 #include <string_view>
0063 #endif
0064
0065 namespace absl {
0066 ABSL_NAMESPACE_BEGIN
0067 namespace container_internal {
0068
0069
0070 template <class T, class E = void>
0071 struct HashEq {
0072 using Hash = absl::Hash<T>;
0073 using Eq = std::equal_to<T>;
0074 };
0075
0076 struct StringHash {
0077 using is_transparent = void;
0078
0079 size_t operator()(absl::string_view v) const {
0080 return absl::Hash<absl::string_view>{}(v);
0081 }
0082 size_t operator()(const absl::Cord& v) const {
0083 return absl::Hash<absl::Cord>{}(v);
0084 }
0085 };
0086
0087 struct StringEq {
0088 using is_transparent = void;
0089 bool operator()(absl::string_view lhs, absl::string_view rhs) const {
0090 return lhs == rhs;
0091 }
0092 bool operator()(const absl::Cord& lhs, const absl::Cord& rhs) const {
0093 return lhs == rhs;
0094 }
0095 bool operator()(const absl::Cord& lhs, absl::string_view rhs) const {
0096 return lhs == rhs;
0097 }
0098 bool operator()(absl::string_view lhs, const absl::Cord& rhs) const {
0099 return lhs == rhs;
0100 }
0101 };
0102
0103
0104 struct StringHashEq {
0105 using Hash = StringHash;
0106 using Eq = StringEq;
0107 };
0108
0109 template <>
0110 struct HashEq<std::string> : StringHashEq {};
0111 template <>
0112 struct HashEq<absl::string_view> : StringHashEq {};
0113 template <>
0114 struct HashEq<absl::Cord> : StringHashEq {};
0115
0116 #ifdef ABSL_HAVE_STD_STRING_VIEW
0117
0118 template <typename TChar>
0119 struct BasicStringHash {
0120 using is_transparent = void;
0121
0122 size_t operator()(std::basic_string_view<TChar> v) const {
0123 return absl::Hash<std::basic_string_view<TChar>>{}(v);
0124 }
0125 };
0126
0127 template <typename TChar>
0128 struct BasicStringEq {
0129 using is_transparent = void;
0130 bool operator()(std::basic_string_view<TChar> lhs,
0131 std::basic_string_view<TChar> rhs) const {
0132 return lhs == rhs;
0133 }
0134 };
0135
0136
0137 template <typename TChar>
0138 struct BasicStringHashEq {
0139 using Hash = BasicStringHash<TChar>;
0140 using Eq = BasicStringEq<TChar>;
0141 };
0142
0143 template <>
0144 struct HashEq<std::wstring> : BasicStringHashEq<wchar_t> {};
0145 template <>
0146 struct HashEq<std::wstring_view> : BasicStringHashEq<wchar_t> {};
0147 template <>
0148 struct HashEq<std::u16string> : BasicStringHashEq<char16_t> {};
0149 template <>
0150 struct HashEq<std::u16string_view> : BasicStringHashEq<char16_t> {};
0151 template <>
0152 struct HashEq<std::u32string> : BasicStringHashEq<char32_t> {};
0153 template <>
0154 struct HashEq<std::u32string_view> : BasicStringHashEq<char32_t> {};
0155
0156 #endif
0157
0158
0159 template <class T>
0160 struct HashEq<T*> {
0161 struct Hash {
0162 using is_transparent = void;
0163 template <class U>
0164 size_t operator()(const U& ptr) const {
0165 return absl::Hash<const T*>{}(HashEq::ToPtr(ptr));
0166 }
0167 };
0168 struct Eq {
0169 using is_transparent = void;
0170 template <class A, class B>
0171 bool operator()(const A& a, const B& b) const {
0172 return HashEq::ToPtr(a) == HashEq::ToPtr(b);
0173 }
0174 };
0175
0176 private:
0177 static const T* ToPtr(const T* ptr) { return ptr; }
0178 template <class U, class D>
0179 static const T* ToPtr(const std::unique_ptr<U, D>& ptr) {
0180 return ptr.get();
0181 }
0182 template <class U>
0183 static const T* ToPtr(const std::shared_ptr<U>& ptr) {
0184 return ptr.get();
0185 }
0186 };
0187
0188 template <class T, class D>
0189 struct HashEq<std::unique_ptr<T, D>> : HashEq<T*> {};
0190 template <class T>
0191 struct HashEq<std::shared_ptr<T>> : HashEq<T*> {};
0192
0193 template <typename T, typename E = void>
0194 struct HasAbslContainerHash : std::false_type {};
0195
0196 template <typename T>
0197 struct HasAbslContainerHash<T, absl::void_t<typename T::absl_container_hash>>
0198 : std::true_type {};
0199
0200 template <typename T, typename E = void>
0201 struct HasAbslContainerEq : std::false_type {};
0202
0203 template <typename T>
0204 struct HasAbslContainerEq<T, absl::void_t<typename T::absl_container_eq>>
0205 : std::true_type {};
0206
0207 template <typename T, typename E = void>
0208 struct AbslContainerEq {
0209 using type = std::equal_to<>;
0210 };
0211
0212 template <typename T>
0213 struct AbslContainerEq<
0214 T, typename std::enable_if_t<HasAbslContainerEq<T>::value>> {
0215 using type = typename T::absl_container_eq;
0216 };
0217
0218 template <typename T, typename E = void>
0219 struct AbslContainerHash {
0220 using type = void;
0221 };
0222
0223 template <typename T>
0224 struct AbslContainerHash<
0225 T, typename std::enable_if_t<HasAbslContainerHash<T>::value>> {
0226 using type = typename T::absl_container_hash;
0227 };
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246 template <typename T>
0247 struct HashEq<T, typename std::enable_if_t<HasAbslContainerHash<T>::value>> {
0248 using Hash = typename AbslContainerHash<T>::type;
0249 using Eq = typename AbslContainerEq<T>::type;
0250 static_assert(IsTransparent<Hash>::value,
0251 "absl_container_hash must be transparent. To achieve it add a "
0252 "`using is_transparent = void;` clause to this type.");
0253 static_assert(IsTransparent<Eq>::value,
0254 "absl_container_eq must be transparent. To achieve it add a "
0255 "`using is_transparent = void;` clause to this type.");
0256 };
0257
0258
0259
0260
0261
0262 template <class T>
0263 using hash_default_hash = typename container_internal::HashEq<T>::Hash;
0264
0265
0266
0267
0268
0269 template <class T>
0270 using hash_default_eq = typename container_internal::HashEq<T>::Eq;
0271
0272 }
0273 ABSL_NAMESPACE_END
0274 }
0275
0276 #endif