Index: base/containers/hash_tables.h |
diff --git a/base/containers/hash_tables.h b/base/containers/hash_tables.h |
index c803ace5cfe2609135e686e5ccc9799d1e30c426..6bf029e4565f50c24db91243fe6601252bca8704 100644 |
--- a/base/containers/hash_tables.h |
+++ b/base/containers/hash_tables.h |
@@ -28,17 +28,14 @@ |
#include "build/build_config.h" |
#if defined(COMPILER_MSVC) |
-#include <hash_map> |
-#include <hash_set> |
+#include <unordered_map> |
+#include <unordered_set> |
-#define BASE_HASH_NAMESPACE stdext |
+#define BASE_HASH_NAMESPACE std |
#elif defined(COMPILER_GCC) |
-#if defined(OS_ANDROID) |
-#define BASE_HASH_NAMESPACE std |
-#else |
-#define BASE_HASH_NAMESPACE __gnu_cxx |
-#endif |
+ |
+#define BASE_HASH_NAMESPACE base_hash |
// This is a hack to disable the gcc 4.4 warning about hash_map and hash_set |
// being deprecated. We can get rid of this when we upgrade to VS2008 and we |
@@ -51,9 +48,11 @@ |
#if defined(OS_ANDROID) |
#include <hash_map> |
#include <hash_set> |
+#define BASE_HASH_IMPL_NAMESPACE std |
#else |
#include <ext/hash_map> |
#include <ext/hash_set> |
+#define BASE_HASH_IMPL_NAMESPACE __gnu_cxx |
#endif |
#include <string> |
@@ -65,6 +64,26 @@ |
namespace BASE_HASH_NAMESPACE { |
+// The pre-standard hash behaves like C++11's std::hash, except around pointers. |
+// const char* is specialized to hash the C string and hash functions for |
+// general T* are missing. Define a BASE_HASH_NAMESPACE::hash which aligns with |
+// the C++11 behavior. |
+ |
+template<typename T> |
+struct hash { |
+ std::size_t operator()(const T& value) const { |
+ return BASE_HASH_IMPL_NAMESPACE::hash<T>()(value); |
+ } |
+}; |
+ |
+template<typename T> |
+struct hash<T*> { |
+ std::size_t operator()(T* value) const { |
+ return BASE_HASH_IMPL_NAMESPACE::hash<uintptr_t>()( |
+ reinterpret_cast<uintptr_t>(value)); |
+ } |
+}; |
+ |
#if !defined(OS_ANDROID) |
// The GNU C++ library provides identity hash functions for many integral types, |
// but not for |long long|. This hash function will truncate if |size_t| is |
@@ -85,17 +104,6 @@ DEFINE_TRIVIAL_HASH(unsigned long long); |
#undef DEFINE_TRIVIAL_HASH |
#endif // !defined(OS_ANDROID) |
-// To align with C++11's std::hash and MSVC's pre-standard stdext::hash_value, |
-// provide a default hash function for raw pointers. Note: const char * is still |
-// specialized to hash as a C string. This is consistent with the currently used |
-// stdext::hash_value, but not C++11. |
-template<typename T> |
-struct hash<T*> { |
- std::size_t operator()(T* value) const { |
- return hash<uintptr_t>()(reinterpret_cast<uintptr_t>(value)); |
- } |
-}; |
- |
// Implement string hash functions so that strings of various flavors can |
// be used as keys in STL maps and sets. The hash algorithm comes from the |
// GNU C++ library, in <tr1/functional>. It is duplicated here because GCC |
@@ -125,10 +133,67 @@ DEFINE_STRING_HASH(base::string16); |
#endif // COMPILER |
namespace base { |
-using BASE_HASH_NAMESPACE::hash_map; |
-using BASE_HASH_NAMESPACE::hash_multimap; |
-using BASE_HASH_NAMESPACE::hash_multiset; |
-using BASE_HASH_NAMESPACE::hash_set; |
+ |
+// On MSVC, use the C++11 containers. |
+#if defined(COMPILER_MSVC) |
+ |
+template<class Key, class T, |
+ class Hash = std::hash<Key>, |
+ class Pred = std::equal_to<Key>, |
+ class Alloc = std::allocator<std::pair<const Key, T>>> |
+using hash_map = std::unordered_map<Key, T, Hash, Pred, Alloc>; |
+ |
+template<class Key, class T, |
+ class Hash = std::hash<Key>, |
+ class Pred = std::equal_to<Key>, |
+ class Alloc = std::allocator<std::pair<const Key, T>>> |
+using hash_multimap = std::unordered_multimap<Key, T, Hash, Pred, Alloc>; |
+ |
+template<class Key, |
+ class Hash = std::hash<Key>, |
+ class Pred = std::equal_to<Key>, |
+ class Alloc = std::allocator<Key>> |
+using hash_multiset = std::unordered_multiset<Key, Hash, Pred, Alloc>; |
+ |
+template<class Key, |
+ class Hash = std::hash<Key>, |
+ class Pred = std::equal_to<Key>, |
+ class Alloc = std::allocator<Key>> |
+using hash_set = std::unordered_set<Key, Hash, Pred, Alloc>; |
+ |
+#else // !COMPILER_MSVC |
+ |
+// Otherwise, use the pre-standard ones, but override the default hash to match |
+// C++11. |
+template<class Key, class T, |
+ class Hash = BASE_HASH_NAMESPACE::hash<Key>, |
+ class Pred = std::equal_to<Key>, |
+ class Alloc = std::allocator<std::pair<const Key, T>>> |
+using hash_map = BASE_HASH_IMPL_NAMESPACE::hash_map<Key, T, Hash, Pred, Alloc>; |
+ |
+template<class Key, class T, |
+ class Hash = BASE_HASH_NAMESPACE::hash<Key>, |
+ class Pred = std::equal_to<Key>, |
+ class Alloc = std::allocator<std::pair<const Key, T>>> |
+using hash_multimap = |
+ BASE_HASH_IMPL_NAMESPACE::hash_multimap<Key, T, Hash, Pred, Alloc>; |
+ |
+template<class Key, |
+ class Hash = BASE_HASH_NAMESPACE::hash<Key>, |
+ class Pred = std::equal_to<Key>, |
+ class Alloc = std::allocator<Key>> |
+using hash_multiset = |
+ BASE_HASH_IMPL_NAMESPACE::hash_multiset<Key, Hash, Pred, Alloc>; |
+ |
+template<class Key, |
+ class Hash = BASE_HASH_NAMESPACE::hash<Key>, |
+ class Pred = std::equal_to<Key>, |
+ class Alloc = std::allocator<Key>> |
+using hash_set = BASE_HASH_IMPL_NAMESPACE::hash_set<Key, Hash, Pred, Alloc>; |
+ |
+#undef BASE_HASH_IMPL_NAMESPACE |
+ |
+#endif // COMPILER_MSVC |
// Implement hashing for pairs of at-most 32 bit integer values. |
// When size_t is 32 bits, we turn the 64-bit hash code into 32 bits by using |
@@ -248,14 +313,6 @@ namespace BASE_HASH_NAMESPACE { |
// Implement methods for hashing a pair of integers, so they can be used as |
// keys in STL containers. |
-#if defined(COMPILER_MSVC) |
- |
-template<typename Type1, typename Type2> |
-inline std::size_t hash_value(const std::pair<Type1, Type2>& value) { |
- return base::HashPair(value.first, value.second); |
-} |
- |
-#elif defined(COMPILER_GCC) |
template<typename Type1, typename Type2> |
struct hash<std::pair<Type1, Type2> > { |
std::size_t operator()(std::pair<Type1, Type2> value) const { |
@@ -263,10 +320,6 @@ struct hash<std::pair<Type1, Type2> > { |
} |
}; |
-#else |
-#error define hash<std::pair<Type1, Type2> > for your compiler |
-#endif // COMPILER |
- |
} |
#undef DEFINE_PAIR_HASH_FUNCTION_START |