MADNESS  version 0.9
worldhash.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 
31 
32  $Id$
33 */
34 
35 
36 #ifndef MADNESS_WORLD_WORLDHASH_H__INCLUDED
37 #define MADNESS_WORLD_WORLDHASH_H__INCLUDED
38 
130 #include <madness/madness_config.h>
131 #include <madness/world/typestuff.h>
132 #include <madness/world/enable_if.h>
133 #include <stdint.h>
134 #include <cstddef>
135 #include <iterator>
136 
137 // Bob Jenkin's "lookup v3" hash from http://www.burtleburtle.net/bob/c/lookup3.c.
138 extern "C" {
139  uint32_t hashword(const uint32_t *k, size_t length, uint32_t initval);
140  uint32_t hashlittle(const void *key, size_t length, uint32_t initval);
141 }
142 
143 namespace madness {
144 
145  // Hash, hash_value, hash_combine, and hash_range a la Boost.
146 
148  typedef std::size_t hashT;
149 
151 
157  template <class T>
159  ((sizeof(T)%sizeof(uint32_t)) == 0),
160  hashT>::type
161  hash_value(const T t) {
162  hashT result = 0ul;
163  result = hashword(reinterpret_cast<const uint32_t*>(&t),
164  std::integral_constant<std::size_t,sizeof(T)/sizeof(uint32_t)>::value, 0u);
165  return result;
166  }
167 
169 
173  template <class T>
175  ((sizeof(T)%sizeof(uint32_t)) != 0),
176  hashT>::type
177  hash_value(const T t) {
178  hashT result = 0ul;
179  result = hashlittle(reinterpret_cast<const void*>(&t), sizeof(T), 0u);
180  return result;
181  }
182 
184 
188  template <typename T>
189  inline hashT hash_value(const T* t) {
190  const unsigned long n = reinterpret_cast<unsigned long>(t);
191  return hash_value(n);
192  }
193 
195 
199  template <typename T>
200  inline typename enable_if_c<!(std::is_fundamental<T>::value ||
202  hash_value(const T& t) {
203  return t.hash();
204  }
205 
207 
211  template <typename T>
212  inline hashT hash_value(const std::basic_string<T>& t) {
213  return hash_range(t.c_str(), t.size());
214  }
215 
217 
231  template <typename T>
232  struct Hash {
233 
235 
238  hashT operator()(const T& t) const {
239  return hash_value(t);
240  }
241  }; // struct Hash
242 
243  namespace detail {
245  // We don't hash anything here. It is just used for combining a hashed
246  // value with a seed.
247  inline void combine_hash(hashT& seed, hashT hash) {
248  seed ^= hash + 0x9e3779b9 + (seed<<6) + (seed>>2);
249  }
250  }
251 
253 
258  template <class T>
259  inline void hash_combine(hashT& seed, const T& v) {
260  Hash<T> hasher;
261  detail::combine_hash(seed, hasher(v));
262  }
263 
265 
270  template <class It>
271  inline void hash_range(hashT& seed, It first, It last) {
273  for(; first != last; ++first)
274  detail::combine_hash(seed, hasher(*first));
275  }
276 
278 
283  template <class It>
284  inline hashT hash_range(It first, It last) {
285  hashT seed = 0;
286  hash_range(seed, first, last);
287 
288  return seed;
289  }
290 
292 
297  template <class T, std::size_t n>
298  inline hashT hash_range(const T(&t)[n]) {
299  return hash_range(t, n);
300  }
301 
303 
309  template <class T, std::size_t n>
310  inline void hash_range(hashT& seed, const T(&t)[n]) {
311  hash_range(seed, t, n);
312  }
313 
315 
322  template <class T>
323  inline typename enable_if<std::is_fundamental<T> >::type
324  hash_range(hashT& seed, const T* t, std::size_t n) {
325  const std::size_t bytes = n * sizeof(T);
326  if((bytes % sizeof(uint32_t)) == 0)
327  seed = hashword(reinterpret_cast<const uint32_t *>(t), bytes/sizeof(uint32_t), seed);
328  else
329  seed = hashlittle(static_cast<const void *>(t), bytes, seed);
330  }
331 
333 
338  template <class T>
339  inline typename disable_if<std::is_fundamental<T> >::type
340  hash_range(hashT& seed, const T* t, std::size_t n) {
341  hash_range(seed, t, t + n);
342  }
343 
345 
350  template <class T>
351  inline hashT hash_range(const T* t, std::size_t n) {
352  hashT seed = 0ul;
353  hash_range(seed, t, n);
354  return seed;
355  }
356 
357 } // namespace madness
358 
359 
360 #endif // MADNESS_WORLD_WORLDHASH_H__INCLUDED
uint32_t hashword(const uint32_t *k, size_t length, uint32_t initval)
Definition: lookup3.c:177
Grossly simplified Boost-like type traits and templates.
hashT operator()(const T &t) const
Hashing function wrapper.
Definition: worldhash.h:238
is_pointer::value will be true if T is a pointer type
Definition: type_traits_bits.h:69
const T1 &f1 return GTEST_2_TUPLE_() T(f0, f1)
void combine_hash(hashT &seed, hashT hash)
Internal use only.
Definition: worldhash.h:247
uint32_t hashlittle(const void *key, size_t length, uint32_t initval)
Definition: lookup3.c:240
void hash_range(hashT &seed, It first, It last)
Combine the hash values of an iterator range.
Definition: worldhash.h:271
madness::hashT hash_value(const std::array< T, N > &a)
Hash std::array with madness::Hash.
Definition: array.h:62
void hash_combine(hashT &seed, const T &v)
Combine hash values.
Definition: worldhash.h:259
enable_if_c from Boost for conditionally instantiating templates based on type
Definition: enable_if.h:46
std::size_t hashT
The hash value type.
Definition: worldhash.h:148
Definition: integral_constant.h:7
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
is_array::value will be true if T is an array type
Definition: type_traits_bits.h:61
Hash functor.
Definition: shared_ptr_bits.h:32