carl  24.04
Computer ARithmetic Library
hash.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <utility>
4 #include <vector>
5 #include <set>
6 
7 namespace carl {
8 
9 /**
10  * Add a value to the given hash seed.
11  * This method is a copy of boost::hash_combine().
12  * It is reimplemented here to avoid including all of boost/functional/hash.hpp for this single line of code.
13  */
14 inline void hash_combine(std::size_t& seed, std::size_t value) {
15  seed ^= value + 0x9e3779b9 + (seed<<6u) + (seed>>2u);
16 }
17 
18 /**
19  * Add hash of the given value to the hash seed.
20  * Used `hash_combine` with the result of `std::hash<T>`.
21  */
22 template<typename T>
23 inline void hash_add(std::size_t& seed, const T& value) {
24  carl::hash_combine(seed, std::hash<T>()(value));
25 }
26 
27 /**
28  * Add hash of the given value to the hash seed.
29  */
30 template<>
31 inline void hash_add(std::size_t& seed, const std::size_t& value) {
32  carl::hash_combine(seed, value);
33 }
34 
35 /**
36  * Add hash of both elements of a `std::pair` to the seed.
37  */
38 template<typename T1, typename T2>
39 inline void hash_add(std::size_t& seed, const std::pair<T1, T2>& p) {
40  carl::hash_add(seed, p.first);
41  carl::hash_add(seed, p.second);
42 }
43 
44 /**
45  * Add hash of all elements of a `std::vector` to the seed.
46  */
47 template<typename T>
48 inline void hash_add(std::size_t& seed, const std::vector<T>& v) {
49  for (const auto& t: v) carl::hash_add(seed, t);
50 }
51 
52 template<typename T>
53 inline void hash_add(std::size_t& seed, const std::set<T>& s) {
54  for (const auto& t: s) carl::hash_add(seed, t);
55 }
56 
57 /**
58  * Variadic version of `hash_add` to add an arbitrary number of values to the seed.
59  */
60 template<typename First, typename... Tail>
61 inline void hash_add(std::size_t& seed, const First& value, Tail&&... tail) {
62  carl::hash_add(seed, value);
63  carl::hash_add(seed, std::forward<Tail>(tail)...);
64 }
65 
66 /**
67  * Hashes an arbitrary number of values.
68  * Uses `hash_add` with a seed of `0`.
69  */
70 template<typename... Args>
71 inline std::size_t hash_all(Args&&... args) {
72  std::size_t seed = 0;
73  hash_add(seed, std::forward<Args>(args)...);
74  return seed;
75 }
76 
77 /**
78  * Utility functor to hash a sequence of object using an output iterator.
79  */
80 template<typename T>
81 struct hash_inserter {
82  using difference_type = void;
83  using pointer = void;
84  using reference = void;
85  using value_type = void;
86  using iterator_category = std::output_iterator_tag;
87 
88  std::size_t& seed;
89  hash_inserter& operator=(const T& t) {
90  hash_add(seed, t);
91  return *this;
92  }
93  hash_inserter& operator*() { return *this; }
94  hash_inserter& operator++() { return *this; }
95  const hash_inserter operator++(int) { return *this; }
96 };
97 
98 } // namespace carl
carl is the main namespace for the library.
std::size_t hash_all(Args &&... args)
Hashes an arbitrary number of values.
Definition: hash.h:71
void hash_combine(std::size_t &seed, std::size_t value)
Add a value to the given hash seed.
Definition: hash.h:14
void hash_add(std::size_t &seed, const T &value)
Add hash of the given value to the hash seed.
Definition: hash.h:23
Utility functor to hash a sequence of object using an output iterator.
Definition: hash.h:81
std::size_t & seed
Definition: hash.h:88
std::output_iterator_tag iterator_category
Definition: hash.h:86
void difference_type
Definition: hash.h:82
void value_type
Definition: hash.h:85
hash_inserter & operator++()
Definition: hash.h:94
const hash_inserter operator++(int)
Definition: hash.h:95
hash_inserter & operator*()
Definition: hash.h:93
hash_inserter & operator=(const T &t)
Definition: hash.h:89
void reference
Definition: hash.h:84