| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
|
|
| #ifndef ABSL_HASH_INTERNAL_HASH_TEST_H_ |
| #define ABSL_HASH_INTERNAL_HASH_TEST_H_ |
|
|
| #include <type_traits> |
| #include <utility> |
|
|
| #include "absl/base/config.h" |
| #include "absl/hash/hash.h" |
|
|
| namespace absl { |
| ABSL_NAMESPACE_BEGIN |
| namespace hash_test_internal { |
|
|
| |
| |
| |
| |
| template <typename T> |
| class TypeErasedValue { |
| public: |
| TypeErasedValue() = default; |
| TypeErasedValue(const TypeErasedValue&) = default; |
| TypeErasedValue(TypeErasedValue&&) = default; |
| explicit TypeErasedValue(const T& n) : n_(n) {} |
|
|
| template <typename H> |
| friend H AbslHashValue(H hash_state, const TypeErasedValue& v) { |
| v.HashValue(absl::HashState::Create(&hash_state)); |
| return hash_state; |
| } |
|
|
| void HashValue(absl::HashState state) const { |
| absl::HashState::combine(std::move(state), n_); |
| } |
|
|
| bool operator==(const TypeErasedValue& rhs) const { return n_ == rhs.n_; } |
| bool operator!=(const TypeErasedValue& rhs) const { return !(*this == rhs); } |
|
|
| private: |
| T n_; |
| }; |
|
|
| |
| |
| template <typename T> |
| class TypeErasedContainer : public TypeErasedValue<T> { |
| public: |
| using value_type = typename T::value_type; |
| TypeErasedContainer() = default; |
| TypeErasedContainer(const TypeErasedContainer&) = default; |
| TypeErasedContainer(TypeErasedContainer&&) = default; |
| explicit TypeErasedContainer(const T& n) : TypeErasedValue<T>(n) {} |
| TypeErasedContainer(std::initializer_list<value_type> init_list) |
| : TypeErasedContainer(T(init_list.begin(), init_list.end())) {} |
| |
| |
| explicit TypeErasedContainer(const value_type& v) |
| : TypeErasedContainer(T(&v, &v + 1)) {} |
| }; |
|
|
| |
| |
| template <typename T> |
| using is_hashable = std::is_default_constructible<absl::Hash<T>>; |
|
|
| } |
| ABSL_NAMESPACE_END |
| } |
|
|
| #endif |
|
|