| Index: base/containers/hash_tables.h
|
| diff --git a/base/containers/hash_tables.h b/base/containers/hash_tables.h
|
| index 6f37c49c3e476f7ccf9f0685d8ada16befa1b03d..6904d7754433e742a09b667450f2c9ebf1e7bc56 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,27 @@
|
|
|
| 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 {
|
| + BASE_HASH_IMPL_NAMESPACE::hash<T> h;
|
| + return h(value);
|
| + }
|
| +};
|
| +
|
| +template<typename T>
|
| +struct hash<T*> {
|
| + std::size_t operator()(T* value) const {
|
| + BASE_HASH_IMPL_NAMESPACE::hash<uintptr_t> h;
|
| + return h(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
|
| @@ -114,10 +134,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
|
| @@ -237,14 +314,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 {
|
| @@ -252,10 +321,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
|
|
|