HashingUtil.h
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package RobotComponents
19 * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
20 * @date 2015
21 * @copyright http://www.gnu.org/licenses/gpl.txt
22 * GNU General Public License
23 */
24#pragma once
25
26#include <functional>
27
28#include <boost/functional/hash.hpp>
29
30//include "Preprocessor.h"
31
32
33/**
34 * @brief Expands to it's input.
35 */
36#define ARMARX_IDENTITY(...) __VA_ARGS__
37
38/**
39 * @brief Strips the parentheses of an input.
40 */
41#define ARMARX_STRIP_PARENTHESES(X) ARMARX_IDENTITY X
42
43/**
44 *@brief Overloads the std::hash template for Type.
45 * If the hash value of type foo depends on the members a and b the call has to be:
46 * ARMARX_OVERLOAD_STD_HASH((foo), (arg.a, arg.b))
47 * The parentheses are required!
48 */
49#define ARMARX_OVERLOAD_STD_HASH(Type, Members) \
50 namespace std \
51 { \
52 template <> \
53 struct hash<ARMARX_STRIP_PARENTHESES(Type)> \
54 { \
55 using argument_type = ARMARX_STRIP_PARENTHESES(Type); \
56 using result_type = std::size_t; \
57 result_type \
58 operator()(argument_type const& arg) const \
59 { \
60 return armarx::hash_all(ARMARX_STRIP_PARENTHESES(Members)); \
61 } \
62 }; \
63 }
64
65/**
66 *@brief Overloads the std::hash template for a type Type with the member functions begin() and end().
67 * If the type depends on some template parameters they can be passed as the first argument.
68 * The parentheses around both arguments are required!
69 *
70 * examples:
71 * for vector<int, AllocatorType> : ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((), (vector<int, AllocatorType>))
72 * for all vectors: ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class A), (vector<T, A>))
73 */
74#define ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE(TemplateArgs, Type) \
75 namespace std \
76 { \
77 template <ARMARX_STRIP_PARENTHESES(TemplateArgs)> \
78 struct hash<ARMARX_STRIP_PARENTHESES(Type)> \
79 { \
80 using argument_type = ARMARX_STRIP_PARENTHESES(Type); \
81 using result_type = std::size_t; \
82 result_type \
83 operator()(argument_type const& arg) const \
84 { \
85 return boost::hash_range(arg.begin(), arg.end()); \
86 } \
87 }; \
88 }
89
90namespace armarx
91{
92 /**
93 * @brief Combines the accumulated hash and the parameters hash.
94 * @param hashed The accumulated hash.
95 * @param t0 The value to hash.
96 */
97 template <class T0>
98 void
99 do_hash(std::size_t& hashed, const T0& t0)
100 {
101 //replace this call to change combination methode of hash values and the used hash function
102 //(currently uses boost::hash_value)
103 boost::hash_combine(hashed, t0);
104 }
105
106 /**
107 * @brief Combines the accumulated hash and the parameters hash.
108 * @param hashed The accumulated hash.
109 * @param t0 The first value to hash.
110 * @param ts Further values to hash.
111 */
112 template <class T0, class... Ts>
113 void
114 do_hash(std::size_t& hashed, const T0& t0, const Ts&... ts)
115 {
116 do_hash(hashed, t0);
117 do_hash(hashed, ts...);
118 }
119
120 /**
121 * @brief Returns the hash of all parameters.
122 * @param ts The parameters to hash
123 * @return The hash of all parameters.
124 */
125 template <class... Ts>
126 std::size_t
127 hash_all(const Ts&... ts)
128 {
129 std::size_t hashed = 0;
130 do_hash(hashed, ts...);
131 return hashed;
132 }
133} // namespace armarx
134
135//basic overloads from boost
136#include <tuple>
137
138namespace std
139{
140 /**
141 * @brief Enables hashing of std::tuple.
142 */
143 template <class... Ts>
144 struct hash<tuple<Ts...>>
145 {
146 /**
147 * @brief the hash operator's argument type.
148 */
149 using argument_type = tuple<Ts...>;
150 /**
151 * @brief the hash operator's result type
152 */
153 using result_type = std::size_t;
154
155 /**
156 * @brief Hashes a tuple
157 * @param the tuple to hash
158 * @return The tuple's hash
159 */
161 operator()(argument_type const& arg) const
162 {
163 return hash_all(arg);
164 }
165 };
166} // namespace std
167
168#include <utility>
169
170namespace std
171{
172 /**
173 * @brief Enables hashing of std::pair.
174 */
175 template <class A, class B>
176 struct hash<pair<A, B>>
177 {
178 /**
179 * @brief the hash operator's argument type.
180 */
181 using argument_type = pair<A, B>;
182 /**
183 * @brief the hash operator's result type
184 */
185 using result_type = std::size_t;
186
187 /**
188 * @brief Hashes a pair
189 * @param the pair to hash
190 * @return The pair's hash
191 */
193 operator()(argument_type const& arg) const
194 {
195 return armarx::hash_all(arg.first, arg.second);
196 }
197 };
198} // namespace std
199
200#include <vector>
201/**
202 * @brief Enables hashing of std::vector.
203 */
204ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class A), (vector<T, A>))
205
206#include <deque>
207/**
208 * @brief Enables hashing of std::deque.
209 */
210ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class A), (deque<T, A>))
211
212#include <list>
213/**
214 * @brief Enables hashing of std::list.
215 */
216ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class A), (list<T, A>))
217
218#include <set>
219/**
220 * @brief Enables hashing of std::set.
221 */
222ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class C, class A), (set<T, C, A>))
223/**
224 * @brief Enables hashing of std::multiset.
225 */
226ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class C, class A), (multiset<T, C, A>))
227
228#include <map>
229/**
230 * @brief Enables hashing of std::map.
231 */
232ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class K, class V, class C, class A), (map<K, V, C, A>))
233/**
234 * @brief Enables hashing of std::multimap.
235 */
236ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class K, class V, class C, class A), (multimap<K, V, C, A>))
#define ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE(TemplateArgs, Type)
Overloads the std::hash template for a type Type with the member functions begin() and end().
Definition HashingUtil.h:74
class A(deque< T, A >)) ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T
Enables hashing of std::list.
This file offers overloads of toIce() and fromIce() functions for STL container types.
void do_hash(std::size_t &hashed, const T0 &t0)
Combines the accumulated hash and the parameters hash.
Definition HashingUtil.h:99
std::size_t hash_all(const Ts &... ts)
Returns the hash of all parameters.
pair< A, B > argument_type
the hash operator's argument type.
std::size_t result_type
the hash operator's result type
result_type operator()(argument_type const &arg) const
Hashes a pair.
std::size_t result_type
the hash operator's result type
result_type operator()(argument_type const &arg) const
Hashes a tuple.
tuple< Ts... > argument_type
the hash operator's argument type.