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 
90 namespace 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 
138 namespace 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 
170 namespace 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  */
204 ARMARX_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  */
210 ARMARX_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  */
216 ARMARX_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  */
222 ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class C, class A), (set<T, C, A>))
223 /**
224  * @brief Enables hashing of std::multiset.
225  */
226 ARMARX_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  */
232 ARMARX_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  */
236 ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class K, class V, class C, class A), (multimap<K, V, C, A>))
std::hash< pair< A, B > >::argument_type
pair< A, B > argument_type
the hash operator's argument type.
Definition: HashingUtil.h:181
std::hash< tuple< Ts... > >::result_type
std::size_t result_type
the hash operator's result type
Definition: HashingUtil.h:153
armarx::do_hash
void do_hash(std::size_t &hashed, const T0 &t0)
Combines the accumulated hash and the parameters hash.
Definition: HashingUtil.h:99
std::hash< tuple< Ts... > >::operator()
result_type operator()(argument_type const &arg) const
Hashes a tuple.
Definition: HashingUtil.h:161
std::hash< pair< A, B > >::operator()
result_type operator()(argument_type const &arg) const
Hashes a pair.
Definition: HashingUtil.h:193
ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE
#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
std::hash< pair< A, B > >::result_type
std::size_t result_type
the hash operator's result type
Definition: HashingUtil.h:185
std::hash< tuple< Ts... > >::argument_type
tuple< Ts... > argument_type
the hash operator's argument type.
Definition: HashingUtil.h:149
A
class A(deque< T, A >)) ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T
Enables hashing of std::list.
std
Definition: Application.h:66
armarx::hash_all
std::size_t hash_all(const Ts &... ts)
Returns the hash of all parameters.
Definition: HashingUtil.h:127
T
float T
Definition: UnscentedKalmanFilterTest.cpp:38
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27