pairinteraction
A Rydberg Interaction Calculator
hash.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2024 Pairinteraction Developers
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4#pragma once
5
6#include <array>
7#include <complex>
8#include <functional>
9#include <vector>
10
11namespace pairinteraction::utils {
12
13/**
14 * @struct hash
15 *
16 * @brief Hash function
17 *
18 * The `std::hash` template allows specialization but only for types that are
19 * not in the standard library. This means that we cannot specialize
20 * `std::hash` for, e.g. `std::array`. To this end we define a struct `hash`
21 * which just inherits from `std::hash` by default.
22 *
23 * @tparam T type to be hashed
24 */
25
26template <typename T>
27struct hash;
28
29/**
30 * @function hash_combine
31 *
32 * @brief Combine hashes
33 *
34 * The implementation of `hash_combine` is copied from Boost but simplified.
35 *
36 * @param seed start hash
37 * @param v value whose hash is to be added to \p seed
38 *
39 * @tparam T type to be hashed
40 */
41
42template <typename T>
43inline void hash_combine(std::size_t &seed, T const &v) {
44 hash<T> hasher;
45 seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
46}
47
48/**
49 * @function hash_range
50 *
51 * @brief Combine hashes of values in a range
52 *
53 * @param first forward iterator
54 * @param last forward iterator
55 *
56 * @return combined hash
57 *
58 * @tparam It forward iterator
59 */
60
61template <typename It>
62inline std::size_t hash_range(It first, It last) {
63 std::size_t seed = 0;
64 for (; first != last; ++first) {
65 hash_combine(seed, *first);
66 }
67 return seed;
68}
69
70// By default use std::hash
71template <typename T>
72struct hash : std::hash<T> {};
73
74// Specializations for other types
75template <typename T, std::size_t N>
76struct hash<std::array<T, N>> {
77 std::size_t operator()(std::array<T, N> const &a) const {
78 return hash_range(a.begin(), a.end());
79 }
80};
81
82template <typename T>
83struct hash<std::vector<T>> {
84 std::size_t operator()(std::vector<T> const &v) const { return hash_range(v.begin(), v.end()); }
85};
86
87template <typename T>
88struct hash<std::complex<T>> {
89 std::size_t operator()(std::complex<T> const &c) const {
90 std::size_t seed = 0;
91 hash_combine(seed, c.real());
92 hash_combine(seed, c.imag());
93 return seed;
94 }
95};
96
97enum class Parity : int;
98
99template <>
100struct hash<Parity> {
101 std::size_t operator()(const Parity &parity) const {
102 return std::hash<char>{}(static_cast<char>(parity));
103 }
104};
105
106} // namespace pairinteraction::utils
void hash_combine(std::size_t &seed, T const &v)
Combine hashes.
Definition: hash.hpp:43
std::size_t hash_range(It first, It last)
Combine hashes of values in a range.
Definition: hash.hpp:62
std::size_t operator()(const Parity &parity) const
Definition: hash.hpp:101
std::size_t operator()(std::array< T, N > const &a) const
Definition: hash.hpp:77
std::size_t operator()(std::complex< T > const &c) const
Definition: hash.hpp:89
std::size_t operator()(std::vector< T > const &v) const
Definition: hash.hpp:84
Hash function.
Definition: hash.hpp:72