File: vtkHashCombiner.h

package info (click to toggle)
vtk9 9.5.2%2Bdfsg4-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 206,640 kB
  • sloc: cpp: 2,340,827; ansic: 327,116; python: 114,881; yacc: 4,104; java: 3,977; sh: 3,032; xml: 2,771; perl: 2,189; lex: 1,787; javascript: 1,261; makefile: 194; objc: 153; tcl: 59
file content (69 lines) | stat: -rw-r--r-- 1,898 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
/**
 * @class   vtkHashCombiner
 * @brief   Combine 4- and 8-byte integers into a single hash value.
 *
 * This templated class accepts one 4- or 8-byte integer
 * and combines it with an existing hash. It is useful for
 * combining hashes of strings with integer values such as
 * connectivity entries for shape primitives.
 *
 * This class was adapted from (i.e., uses the integer constants from)
 * boost::hash_combine but adds the templating on input value sizes.
 *
 * \sa vtkCellGridSidesQuery for an example of its use.
 */

#ifndef vtkHashCombiner_h
#define vtkHashCombiner_h

#include "vtkCommonCoreModule.h" // For export macro

#include <cstdint> // For uint32_t.

VTK_ABI_NAMESPACE_BEGIN

class VTKCOMMONCORE_EXPORT VTK_WRAPEXCLUDE vtkHashCombiner
{
public:
  /// Combine an integer \a k with the 64-bit hash \a h (which is modified on exit).
  template <typename T>
  void operator()(T& h, typename std::enable_if<sizeof(T) == 8, std::size_t>::type k)
  {
    constexpr T m = 0xc6a4a7935bd1e995ull;
    constexpr int r = 47;

    k *= m;
    k ^= k >> r;
    k *= m;

    h ^= k;
    h *= m;

    // Completely arbitrary number, to prevent 0's
    // from hashing to 0.
    h += 0xe6546b64;
  }

  /// Combine an integer \a k with the 32-bit hash \a h (which is modified on exit).
  template <typename T>
  void operator()(T& h, typename std::enable_if<sizeof(T) == 4, std::size_t>::type k)
  {
    constexpr std::uint32_t c1 = 0xcc9e2d51;
    constexpr std::uint32_t c2 = 0x1b873593;
    constexpr std::uint32_t r1 = 15;
    constexpr std::uint32_t r2 = 13;

    k *= c1;
    k = (k << r1) | (k >> (32 - r1));
    k *= c2;

    h ^= k;
    h = (h << r2) | (h >> (32 - r2));
    h = h * 5 + 0xe6546b64;
  }
};

VTK_ABI_NAMESPACE_END
#endif // vtkHashCombiner_h