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 operator()(argument_type const& arg) const\
58  {\
59  return armarx::hash_all( ARMARX_STRIP_PARENTHESES(Members) );\
60  }\
61  };\
62  }
63 
64 /**
65  *@brief Overloads the std::hash template for a type Type with the member functions begin() and end().
66  * If the type depends on some template parameters they can be passed as the first argument.
67  * The parentheses around both arguments are required!
68  *
69  * examples:
70  * for vector<int, AllocatorType> : ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((), (vector<int, AllocatorType>))
71  * for all vectors: ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class A), (vector<T, A>))
72  */
73 #define ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE(TemplateArgs, Type)\
74  namespace std\
75  {\
76  template< ARMARX_STRIP_PARENTHESES(TemplateArgs) >\
77  struct hash< ARMARX_STRIP_PARENTHESES(Type) >\
78  {\
79  using argument_type = ARMARX_STRIP_PARENTHESES(Type);\
80  using result_type = std::size_t;\
81  result_type operator()(argument_type const& arg) const\
82  {\
83  return boost::hash_range(arg.begin(), arg.end());\
84  }\
85  };\
86  }
87 
88 namespace armarx
89 {
90  /**
91  * @brief Combines the accumulated hash and the parameters hash.
92  * @param hashed The accumulated hash.
93  * @param t0 The value to hash.
94  */
95  template<class T0>
96  void do_hash(std::size_t& hashed, const T0& t0)
97  {
98  //replace this call to change combination methode of hash values and the used hash function
99  //(currently uses boost::hash_value)
100  boost::hash_combine(hashed, t0);
101  }
102 
103  /**
104  * @brief Combines the accumulated hash and the parameters hash.
105  * @param hashed The accumulated hash.
106  * @param t0 The first value to hash.
107  * @param ts Further values to hash.
108  */
109  template<class T0, class...Ts>
110  void do_hash(std::size_t& hashed, const T0& t0, const Ts& ...ts)
111  {
112  do_hash(hashed, t0);
113  do_hash(hashed, ts...);
114  }
115 
116  /**
117  * @brief Returns the hash of all parameters.
118  * @param ts The parameters to hash
119  * @return The hash of all parameters.
120  */
121  template<class...Ts>
122  std::size_t hash_all(const Ts& ...ts)
123  {
124  std::size_t hashed = 0;
125  do_hash(hashed, ts...);
126  return hashed;
127  }
128 }
129 
130 //basic overloads from boost
131 #include <tuple>
132 namespace std
133 {
134  /**
135  * @brief Enables hashing of std::tuple.
136  */
137  template<class...Ts>
138  struct hash<tuple<Ts...>>
139  {
140  /**
141  * @brief the hash operator's argument type.
142  */
143  using argument_type = tuple<Ts...>;
144  /**
145  * @brief the hash operator's result type
146  */
147  using result_type = std::size_t;
148  /**
149  * @brief Hashes a tuple
150  * @param the tuple to hash
151  * @return The tuple's hash
152  */
154  {
155  return hash_all(arg);
156  }
157  };
158 }
159 
160 #include <utility>
161 namespace std
162 {
163  /**
164  * @brief Enables hashing of std::pair.
165  */
166  template<class A, class B>
167  struct hash<pair<A, B>>
168  {
169  /**
170  * @brief the hash operator's argument type.
171  */
172  using argument_type = pair<A, B>;
173  /**
174  * @brief the hash operator's result type
175  */
176  using result_type = std::size_t;
177 
178  /**
179  * @brief Hashes a pair
180  * @param the pair to hash
181  * @return The pair's hash
182  */
184  {
185  return armarx::hash_all(arg.first, arg.second);
186  }
187  };
188 }
189 
190 #include <vector>
191 /**
192  * @brief Enables hashing of std::vector.
193  */
194 ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class A), (vector<T, A>))
195 
196 #include <deque>
197 /**
198  * @brief Enables hashing of std::deque.
199  */
200 ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class A), (deque<T, A>))
201 
202 #include <list>
203 /**
204  * @brief Enables hashing of std::list.
205  */
206 ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class A), (list<T, A>))
207 
208 #include <set>
209 /**
210  * @brief Enables hashing of std::set.
211  */
212 ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class C, class A), (set<T, C, A>))
213 /**
214  * @brief Enables hashing of std::multiset.
215  */
216 ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T, class C, class A), (multiset<T, C, A>))
217 
218 #include <map>
219 /**
220  * @brief Enables hashing of std::map.
221  */
222 ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class K, class V, class C, class A), (map<K, V, C, A>))
223 /**
224  * @brief Enables hashing of std::multimap.
225  */
226 ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class K, class V, class C, class A), (multimap<K, V, C, A>))
227 
std::hash< pair< A, B > >::argument_type
pair< A, B > argument_type
the hash operator's argument type.
Definition: HashingUtil.h:172
std::hash< tuple< Ts... > >::result_type
std::size_t result_type
the hash operator's result type
Definition: HashingUtil.h:147
armarx::do_hash
void do_hash(std::size_t &hashed, const T0 &t0)
Combines the accumulated hash and the parameters hash.
Definition: HashingUtil.h:96
std::hash< tuple< Ts... > >::operator()
result_type operator()(argument_type const &arg) const
Hashes a tuple.
Definition: HashingUtil.h:153
std::hash< pair< A, B > >::operator()
result_type operator()(argument_type const &arg) const
Hashes a pair.
Definition: HashingUtil.h:183
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:73
std::hash< pair< A, B > >::result_type
std::size_t result_type
the hash operator's result type
Definition: HashingUtil.h:176
std::hash< tuple< Ts... > >::argument_type
tuple< Ts... > argument_type
the hash operator's argument type.
Definition: HashingUtil.h:143
armarx::hash_all
std::size_t hash_all(const Ts &...ts)
Returns the hash of all parameters.
Definition: HashingUtil.h:122
A
class A(deque< T, A >)) ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T
Enables hashing of std::list.
std
Definition: Application.h:66
T
float T
Definition: UnscentedKalmanFilterTest.cpp:35
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28