Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: third_party/protobuf/src/google/protobuf/stubs/hash.h

Issue 1322483002: Revert https://codereview.chromium.org/1291903002 (protobuf roll). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 19 matching lines...) Expand all
30 30
31 // Author: kenton@google.com (Kenton Varda) 31 // Author: kenton@google.com (Kenton Varda)
32 // 32 //
33 // Deals with the fact that hash_map is not defined everywhere. 33 // Deals with the fact that hash_map is not defined everywhere.
34 34
35 #ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__ 35 #ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__
36 #define GOOGLE_PROTOBUF_STUBS_HASH_H__ 36 #define GOOGLE_PROTOBUF_STUBS_HASH_H__
37 37
38 #include <string.h> 38 #include <string.h>
39 #include <google/protobuf/stubs/common.h> 39 #include <google/protobuf/stubs/common.h>
40 40 #include <google/protobuf/stubs/pbconfig.h>
41 #define GOOGLE_PROTOBUF_HAVE_HASH_MAP 1
42 #define GOOGLE_PROTOBUF_HAVE_HASH_SET 1
43
44 // Use C++11 unordered_{map|set} if available.
45 #if ((__cplusplus >= 201103L) && \
46 ((defined(__GLIBCXX__) && (__GLIBCXX__ > 20090421)) || \
47 (defined(_LIBCPP_VERSION) && (_LIBCPP_STD_VER >= 11))))
48 # define GOOGLE_PROTOBUF_HAS_CXX11_HASH
49
50 // For XCode >= 4.6: the compiler is clang with libc++.
51 // For earlier XCode version: the compiler is gcc-4.2.1 with libstdc++.
52 // libc++ provides <unordered_map> and friends even in non C++11 mode,
53 // and it does not provide the tr1 library. Therefore the following macro
54 // checks against this special case.
55 // Note that we should not test the __APPLE_CC__ version number or the
56 // __clang__ macro, since the new compiler can still use -stdlib=libstdc++, in
57 // which case <unordered_map> is not compilable without -std=c++11
58 #elif defined(__APPLE_CC__)
59 # if __GNUC__ >= 4
60 # define GOOGLE_PROTOBUF_HAS_TR1
61 # else
62 // Not tested for gcc < 4... These setting can compile under 4.2.1 though.
63 # define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx
64 # include <ext/hash_map>
65 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
66 # include <ext/hash_set>
67 # define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
68 # endif
69
70 // Version checks for gcc.
71 #elif defined(__GNUC__)
72 // For GCC 4.x+, use tr1::unordered_map/set; otherwise, follow the
73 // instructions from:
74 // https://gcc.gnu.org/onlinedocs/libstdc++/manual/backwards.html
75 # if __GNUC__ >= 4
76 # define GOOGLE_PROTOBUF_HAS_TR1
77 # elif __GNUC__ >= 3
78 # include <backward/hash_map>
79 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
80 # include <backward/hash_set>
81 # define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
82 # if __GNUC__ == 3 && __GNUC_MINOR__ == 0
83 # define GOOGLE_PROTOBUF_HASH_NAMESPACE std // GCC 3.0
84 # else
85 # define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx // GCC 3.1 and later
86 # endif
87 # else
88 # define GOOGLE_PROTOBUF_HASH_NAMESPACE
89 # include <hash_map>
90 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
91 # include <hash_set>
92 # define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
93 # endif
94
95 // Version checks for MSC.
96 // Apparently Microsoft decided to move hash_map *back* to the std namespace in
97 // MSVC 2010:
98 // http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visua l-studio-2010-beta-1.aspx
99 // And.. they are moved back to stdext in MSVC 2013 (haven't checked 2012). That
100 // said, use unordered_map for MSVC 2010 and beyond is our safest bet.
101 #elif defined(_MSC_VER)
102 # if _MSC_VER >= 1600 // Since Visual Studio 2010
103 # define GOOGLE_PROTOBUF_HAS_CXX11_HASH
104 # define GOOGLE_PROTOBUF_HASH_COMPARE std::hash_compare
105 # elif _MSC_VER >= 1500 // Since Visual Studio 2008
106 # define GOOGLE_PROTOBUF_HAS_TR1
107 # define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
108 # elif _MSC_VER >= 1310
109 # define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext
110 # include <hash_map>
111 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
112 # include <hash_set>
113 # define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
114 # define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
115 # else
116 # define GOOGLE_PROTOBUF_HASH_NAMESPACE std
117 # include <hash_map>
118 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
119 # include <hash_set>
120 # define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
121 # define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
122 # endif
123
124 // **ADD NEW COMPILERS SUPPORT HERE.**
125 // For other compilers, undefine the macro and fallback to use std::map, in
126 // google/protobuf/stubs/hash.h
127 #else
128 # undef GOOGLE_PROTOBUF_HAVE_HASH_MAP
129 # undef GOOGLE_PROTOBUF_HAVE_HASH_SET
130 #endif
131
132 #if defined(GOOGLE_PROTOBUF_HAS_CXX11_HASH)
133 # define GOOGLE_PROTOBUF_HASH_NAMESPACE std
134 # include <unordered_map>
135 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
136 # include <unordered_set>
137 # define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
138 #elif defined(GOOGLE_PROTOBUF_HAS_TR1)
139 # define GOOGLE_PROTOBUF_HASH_NAMESPACE std::tr1
140 # include <tr1/unordered_map>
141 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
142 # include <tr1/unordered_set>
143 # define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
144 #endif
145
146 #undef GOOGLE_PROTOBUF_HAS_CXX11_HASH
147 #undef GOOGLE_PROTOBUF_HAS_TR1
148 41
149 #if defined(GOOGLE_PROTOBUF_HAVE_HASH_MAP) && \ 42 #if defined(GOOGLE_PROTOBUF_HAVE_HASH_MAP) && \
150 defined(GOOGLE_PROTOBUF_HAVE_HASH_SET) 43 defined(GOOGLE_PROTOBUF_HAVE_HASH_SET)
44 #include GOOGLE_PROTOBUF_HASH_MAP_H
45 #include GOOGLE_PROTOBUF_HASH_SET_H
151 #else 46 #else
152 #define GOOGLE_PROTOBUF_MISSING_HASH 47 #define GOOGLE_PROTOBUF_MISSING_HASH
153 #include <map> 48 #include <map>
154 #include <set> 49 #include <set>
155 #endif 50 #endif
156 51
157 namespace google { 52 namespace google {
158 namespace protobuf { 53 namespace protobuf {
159 54
160 #ifdef GOOGLE_PROTOBUF_MISSING_HASH 55 #ifdef GOOGLE_PROTOBUF_MISSING_HASH
161 #undef GOOGLE_PROTOBUF_MISSING_HASH
162 56
163 // This system doesn't have hash_map or hash_set. Emulate them using map and 57 // This system doesn't have hash_map or hash_set. Emulate them using map and
164 // set. 58 // set.
165 59
166 // Make hash<T> be the same as less<T>. Note that everywhere where custom 60 // Make hash<T> be the same as less<T>. Note that everywhere where custom
167 // hash functions are defined in the protobuf code, they are also defined such 61 // hash functions are defined in the protobuf code, they are also defined such
168 // that they can be used as "less" functions, which is required by MSVC anyway. 62 // that they can be used as "less" functions, which is required by MSVC anyway.
169 template <typename Key> 63 template <typename Key>
170 struct hash { 64 struct hash {
171 // Dummy, just to make derivative hash functions compile. 65 // Dummy, just to make derivative hash functions compile.
(...skipping 18 matching lines...) Expand all
190 84
191 inline bool operator()(const char* a, const char* b) const { 85 inline bool operator()(const char* a, const char* b) const {
192 return strcmp(a, b) < 0; 86 return strcmp(a, b) < 0;
193 } 87 }
194 }; 88 };
195 89
196 template <typename Key, typename Data, 90 template <typename Key, typename Data,
197 typename HashFcn = hash<Key>, 91 typename HashFcn = hash<Key>,
198 typename EqualKey = std::equal_to<Key>, 92 typename EqualKey = std::equal_to<Key>,
199 typename Alloc = std::allocator< std::pair<const Key, Data> > > 93 typename Alloc = std::allocator< std::pair<const Key, Data> > >
200 class hash_map : public std::map<Key, Data, HashFcn, Alloc> { 94 class hash_map : public std::map<Key, Data, HashFcn, EqualKey, Alloc> {
201 typedef std::map<Key, Data, HashFcn, Alloc> BaseClass;
202
203 public: 95 public:
204 hash_map(int a = 0, const HashFcn& b = HashFcn(), 96 hash_map(int = 0, const HashFcn& = HashFcn(), const EqualKey& = EqualKey(),
205 const EqualKey& c = EqualKey(), 97 const Alloc& = Alloc()) {}
206 const Alloc& d = Alloc()) : BaseClass(b, d) {}
207 }; 98 };
208 99
209 template <typename Key, 100 template <typename Key,
210 typename HashFcn = hash<Key>, 101 typename HashFcn = hash<Key>,
211 typename EqualKey = std::equal_to<Key> > 102 typename EqualKey = std::equal_to<Key> >
212 class hash_set : public std::set<Key, HashFcn> { 103 class hash_set : public std::set<Key, HashFcn> {
213 public: 104 public:
214 hash_set(int = 0) {} 105 hash_set(int = 0) {}
215 }; 106 };
216 107
217 #elif defined(_MSC_VER) && !defined(_STLPORT_VERSION) 108 #elif defined(_MSC_VER) && !defined(_STLPORT_VERSION)
218 109
219 template <typename Key> 110 template <typename Key>
220 struct hash : public GOOGLE_PROTOBUF_HASH_COMPARE<Key> { 111 struct hash : public GOOGLE_PROTOBUF_HASH_NAMESPACE::hash_compare<Key> {
221 }; 112 };
222 113
223 // MSVC's hash_compare<const char*> hashes based on the string contents but 114 // MSVC's hash_compare<const char*> hashes based on the string contents but
224 // compares based on the string pointer. WTF? 115 // compares based on the string pointer. WTF?
225 class CstringLess { 116 class CstringLess {
226 public: 117 public:
227 inline bool operator()(const char* a, const char* b) const { 118 inline bool operator()(const char* a, const char* b) const {
228 return strcmp(a, b) < 0; 119 return strcmp(a, b) < 0;
229 } 120 }
230 }; 121 };
231 122
232 template <> 123 template <>
233 struct hash<const char*> 124 struct hash<const char*>
234 : public GOOGLE_PROTOBUF_HASH_COMPARE<const char*, CstringLess> {}; 125 : public GOOGLE_PROTOBUF_HASH_NAMESPACE::hash_compare<
126 const char*, CstringLess> {};
235 127
236 template <typename Key, typename Data, 128 template <typename Key, typename Data,
237 typename HashFcn = hash<Key>, 129 typename HashFcn = hash<Key>,
238 typename EqualKey = std::equal_to<Key>, 130 typename EqualKey = std::equal_to<Key>,
239 typename Alloc = std::allocator< std::pair<const Key, Data> > > 131 typename Alloc = std::allocator< std::pair<const Key, Data> > >
240 class hash_map 132 class hash_map
241 : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< 133 : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
242 Key, Data, HashFcn, EqualKey, Alloc> { 134 Key, Data, HashFcn, EqualKey, Alloc> {
243 typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
244 Key, Data, HashFcn, EqualKey, Alloc> BaseClass;
245
246 public: 135 public:
247 hash_map(int a = 0, const HashFcn& b = HashFcn(), 136 hash_map(int = 0, const HashFcn& = HashFcn(), const EqualKey& = EqualKey(),
248 const EqualKey& c = EqualKey(), 137 const Alloc& = Alloc()) {}
249 const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {}
250 }; 138 };
251 139
252 template <typename Key, typename HashFcn = hash<Key>, 140 template <typename Key, typename HashFcn = hash<Key>,
253 typename EqualKey = std::equal_to<Key> > 141 typename EqualKey = std::equal_to<Key> >
254 class hash_set 142 class hash_set
255 : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS< 143 : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS<
256 Key, HashFcn, EqualKey> { 144 Key, HashFcn, EqualKey> {
257 public: 145 public:
258 hash_set(int = 0) {} 146 hash_set(int = 0) {}
259 }; 147 };
(...skipping 17 matching lines...) Expand all
277 struct hash<const char*> { 165 struct hash<const char*> {
278 inline size_t operator()(const char* str) const { 166 inline size_t operator()(const char* str) const {
279 size_t result = 0; 167 size_t result = 0;
280 for (; *str != '\0'; str++) { 168 for (; *str != '\0'; str++) {
281 result = 5 * result + *str; 169 result = 5 * result + *str;
282 } 170 }
283 return result; 171 return result;
284 } 172 }
285 }; 173 };
286 174
287 template<>
288 struct hash<bool> {
289 size_t operator()(bool x) const {
290 return static_cast<size_t>(x);
291 }
292 };
293
294 template <typename Key, typename Data, 175 template <typename Key, typename Data,
295 typename HashFcn = hash<Key>, 176 typename HashFcn = hash<Key>,
296 typename EqualKey = std::equal_to<Key>, 177 typename EqualKey = std::equal_to<Key>,
297 typename Alloc = std::allocator< std::pair<const Key, Data> > > 178 typename Alloc = std::allocator< std::pair<const Key, Data> > >
298 class hash_map 179 class hash_map
299 : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< 180 : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
300 Key, Data, HashFcn, EqualKey, Alloc> { 181 Key, Data, HashFcn, EqualKey, Alloc> {
301 typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
302 Key, Data, HashFcn, EqualKey, Alloc> BaseClass;
303
304 public: 182 public:
305 hash_map(int a = 0, const HashFcn& b = HashFcn(), 183 hash_map(int = 0, const HashFcn& = HashFcn(), const EqualKey& = EqualKey(),
306 const EqualKey& c = EqualKey(), 184 const Alloc& = Alloc()) {}
307 const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {}
308 }; 185 };
309 186
310 template <typename Key, typename HashFcn = hash<Key>, 187 template <typename Key, typename HashFcn = hash<Key>,
311 typename EqualKey = std::equal_to<Key> > 188 typename EqualKey = std::equal_to<Key> >
312 class hash_set 189 class hash_set
313 : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS< 190 : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS<
314 Key, HashFcn, EqualKey> { 191 Key, HashFcn, EqualKey> {
315 public: 192 public:
316 hash_set(int = 0) {} 193 hash_set(int = 0) {}
317 }; 194 };
318 195
196 #undef GOOGLE_PROTOBUF_MISSING_HASH
319 #endif // !GOOGLE_PROTOBUF_MISSING_HASH 197 #endif // !GOOGLE_PROTOBUF_MISSING_HASH
320 198
321 template <> 199 template <>
322 struct hash<string> { 200 struct hash<string> {
323 inline size_t operator()(const string& key) const { 201 inline size_t operator()(const string& key) const {
324 return hash<const char*>()(key.c_str()); 202 return hash<const char*>()(key.c_str());
325 } 203 }
326 204
327 static const size_t bucket_size = 4; 205 static const size_t bucket_size = 4;
328 static const size_t min_buckets = 8; 206 static const size_t min_buckets = 8;
329 inline bool operator()(const string& a, const string& b) const { 207 inline size_t operator()(const string& a, const string& b) const {
330 return a < b; 208 return a < b;
331 } 209 }
332 }; 210 };
333 211
334 template <typename First, typename Second> 212 template <typename First, typename Second>
335 struct hash<pair<First, Second> > { 213 struct hash<pair<First, Second> > {
336 inline size_t operator()(const pair<First, Second>& key) const { 214 inline size_t operator()(const pair<First, Second>& key) const {
337 size_t first_hash = hash<First>()(key.first); 215 size_t first_hash = hash<First>()(key.first);
338 size_t second_hash = hash<Second>()(key.second); 216 size_t second_hash = hash<Second>()(key.second);
339 217
340 // FIXME(kenton): What is the best way to compute this hash? I have 218 // FIXME(kenton): What is the best way to compute this hash? I have
341 // no idea! This seems a bit better than an XOR. 219 // no idea! This seems a bit better than an XOR.
342 return first_hash * ((1 << 16) - 1) + second_hash; 220 return first_hash * ((1 << 16) - 1) + second_hash;
343 } 221 }
344 222
345 static const size_t bucket_size = 4; 223 static const size_t bucket_size = 4;
346 static const size_t min_buckets = 8; 224 static const size_t min_buckets = 8;
347 inline bool operator()(const pair<First, Second>& a, 225 inline size_t operator()(const pair<First, Second>& a,
348 const pair<First, Second>& b) const { 226 const pair<First, Second>& b) const {
349 return a < b; 227 return a < b;
350 } 228 }
351 }; 229 };
352 230
353 // Used by GCC/SGI STL only. (Why isn't this provided by the standard 231 // Used by GCC/SGI STL only. (Why isn't this provided by the standard
354 // library? :( ) 232 // library? :( )
355 struct streq { 233 struct streq {
356 inline bool operator()(const char* a, const char* b) const { 234 inline bool operator()(const char* a, const char* b) const {
357 return strcmp(a, b) == 0; 235 return strcmp(a, b) == 0;
358 } 236 }
359 }; 237 };
360 238
361 } // namespace protobuf 239 } // namespace protobuf
362 } // namespace google 240 } // namespace google
363 241
364 #endif // GOOGLE_PROTOBUF_STUBS_HASH_H__ 242 #endif // GOOGLE_PROTOBUF_STUBS_HASH_H__
OLDNEW
« no previous file with comments | « third_party/protobuf/src/google/protobuf/stubs/fastmem.h ('k') | third_party/protobuf/src/google/protobuf/stubs/logging.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698