webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
hash.h
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 //
33 // Deals with the fact that hash_map is not defined everywhere.
34 
35 #ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__
36 #define GOOGLE_PROTOBUF_STUBS_HASH_H__
37 
38 #include <string.h>
40 
41 #define GOOGLE_PROTOBUF_HAVE_HASH_MAP 1
42 #define GOOGLE_PROTOBUF_HAVE_HASH_SET 1
43 
44 // Android
45 #if defined(__ANDROID__)
46 # undef GOOGLE_PROTOBUF_HAVE_HASH_MAP
47 # undef GOOGLE_PROTOBUF_HAVE_HASH_MAP
48 
49 // Use C++11 unordered_{map|set} if available.
50 #elif ((_LIBCPP_STD_VER >= 11) || \
51  (((__cplusplus >= 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X)) && \
52  (__GLIBCXX__ > 20090421)))
53 # define GOOGLE_PROTOBUF_HAS_CXX11_HASH
54 
55 // For XCode >= 4.6: the compiler is clang with libc++.
56 // For earlier XCode version: the compiler is gcc-4.2.1 with libstdc++.
57 // libc++ provides <unordered_map> and friends even in non C++11 mode,
58 // and it does not provide the tr1 library. Therefore the following macro
59 // checks against this special case.
60 // Note that we should not test the __APPLE_CC__ version number or the
61 // __clang__ macro, since the new compiler can still use -stdlib=libstdc++, in
62 // which case <unordered_map> is not compilable without -std=c++11
63 #elif defined(__APPLE_CC__)
64 # if __GNUC__ >= 4
65 # define GOOGLE_PROTOBUF_HAS_TR1
66 # else
67 // Not tested for gcc < 4... These setting can compile under 4.2.1 though.
68 # define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx
69 # include <ext/hash_map>
70 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
71 # include <ext/hash_set>
72 # define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
73 # endif
74 
75 // Version checks for gcc.
76 #elif defined(__GNUC__)
77 // For GCC 4.x+, use tr1::unordered_map/set; otherwise, follow the
78 // instructions from:
79 // https://gcc.gnu.org/onlinedocs/libstdc++/manual/backwards.html
80 # if __GNUC__ >= 4
81 # define GOOGLE_PROTOBUF_HAS_TR1
82 # elif __GNUC__ >= 3
83 # include <backward/hash_map>
84 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
85 # include <backward/hash_set>
86 # define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
87 # if __GNUC__ == 3 && __GNUC_MINOR__ == 0
88 # define GOOGLE_PROTOBUF_HASH_NAMESPACE std // GCC 3.0
89 # else
90 # define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx // GCC 3.1 and later
91 # endif
92 # else
93 # define GOOGLE_PROTOBUF_HASH_NAMESPACE
94 # include <hash_map>
95 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
96 # include <hash_set>
97 # define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
98 # endif
99 
100 // Version checks for MSC.
101 // Apparently Microsoft decided to move hash_map *back* to the std namespace in
102 // MSVC 2010:
103 // http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
104 // And.. they are moved back to stdext in MSVC 2013 (haven't checked 2012). That
105 // said, use unordered_map for MSVC 2010 and beyond is our safest bet.
106 #elif defined(_MSC_VER)
107 # if _MSC_VER >= 1600 // Since Visual Studio 2010
108 # define GOOGLE_PROTOBUF_HAS_CXX11_HASH
109 # define GOOGLE_PROTOBUF_HASH_COMPARE std::hash_compare
110 # elif _MSC_VER >= 1500 // Since Visual Studio 2008
111 # define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext
112 # include <hash_map>
113 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
114 # include <hash_set>
115 # define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
116 # define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
117 # define GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE
118 # elif _MSC_VER >= 1310
119 # define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext
120 # include <hash_map>
121 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
122 # include <hash_set>
123 # define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
124 # define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
125 # else
126 # define GOOGLE_PROTOBUF_HASH_NAMESPACE std
127 # include <hash_map>
128 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
129 # include <hash_set>
130 # define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
131 # define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
132 # endif
133 
134 // **ADD NEW COMPILERS SUPPORT HERE.**
135 // For other compilers, undefine the macro and fallback to use std::map, in
136 // google/protobuf/stubs/hash.h
137 #else
138 # undef GOOGLE_PROTOBUF_HAVE_HASH_MAP
139 # undef GOOGLE_PROTOBUF_HAVE_HASH_SET
140 #endif
141 
142 #if defined(GOOGLE_PROTOBUF_HAS_CXX11_HASH)
143 # define GOOGLE_PROTOBUF_HASH_NAMESPACE std
144 # include <unordered_map>
145 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
146 # include <unordered_set>
147 # define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
148 #elif defined(GOOGLE_PROTOBUF_HAS_TR1)
149 # define GOOGLE_PROTOBUF_HASH_NAMESPACE std::tr1
150 # include <tr1/unordered_map>
151 # define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
152 # include <tr1/unordered_set>
153 # define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
154 #endif
155 
156 # define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START \
157  namespace google { \
158  namespace protobuf {
159 # define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END }}
160 
161 #undef GOOGLE_PROTOBUF_HAS_CXX11_HASH
162 #undef GOOGLE_PROTOBUF_HAS_TR1
163 
164 #if defined(GOOGLE_PROTOBUF_HAVE_HASH_MAP) && \
165  defined(GOOGLE_PROTOBUF_HAVE_HASH_SET)
166 #else
167 #define GOOGLE_PROTOBUF_MISSING_HASH
168 #include <map>
169 #include <set>
170 #endif
171 
172 namespace google {
173 namespace protobuf {
174 
175 #ifdef GOOGLE_PROTOBUF_MISSING_HASH
176 #undef GOOGLE_PROTOBUF_MISSING_HASH
177 
178 // This system doesn't have hash_map or hash_set. Emulate them using map and
179 // set.
180 
181 // Make hash<T> be the same as less<T>. Note that everywhere where custom
182 // hash functions are defined in the protobuf code, they are also defined such
183 // that they can be used as "less" functions, which is required by MSVC anyway.
184 template <typename Key>
185 struct hash {
186  // Dummy, just to make derivative hash functions compile.
187  int operator()(const Key& key) {
188  GOOGLE_LOG(FATAL) << "Should never be called.";
189  return 0;
190  }
191 
192  inline bool operator()(const Key& a, const Key& b) const {
193  return a < b;
194  }
195 };
196 
197 // Make sure char* is compared by value.
198 template <>
199 struct hash<const char*> {
200  // Dummy, just to make derivative hash functions compile.
201  int operator()(const char* key) {
202  GOOGLE_LOG(FATAL) << "Should never be called.";
203  return 0;
204  }
205 
206  inline bool operator()(const char* a, const char* b) const {
207  return strcmp(a, b) < 0;
208  }
209 };
210 
211 template <typename Key, typename Data,
212  typename HashFcn = hash<Key>,
213  typename EqualKey = std::equal_to<Key>,
214  typename Alloc = std::allocator< std::pair<const Key, Data> > >
215 class hash_map : public std::map<Key, Data, HashFcn, Alloc> {
216  typedef std::map<Key, Data, HashFcn, Alloc> BaseClass;
217 
218  public:
219  hash_map(int a = 0, const HashFcn& b = HashFcn(),
220  const EqualKey& c = EqualKey(),
221  const Alloc& d = Alloc()) : BaseClass(b, d) {}
222 
223  HashFcn hash_function() const { return HashFcn(); }
224 };
225 
226 template <typename Key,
227  typename HashFcn = hash<Key>,
228  typename EqualKey = std::equal_to<Key> >
229 class hash_set : public std::set<Key, HashFcn> {
230  public:
231  hash_set(int = 0) {}
232 
233  HashFcn hash_function() const { return HashFcn(); }
234 };
235 
236 #elif defined(_MSC_VER) && !defined(_STLPORT_VERSION)
237 
238 template <typename Key>
239 struct hash : public GOOGLE_PROTOBUF_HASH_COMPARE<Key> {
240 };
241 
242 // MSVC's hash_compare<const char*> hashes based on the string contents but
243 // compares based on the string pointer. WTF?
244 class CstringLess {
245  public:
246  inline bool operator()(const char* a, const char* b) const {
247  return strcmp(a, b) < 0;
248  }
249 };
250 
251 template <>
252 struct hash<const char*>
253  : public GOOGLE_PROTOBUF_HASH_COMPARE<const char*, CstringLess> {};
254 
255 #ifdef GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE
256 
257 template <typename Key, typename HashFcn, typename EqualKey>
258 struct InternalHashCompare : public GOOGLE_PROTOBUF_HASH_COMPARE<Key> {
259  InternalHashCompare() {}
260  InternalHashCompare(HashFcn hashfcn, EqualKey equalkey)
261  : hashfcn_(hashfcn), equalkey_(equalkey) {}
262  size_t operator()(const Key& key) const { return hashfcn_(key); }
263  bool operator()(const Key& key1, const Key& key2) const {
264  return !equalkey_(key1, key2);
265  }
266  HashFcn hashfcn_;
267  EqualKey equalkey_;
268 };
269 
270 template <typename Key, typename Data,
271  typename HashFcn = hash<Key>,
272  typename EqualKey = std::equal_to<Key>,
273  typename Alloc = std::allocator< std::pair<const Key, Data> > >
274 class hash_map
275  : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
276  Key, Data, InternalHashCompare<Key, HashFcn, EqualKey>, Alloc> {
277  typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
278  Key, Data, InternalHashCompare<Key, HashFcn, EqualKey>, Alloc> BaseClass;
279 
280  public:
281  hash_map(int a = 0, const HashFcn& b = HashFcn(),
282  const EqualKey& c = EqualKey(), const Alloc& d = Alloc())
283  : BaseClass(InternalHashCompare<Key, HashFcn, EqualKey>(b, c), d) {}
284 
285  HashFcn hash_function() const { return HashFcn(); }
286 };
287 
288 template <typename Key, typename HashFcn = hash<Key>,
289  typename EqualKey = std::equal_to<Key> >
290 class hash_set
291  : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS<
292  Key, InternalHashCompare<Key, HashFcn, EqualKey> > {
293  public:
294  hash_set(int = 0) {}
295 
296  HashFcn hash_function() const { return HashFcn(); }
297 };
298 
299 #else // GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE
300 
301 template <typename Key, typename Data,
302  typename HashFcn = hash<Key>,
303  typename EqualKey = std::equal_to<Key>,
304  typename Alloc = std::allocator< std::pair<const Key, Data> > >
305 class hash_map
306  : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
307  Key, Data, HashFcn, EqualKey, Alloc> {
308  typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
309  Key, Data, HashFcn, EqualKey, Alloc> BaseClass;
310 
311  public:
312  hash_map(int a = 0, const HashFcn& b = HashFcn(),
313  const EqualKey& c = EqualKey(),
314  const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {}
315 
316  HashFcn hash_function() const { return HashFcn(); }
317 };
318 
319 template <typename Key, typename HashFcn = hash<Key>,
320  typename EqualKey = std::equal_to<Key> >
321 class hash_set
322  : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS<
323  Key, HashFcn, EqualKey> {
324  public:
325  hash_set(int = 0) {}
326 
327  HashFcn hash_function() const { return HashFcn(); }
328 };
329 #endif // GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE
330 
331 #else // defined(_MSC_VER) && !defined(_STLPORT_VERSION)
332 
333 template <typename Key>
334 struct hash : public GOOGLE_PROTOBUF_HASH_NAMESPACE::hash<Key> {
335 };
336 
337 template <typename Key>
338 struct hash<const Key*> {
339  inline size_t operator()(const Key* key) const {
340  return reinterpret_cast<size_t>(key);
341  }
342 };
343 
344 // Unlike the old SGI version, the TR1 "hash" does not special-case char*. So,
345 // we go ahead and provide our own implementation.
346 template <>
347 struct hash<const char*> {
348  inline size_t operator()(const char* str) const {
349  size_t result = 0;
350  for (; *str != '\0'; str++) {
351  result = 5 * result + *str;
352  }
353  return result;
354  }
355 };
356 
357 template<>
358 struct hash<bool> {
359  size_t operator()(bool x) const {
360  return static_cast<size_t>(x);
361  }
362 };
363 
364 template <typename Key, typename Data,
365  typename HashFcn = hash<Key>,
366  typename EqualKey = std::equal_to<Key>,
367  typename Alloc = std::allocator< std::pair<const Key, Data> > >
368 class hash_map
369  : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
370  Key, Data, HashFcn, EqualKey, Alloc> {
371  typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
372  Key, Data, HashFcn, EqualKey, Alloc> BaseClass;
373 
374  public:
375  hash_map(int a = 0, const HashFcn& b = HashFcn(),
376  const EqualKey& c = EqualKey(),
377  const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {}
378 
379  HashFcn hash_function() const { return HashFcn(); }
380 };
381 
382 template <typename Key, typename HashFcn = hash<Key>,
383  typename EqualKey = std::equal_to<Key> >
384 class hash_set
385  : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS<
386  Key, HashFcn, EqualKey> {
387  public:
388  hash_set(int = 0) {}
389 
390  HashFcn hash_function() const { return HashFcn(); }
391 };
392 
393 #endif // !GOOGLE_PROTOBUF_MISSING_HASH
394 
395 template <>
396 struct hash<string> {
397  inline size_t operator()(const string& key) const {
398  return hash<const char*>()(key.c_str());
399  }
400 
401  static const size_t bucket_size = 4;
402  static const size_t min_buckets = 8;
403  inline bool operator()(const string& a, const string& b) const {
404  return a < b;
405  }
406 };
407 
408 template <typename First, typename Second>
409 struct hash<pair<First, Second> > {
410  inline size_t operator()(const pair<First, Second>& key) const {
411  size_t first_hash = hash<First>()(key.first);
412  size_t second_hash = hash<Second>()(key.second);
413 
414  // FIXME(kenton): What is the best way to compute this hash? I have
415  // no idea! This seems a bit better than an XOR.
416  return first_hash * ((1 << 16) - 1) + second_hash;
417  }
418 
419  static const size_t bucket_size = 4;
420  static const size_t min_buckets = 8;
421  inline bool operator()(const pair<First, Second>& a,
422  const pair<First, Second>& b) const {
423  return a < b;
424  }
425 };
426 
427 // Used by GCC/SGI STL only. (Why isn't this provided by the standard
428 // library? :( )
429 struct streq {
430  inline bool operator()(const char* a, const char* b) const {
431  return strcmp(a, b) == 0;
432  }
433 };
434 
435 } // namespace protobuf
436 } // namespace google
437 
438 #endif // GOOGLE_PROTOBUF_STUBS_HASH_H__
hash_set(int=0)
Definition: hash.h:231
size_t operator()(const string &key) const
Definition: hash.h:397
int operator()(const Key &key)
Definition: hash.h:187
required HashAlgorithmIdentifier hash
Definition: WebCryptoAPI.idl:276
int c
Definition: cpp_unittests.cpp:275
#define GOOGLE_LOG(LEVEL)
Definition: logging.h:144
typename detail::make_map< Ts... >::type map
Definition: Brigand.h:223
HashFcn hash_function() const
Definition: hash.h:233
hash_map(int a=0, const HashFcn &b=HashFcn(), const EqualKey &c=EqualKey(), const Alloc &d=Alloc())
Definition: hash.h:219
int operator()(const char *key)
Definition: hash.h:201
size_t operator()(const pair< First, Second > &key) const
Definition: hash.h:410
bool operator()(const string &a, const string &b) const
Definition: hash.h:403
EGLSurface EGLint x
Definition: eglext.h:950
Definition: hash.h:429
HashFcn hash_function() const
Definition: hash.h:223
bool operator()(const Key &a, const Key &b) const
Definition: hash.h:192
Definition: RTCStatsReport.idl:41
#define FATAL(...)
Definition: Assertions.h:388
bool operator()(const char *a, const char *b) const
Definition: hash.h:206
bool operator()(const char *a, const char *b) const
Definition: hash.h:430
Definition: __init__.py:1
GLboolean GLboolean GLboolean GLboolean a
Definition: gl2ext.h:306
EGLSetBlobFuncANDROID set
Definition: eglext.h:426
Definition: hash.h:229
str
Definition: make-dist.py:305
GLsizei const GLchar *const * string
Definition: gl2.h:479
result
Definition: target-blank-opener-post-window.php:5
Definition: hash.h:215
bool operator()(const pair< First, Second > &a, const pair< First, Second > &b) const
Definition: hash.h:421
const
Definition: upload.py:398
Key
Definition: keyboard.h:10
GLboolean GLboolean GLboolean b
Definition: gl2ext.h:306
Definition: gflags_completions.h:115
Definition: hash.h:185
CFArrayRef CFTypeRef key
Definition: AVFoundationCFSoftLinking.h:129
Definition: WebKitWebViewSessionState.cpp:89
#define d
Definition: float-mm.c:30
const uint16_t key1[47]
Definition: auth_driver.c:64