diff options
Diffstat (limited to 'src/google/protobuf/stubs/hash.h')
-rw-r--r-- | src/google/protobuf/stubs/hash.h | 324 |
1 files changed, 3 insertions, 321 deletions
diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h index fd8ba156..a093b406 100644 --- a/src/google/protobuf/stubs/hash.h +++ b/src/google/protobuf/stubs/hash.h @@ -29,8 +29,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: kenton@google.com (Kenton Varda) -// -// Deals with the fact that hash_map is not defined everywhere. #ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__ #define GOOGLE_PROTOBUF_STUBS_HASH_H__ @@ -38,304 +36,19 @@ #include <string.h> #include <google/protobuf/stubs/common.h> -#define GOOGLE_PROTOBUF_HAVE_HASH_MAP 1 -#define GOOGLE_PROTOBUF_HAVE_HASH_SET 1 - -// Use C++11 unordered_{map|set} if available. -#if ((defined(_LIBCPP_STD_VER) && _LIBCPP_STD_VER >= 11) || \ - (((__cplusplus >= 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X)) && \ - (__GLIBCXX__ > 20090421))) -# define GOOGLE_PROTOBUF_HAS_CXX11_HASH - -// For XCode >= 4.6: the compiler is clang with libc++. -// For earlier XCode version: the compiler is gcc-4.2.1 with libstdc++. -// libc++ provides <unordered_map> and friends even in non C++11 mode, -// and it does not provide the tr1 library. Therefore the following macro -// checks against this special case. -// Note that we should not test the __APPLE_CC__ version number or the -// __clang__ macro, since the new compiler can still use -stdlib=libstdc++, in -// which case <unordered_map> is not compilable without -std=c++11 -#elif defined(__APPLE_CC__) -# if __GNUC__ >= 4 -# define GOOGLE_PROTOBUF_HAS_TR1 -# else -// Not tested for gcc < 4... These setting can compile under 4.2.1 though. -# define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx -# include <ext/hash_map> -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map -# include <ext/hash_set> -# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set -# endif - -// Version checks for gcc. -#elif defined(__GNUC__) -// For GCC 4.x+, use tr1::unordered_map/set; otherwise, follow the -// instructions from: -// https://gcc.gnu.org/onlinedocs/libstdc++/manual/backwards.html -# if __GNUC__ >= 4 -# define GOOGLE_PROTOBUF_HAS_TR1 -# elif __GNUC__ >= 3 -# include <backward/hash_map> -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map -# include <backward/hash_set> -# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set -# if __GNUC__ == 3 && __GNUC_MINOR__ == 0 -# define GOOGLE_PROTOBUF_HASH_NAMESPACE std // GCC 3.0 -# else -# define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx // GCC 3.1 and later -# endif -# else -# define GOOGLE_PROTOBUF_HASH_NAMESPACE -# include <hash_map> -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map -# include <hash_set> -# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set -# endif - -// GCC <= 4.1 does not define std::tr1::hash for `long long int` or `long long unsigned int` -# if __GNUC__ == 4 && defined(__GNUC_MINOR__) && __GNUC_MINOR__ <= 1 -# undef GOOGLE_PROTOBUF_HAS_TR1 -# undef GOOGLE_PROTOBUF_HAVE_HASH_MAP -# undef GOOGLE_PROTOBUF_HAVE_HASH_SET -# endif - -// Version checks for MSC. -// Apparently Microsoft decided to move hash_map *back* to the std namespace in -// MSVC 2010: -// http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx -// And.. they are moved back to stdext in MSVC 2013 (haven't checked 2012). That -// said, use unordered_map for MSVC 2010 and beyond is our safest bet. -#elif defined(_MSC_VER) -# if _MSC_VER >= 1600 // Since Visual Studio 2010 -# define GOOGLE_PROTOBUF_HAS_CXX11_HASH -# define GOOGLE_PROTOBUF_HASH_COMPARE std::hash_compare -# elif _MSC_VER >= 1500 // Since Visual Studio 2008 -# define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext -# include <hash_map> -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map -# include <hash_set> -# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set -# define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare -# define GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE -# elif _MSC_VER >= 1310 -# define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext -# include <hash_map> -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map -# include <hash_set> -# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set -# define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare -# else -# define GOOGLE_PROTOBUF_HASH_NAMESPACE std -# include <hash_map> -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map -# include <hash_set> -# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set -# define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare -# endif - -// **ADD NEW COMPILERS SUPPORT HERE.** -// For other compilers, undefine the macro and fallback to use std::map, in -// google/protobuf/stubs/hash.h -#else -# undef GOOGLE_PROTOBUF_HAVE_HASH_MAP -# undef GOOGLE_PROTOBUF_HAVE_HASH_SET -#endif - -#if defined(GOOGLE_PROTOBUF_HAS_CXX11_HASH) -# define GOOGLE_PROTOBUF_HASH_NAMESPACE std -# include <unordered_map> -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map -# include <unordered_set> -# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set -#elif defined(GOOGLE_PROTOBUF_HAS_TR1) -# define GOOGLE_PROTOBUF_HASH_NAMESPACE std::tr1 -# include <tr1/unordered_map> -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map -# include <tr1/unordered_set> -# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set -#endif +#include <unordered_map> +#include <unordered_set> # define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START \ namespace google { \ namespace protobuf { # define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END }} -#undef GOOGLE_PROTOBUF_HAS_CXX11_HASH -#undef GOOGLE_PROTOBUF_HAS_TR1 - -#if defined(GOOGLE_PROTOBUF_HAVE_HASH_MAP) && \ - defined(GOOGLE_PROTOBUF_HAVE_HASH_SET) -#else -#define GOOGLE_PROTOBUF_MISSING_HASH -#include <map> -#include <set> -#endif - namespace google { namespace protobuf { -#ifdef GOOGLE_PROTOBUF_MISSING_HASH -#undef GOOGLE_PROTOBUF_MISSING_HASH - -// This system doesn't have hash_map or hash_set. Emulate them using map and -// set. - -// Make hash<T> be the same as less<T>. Note that everywhere where custom -// hash functions are defined in the protobuf code, they are also defined such -// that they can be used as "less" functions, which is required by MSVC anyway. template <typename Key> -struct hash { - // Dummy, just to make derivative hash functions compile. - int operator()(const Key& key) { - GOOGLE_LOG(FATAL) << "Should never be called."; - return 0; - } - - inline bool operator()(const Key& a, const Key& b) const { - return a < b; - } -}; - -// Make sure char* is compared by value. -template <> -struct hash<const char*> { - // Dummy, just to make derivative hash functions compile. - int operator()(const char* key) { - GOOGLE_LOG(FATAL) << "Should never be called."; - return 0; - } - - inline bool operator()(const char* a, const char* b) const { - return strcmp(a, b) < 0; - } -}; - -template <typename Key, typename Data, - typename HashFcn = hash<Key>, - typename EqualKey = std::equal_to<Key>, - typename Alloc = std::allocator< std::pair<const Key, Data> > > -class hash_map : public std::map<Key, Data, HashFcn, Alloc> { - typedef std::map<Key, Data, HashFcn, Alloc> BaseClass; - - public: - hash_map(int a = 0, const HashFcn& b = HashFcn(), - const EqualKey& c = EqualKey(), - const Alloc& d = Alloc()) : BaseClass(b, d) {} - - HashFcn hash_function() const { return HashFcn(); } -}; - -template <typename Key, - typename HashFcn = hash<Key>, - typename EqualKey = std::equal_to<Key> > -class hash_set : public std::set<Key, HashFcn> { - public: - hash_set(int = 0) {} - - HashFcn hash_function() const { return HashFcn(); } -}; - -#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION) && \ - !(defined(_LIBCPP_STD_VER) && _LIBCPP_STD_VER >= 11) - -template <typename Key> -struct hash : public GOOGLE_PROTOBUF_HASH_COMPARE<Key> { -}; - -// MSVC's hash_compare<const char*> hashes based on the string contents but -// compares based on the string pointer. WTF? -class CstringLess { - public: - inline bool operator()(const char* a, const char* b) const { - return strcmp(a, b) < 0; - } -}; - -template <> -struct hash<const char*> - : public GOOGLE_PROTOBUF_HASH_COMPARE<const char*, CstringLess> {}; - -#ifdef GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE - -template <typename Key, typename HashFcn, typename EqualKey> -struct InternalHashCompare : public GOOGLE_PROTOBUF_HASH_COMPARE<Key> { - InternalHashCompare() {} - InternalHashCompare(HashFcn hashfcn, EqualKey equalkey) - : hashfcn_(hashfcn), equalkey_(equalkey) {} - size_t operator()(const Key& key) const { return hashfcn_(key); } - bool operator()(const Key& key1, const Key& key2) const { - return !equalkey_(key1, key2); - } - HashFcn hashfcn_; - EqualKey equalkey_; -}; - -template <typename Key, typename Data, - typename HashFcn = hash<Key>, - typename EqualKey = std::equal_to<Key>, - typename Alloc = std::allocator< std::pair<const Key, Data> > > -class hash_map - : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< - Key, Data, InternalHashCompare<Key, HashFcn, EqualKey>, Alloc> { - typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< - Key, Data, InternalHashCompare<Key, HashFcn, EqualKey>, Alloc> BaseClass; - - public: - hash_map(int a = 0, const HashFcn& b = HashFcn(), - const EqualKey& c = EqualKey(), const Alloc& d = Alloc()) - : BaseClass(InternalHashCompare<Key, HashFcn, EqualKey>(b, c), d) {} - - HashFcn hash_function() const { return HashFcn(); } -}; - -template <typename Key, typename HashFcn = hash<Key>, - typename EqualKey = std::equal_to<Key> > -class hash_set - : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS< - Key, InternalHashCompare<Key, HashFcn, EqualKey> > { - public: - hash_set(int = 0) {} - - HashFcn hash_function() const { return HashFcn(); } -}; - -#else // GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE - -template <typename Key, typename Data, - typename HashFcn = hash<Key>, - typename EqualKey = std::equal_to<Key>, - typename Alloc = std::allocator< std::pair<const Key, Data> > > -class hash_map - : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< - Key, Data, HashFcn, EqualKey, Alloc> { - typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< - Key, Data, HashFcn, EqualKey, Alloc> BaseClass; - - public: - hash_map(int a = 0, const HashFcn& b = HashFcn(), - const EqualKey& c = EqualKey(), - const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {} - - HashFcn hash_function() const { return HashFcn(); } -}; - -template <typename Key, typename HashFcn = hash<Key>, - typename EqualKey = std::equal_to<Key> > -class hash_set - : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS< - Key, HashFcn, EqualKey> { - public: - hash_set(int = 0) {} - - HashFcn hash_function() const { return HashFcn(); } -}; -#endif // GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE - -#else // defined(_MSC_VER) && !defined(_STLPORT_VERSION) - -template <typename Key> -struct hash : public GOOGLE_PROTOBUF_HASH_NAMESPACE::hash<Key> { -}; +struct hash : public std::hash<Key> {}; template <typename Key> struct hash<const Key*> { @@ -364,37 +77,6 @@ struct hash<bool> { } }; -template <typename Key, typename Data, - typename HashFcn = hash<Key>, - typename EqualKey = std::equal_to<Key>, - typename Alloc = std::allocator< std::pair<const Key, Data> > > -class hash_map - : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< - Key, Data, HashFcn, EqualKey, Alloc> { - typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< - Key, Data, HashFcn, EqualKey, Alloc> BaseClass; - - public: - hash_map(int a = 0, const HashFcn& b = HashFcn(), - const EqualKey& c = EqualKey(), - const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {} - - HashFcn hash_function() const { return HashFcn(); } -}; - -template <typename Key, typename HashFcn = hash<Key>, - typename EqualKey = std::equal_to<Key> > -class hash_set - : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS< - Key, HashFcn, EqualKey> { - public: - hash_set(int = 0) {} - - HashFcn hash_function() const { return HashFcn(); } -}; - -#endif // !GOOGLE_PROTOBUF_MISSING_HASH - template <> struct hash<string> { inline size_t operator()(const string& key) const { |