hash_function_defaults.h
Go to the documentation of this file.
00001 // Copyright 2018 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 //
00015 // Define the default Hash and Eq functions for SwissTable containers.
00016 //
00017 // std::hash<T> and std::equal_to<T> are not appropriate hash and equal
00018 // functions for SwissTable containers. There are two reasons for this.
00019 //
00020 // SwissTable containers are power of 2 sized containers:
00021 //
00022 // This means they use the lower bits of the hash value to find the slot for
00023 // each entry. The typical hash function for integral types is the identity.
00024 // This is a very weak hash function for SwissTable and any power of 2 sized
00025 // hashtable implementation which will lead to excessive collisions. For
00026 // SwissTable we use murmur3 style mixing to reduce collisions to a minimum.
00027 //
00028 // SwissTable containers support heterogeneous lookup:
00029 //
00030 // In order to make heterogeneous lookup work, hash and equal functions must be
00031 // polymorphic. At the same time they have to satisfy the same requirements the
00032 // C++ standard imposes on hash functions and equality operators. That is:
00033 //
00034 //   if hash_default_eq<T>(a, b) returns true for any a and b of type T, then
00035 //   hash_default_hash<T>(a) must equal hash_default_hash<T>(b)
00036 //
00037 // For SwissTable containers this requirement is relaxed to allow a and b of
00038 // any and possibly different types. Note that like the standard the hash and
00039 // equal functions are still bound to T. This is important because some type U
00040 // can be hashed by/tested for equality differently depending on T. A notable
00041 // example is `const char*`. `const char*` is treated as a c-style string when
00042 // the hash function is hash<std::string> but as a pointer when the hash
00043 // function is hash<void*>.
00044 //
00045 #ifndef ABSL_CONTAINER_INTERNAL_HASH_FUNCTION_DEFAULTS_H_
00046 #define ABSL_CONTAINER_INTERNAL_HASH_FUNCTION_DEFAULTS_H_
00047 
00048 #include <stdint.h>
00049 #include <cstddef>
00050 #include <memory>
00051 #include <string>
00052 #include <type_traits>
00053 
00054 #include "absl/base/config.h"
00055 #include "absl/hash/hash.h"
00056 #include "absl/strings/string_view.h"
00057 
00058 namespace absl {
00059 namespace container_internal {
00060 
00061 // The hash of an object of type T is computed by using absl::Hash.
00062 template <class T, class E = void>
00063 struct HashEq {
00064   using Hash = absl::Hash<T>;
00065   using Eq = std::equal_to<T>;
00066 };
00067 
00068 struct StringHash {
00069   using is_transparent = void;
00070 
00071   size_t operator()(absl::string_view v) const {
00072     return absl::Hash<absl::string_view>{}(v);
00073   }
00074 };
00075 
00076 // Supports heterogeneous lookup for string-like elements.
00077 struct StringHashEq {
00078   using Hash = StringHash;
00079   struct Eq {
00080     using is_transparent = void;
00081     bool operator()(absl::string_view lhs, absl::string_view rhs) const {
00082       return lhs == rhs;
00083     }
00084   };
00085 };
00086 
00087 template <>
00088 struct HashEq<std::string> : StringHashEq {};
00089 template <>
00090 struct HashEq<absl::string_view> : StringHashEq {};
00091 
00092 // Supports heterogeneous lookup for pointers and smart pointers.
00093 template <class T>
00094 struct HashEq<T*> {
00095   struct Hash {
00096     using is_transparent = void;
00097     template <class U>
00098     size_t operator()(const U& ptr) const {
00099       return absl::Hash<const T*>{}(HashEq::ToPtr(ptr));
00100     }
00101   };
00102   struct Eq {
00103     using is_transparent = void;
00104     template <class A, class B>
00105     bool operator()(const A& a, const B& b) const {
00106       return HashEq::ToPtr(a) == HashEq::ToPtr(b);
00107     }
00108   };
00109 
00110  private:
00111   static const T* ToPtr(const T* ptr) { return ptr; }
00112   template <class U, class D>
00113   static const T* ToPtr(const std::unique_ptr<U, D>& ptr) {
00114     return ptr.get();
00115   }
00116   template <class U>
00117   static const T* ToPtr(const std::shared_ptr<U>& ptr) {
00118     return ptr.get();
00119   }
00120 };
00121 
00122 template <class T, class D>
00123 struct HashEq<std::unique_ptr<T, D>> : HashEq<T*> {};
00124 template <class T>
00125 struct HashEq<std::shared_ptr<T>> : HashEq<T*> {};
00126 
00127 // This header's visibility is restricted.  If you need to access the default
00128 // hasher please use the container's ::hasher alias instead.
00129 //
00130 // Example: typename Hash = typename absl::flat_hash_map<K, V>::hasher
00131 template <class T>
00132 using hash_default_hash = typename container_internal::HashEq<T>::Hash;
00133 
00134 // This header's visibility is restricted.  If you need to access the default
00135 // key equal please use the container's ::key_equal alias instead.
00136 //
00137 // Example: typename Eq = typename absl::flat_hash_map<K, V, Hash>::key_equal
00138 template <class T>
00139 using hash_default_eq = typename container_internal::HashEq<T>::Eq;
00140 
00141 }  // namespace container_internal
00142 }  // namespace absl
00143 
00144 #endif  // ABSL_CONTAINER_INTERNAL_HASH_FUNCTION_DEFAULTS_H_


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:14