Directory: | ./ |
---|---|
File: | Core/key_hash.hpp |
Date: | 2024-04-14 07:32:34 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 22 | 23 | 95.7% |
Branches: | 13 | 14 | 92.9% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | // ______ ______ _ _ _____ ______ | ||
2 | // | ____| ____| | (_)/ ____| | ____| | ||
3 | // | |__ | |__ | | _| (___ ___| |__ | ||
4 | // | __| | __| | | | |\___ \ / __| __| | ||
5 | // | | | |____| |____| |____) | (__| |____ | ||
6 | // |_| |______|______|_|_____/ \___|______| | ||
7 | // Finite Elements for Life Sciences and Engineering | ||
8 | // | ||
9 | // License: LGL2.1 License | ||
10 | // FELiScE default license: LICENSE in root folder | ||
11 | // | ||
12 | // Main authors: Vicente Mataix Ferrandiz | ||
13 | // | ||
14 | |||
15 | #ifndef FELISCE_KEY_HASH_H_INCLUDED | ||
16 | #define FELISCE_KEY_HASH_H_INCLUDED | ||
17 | |||
18 | // System includes | ||
19 | #include <functional> | ||
20 | |||
21 | // External includes | ||
22 | |||
23 | // Project includes | ||
24 | #include "Core/indexed_object.hpp" | ||
25 | |||
26 | namespace felisce | ||
27 | { | ||
28 | ///@addtogroup felisceCore | ||
29 | ///@{ | ||
30 | |||
31 | ///@name felisce Globals | ||
32 | ///@{ | ||
33 | |||
34 | ///@} | ||
35 | ///@name Type Definitions | ||
36 | ///@{ | ||
37 | |||
38 | /// The definition of the index type | ||
39 | typedef std::size_t IndexType; | ||
40 | |||
41 | /// The definition of the hash type | ||
42 | typedef std::size_t HashType; | ||
43 | |||
44 | ///@} | ||
45 | ///@name Enum's | ||
46 | ///@{ | ||
47 | |||
48 | ///@} | ||
49 | ///@name Functions | ||
50 | ///@{ | ||
51 | |||
52 | /** | ||
53 | * @brief This method creates an "unique" hash for the input value | ||
54 | * @tparam TClassType The type of class to be hashed | ||
55 | * @param Seed This is the seed used to create the hash | ||
56 | * @param Value This is the value to be hashed | ||
57 | */ | ||
58 | template <class TClassType> | ||
59 | 39874835 | inline void HashCombine( | |
60 | HashType& Seed, | ||
61 | const TClassType& Value | ||
62 | ) | ||
63 | { | ||
64 | std::hash<TClassType> hasher; | ||
65 | 39874835 | Seed ^= hasher(Value) + 0x9e3779b9 + (Seed<<6) + (Seed>>2); | |
66 | 39874835 | } | |
67 | |||
68 | /** | ||
69 | * @brief This method combines hash until it reaches the last class in order to obtain a corresponding seed | ||
70 | * @tparam TClassType The type of class to be hashed | ||
71 | * @param First The first class to be compared | ||
72 | * @param Last The last class to be compared | ||
73 | * @return The resulting seed | ||
74 | */ | ||
75 | template <class TClassType> | ||
76 | 13550596 | inline HashType HashRange( | |
77 | TClassType First, | ||
78 | TClassType Last | ||
79 | ) | ||
80 | { | ||
81 | 13550596 | HashType seed = 0; | |
82 | |||
83 |
2/2✓ Branch 1 taken 39874835 times.
✓ Branch 2 taken 13550596 times.
|
53425431 | while (First!=Last) { |
84 | 39874835 | HashCombine(seed, *First); | |
85 | 39874835 | ++First; | |
86 | } | ||
87 | |||
88 | 13550596 | return seed; | |
89 | } | ||
90 | |||
91 | /** | ||
92 | * @brief This is a key comparer of general pourpose between two classes | ||
93 | * @tparam TClassType The type of class to be hashed | ||
94 | */ | ||
95 | template<class TClassType> | ||
96 | struct KeyComparorRange | ||
97 | { | ||
98 | /** | ||
99 | * @brief This is the () operator | ||
100 | * @param first The first class to be compared | ||
101 | * @param second The second class to be compared | ||
102 | */ | ||
103 | bool operator()( | ||
104 | const TClassType& first, | ||
105 | const TClassType& second | ||
106 | ) const | ||
107 | { | ||
108 | if(first.size() != second.size()) { | ||
109 | return false; | ||
110 | } | ||
111 | |||
112 | auto it_first = first.begin(); | ||
113 | auto it_second = second.begin(); | ||
114 | |||
115 | while(it_first != first.end()) { // NOTE: We already checked that are same size | ||
116 | if(*it_first != *it_second) { | ||
117 | return false; | ||
118 | } | ||
119 | if(it_first != first.end()) { | ||
120 | ++it_first; | ||
121 | ++it_second; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | return true; | ||
126 | } | ||
127 | }; | ||
128 | |||
129 | /** | ||
130 | * @brief This is a hasher of general pourpose | ||
131 | * @tparam TClassType The type of class to be hashed | ||
132 | */ | ||
133 | template<class TClassType> | ||
134 | struct KeyHasherRange | ||
135 | { | ||
136 | /** | ||
137 | * @brief This is the () operator | ||
138 | * @param rRange The shared pointer to be hashed | ||
139 | * @return The corresponding hash | ||
140 | */ | ||
141 | HashType operator()(const TClassType& rRange) const | ||
142 | { | ||
143 | return HashRange(rRange.begin(), rRange.end()); | ||
144 | } | ||
145 | }; | ||
146 | |||
147 | /** | ||
148 | * @brief This is a hasher for variables | ||
149 | * @tparam TVariable The type of variable to be hashed | ||
150 | */ | ||
151 | template<class TVariable> | ||
152 | struct VariableHasher | ||
153 | { | ||
154 | /** | ||
155 | * @brief This is the () operator | ||
156 | * @param rVariable The variable to be hashed | ||
157 | * @return The corresponding hash | ||
158 | */ | ||
159 | HashType operator()(const TVariable& rVariable) const | ||
160 | { | ||
161 | return rVariable.Key(); | ||
162 | } | ||
163 | }; | ||
164 | |||
165 | /** | ||
166 | * @brief This is a hasher for variables pointers | ||
167 | * @tparam TVariable The type of variable to be hashed | ||
168 | */ | ||
169 | template<class TVariable> | ||
170 | struct pVariableHasher | ||
171 | { | ||
172 | /** | ||
173 | * @brief This is the () operator | ||
174 | * @param pVariable The variable pointer to be hashed | ||
175 | * @return The corresponding hash | ||
176 | */ | ||
177 | HashType operator()(const TVariable* pVariable) const | ||
178 | { | ||
179 | return pVariable->Key(); | ||
180 | } | ||
181 | }; | ||
182 | |||
183 | /** | ||
184 | * @brief This is a key comparer between two variables | ||
185 | * @tparam TVariable The type of variable to be compared | ||
186 | */ | ||
187 | template<class TVariable> | ||
188 | struct VariableComparator | ||
189 | { | ||
190 | /** | ||
191 | * @brief This is the () operator | ||
192 | * @param rFirst The first class to be compared | ||
193 | * @param rSecond The second class to be compared | ||
194 | */ | ||
195 | bool operator()( | ||
196 | const TVariable& rFirst, | ||
197 | const TVariable& rSecond | ||
198 | ) const | ||
199 | { | ||
200 | return rFirst.Key() == rSecond.Key(); | ||
201 | } | ||
202 | }; | ||
203 | |||
204 | /** | ||
205 | * @brief This is a key comparer between two variables pointers | ||
206 | * @tparam TVariable The type of variable to be compared | ||
207 | */ | ||
208 | template<class TVariable> | ||
209 | struct pVariableComparator | ||
210 | { | ||
211 | /** | ||
212 | * @brief This is the () operator | ||
213 | * @param pFirst The first class to be compared | ||
214 | * @param pSecond The second class to be compared | ||
215 | */ | ||
216 | bool operator()( | ||
217 | const TVariable* pFirst, | ||
218 | const TVariable* pSecond | ||
219 | ) const | ||
220 | { | ||
221 | return pFirst->Key() == pSecond->Key(); | ||
222 | } | ||
223 | }; | ||
224 | |||
225 | /** | ||
226 | * @brief This is a hasher for indexed objects | ||
227 | */ | ||
228 | struct IndexedObjectHasher | ||
229 | { | ||
230 | /** | ||
231 | * @brief This is the () operator | ||
232 | * @param rIndexedObject The indexed object to be hashed | ||
233 | * @return The corresponding hash | ||
234 | */ | ||
235 | HashType operator()(const IndexedObject& rIndexedObject) const | ||
236 | { | ||
237 | return rIndexedObject.Id(); | ||
238 | } | ||
239 | }; | ||
240 | |||
241 | /** | ||
242 | * @brief This is a key comparer between two indexed objects | ||
243 | */ | ||
244 | struct IndexedObjectComparator | ||
245 | { | ||
246 | /** | ||
247 | * @brief This is the () operator | ||
248 | * @param rFirst The first class to be compared | ||
249 | * @param rSecond The second class to be compared | ||
250 | */ | ||
251 | bool operator()( | ||
252 | const IndexedObject& rFirst, | ||
253 | const IndexedObject& rSecond | ||
254 | ) const | ||
255 | { | ||
256 | return rFirst.Id() == rSecond.Id(); | ||
257 | } | ||
258 | }; | ||
259 | |||
260 | /** | ||
261 | * @brief This is a hasher for indexed objects (pointer) | ||
262 | * @param TpIndexedObject Pointer type to indexed object | ||
263 | * @note Must be tenmplated to take into account the shared, intrussive,etc... pointers | ||
264 | */ | ||
265 | template<class TpIndexedObject> | ||
266 | struct IndexedObjecPointertHasher | ||
267 | { | ||
268 | /** | ||
269 | * @brief This is the () operator | ||
270 | * @param pIndexedObject The indexed object pointer to be hashed | ||
271 | * @return The corresponding hash | ||
272 | */ | ||
273 | HashType operator()(const TpIndexedObject pIndexedObject) const | ||
274 | { | ||
275 | return pIndexedObject->Id(); | ||
276 | } | ||
277 | }; | ||
278 | |||
279 | /** | ||
280 | * @brief This is a key comparer between two indexed objects (pointer) | ||
281 | * @param TpIndexedObject Pointer type to indexed object | ||
282 | * @note Must be tenmplated to take into account the shared, intrussive,etc... pointers | ||
283 | */ | ||
284 | template<class TpIndexedObject> | ||
285 | struct IndexedObjectPointerComparator | ||
286 | { | ||
287 | /** | ||
288 | * @brief This is the () operator | ||
289 | * @param pFirst The first class to be compared | ||
290 | * @param pSecond The second class to be compared | ||
291 | */ | ||
292 | bool operator()( | ||
293 | const TpIndexedObject pFirst, | ||
294 | const TpIndexedObject pSecond | ||
295 | ) const | ||
296 | { | ||
297 | return pFirst->Id() == pSecond->Id(); | ||
298 | } | ||
299 | }; | ||
300 | |||
301 | /** | ||
302 | * @brief This is a hasher for shared pointers | ||
303 | * @tparam TSharedPointer The type of shared pointer to be hashed | ||
304 | */ | ||
305 | template<class TSharedPointer> | ||
306 | struct SharedPointerHasher | ||
307 | { | ||
308 | /** | ||
309 | * @brief This is the () operator | ||
310 | * @param pPointer The shared pointer to be hashed | ||
311 | * @return The corresponding hash | ||
312 | */ | ||
313 | HashType operator()(const TSharedPointer& pPointer) const | ||
314 | { | ||
315 | return reinterpret_cast<HashType>(pPointer.get()); | ||
316 | } | ||
317 | }; | ||
318 | |||
319 | /** | ||
320 | * @brief This is a key comparer between two shared pointers | ||
321 | * @tparam TSharedPointer The type of shared pointer to be compared | ||
322 | */ | ||
323 | template<class TSharedPointer> | ||
324 | struct SharedPointerComparator | ||
325 | { | ||
326 | /** | ||
327 | * @brief This is the () operator | ||
328 | * @param first The first class to be compared | ||
329 | * @param second The second class to be compared | ||
330 | */ | ||
331 | bool operator()( | ||
332 | const TSharedPointer& first, | ||
333 | const TSharedPointer& second | ||
334 | ) const | ||
335 | { | ||
336 | return first.get() == second.get(); | ||
337 | } | ||
338 | }; | ||
339 | |||
340 | /** | ||
341 | * @brief This is a hasher between two vectors of indexes | ||
342 | * @tparam TVectorIndex The type of vector indexes to be compared | ||
343 | */ | ||
344 | template<class TVectorIndex> | ||
345 | struct VectorIndexHasher | ||
346 | { | ||
347 | /** | ||
348 | * @brief This is the () operator | ||
349 | * @param k The vector of indexes to be hashed | ||
350 | * @return The corresponding hash | ||
351 | */ | ||
352 | 13550596 | HashType operator()(const TVectorIndex& k) const | |
353 | { | ||
354 | 13550596 | return HashRange(k.begin(), k.end()); | |
355 | } | ||
356 | }; | ||
357 | |||
358 | /** | ||
359 | * @brief This is a key comparer between two vectors of indexes | ||
360 | * @tparam TVectorIndex The type of vector indexes to be compared | ||
361 | */ | ||
362 | template<class TVectorIndex> | ||
363 | struct VectorIndexComparor | ||
364 | { | ||
365 | /** | ||
366 | * @brief This is the () operator | ||
367 | * @param lhs The first class to be compared | ||
368 | * @param rhs The second class to be compared | ||
369 | */ | ||
370 | 521419 | bool operator()(const TVectorIndex& lhs, const TVectorIndex& rhs) const | |
371 | { | ||
372 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 521419 times.
|
521419 | if(lhs.size() != rhs.size()) |
373 | ✗ | return false; | |
374 | |||
375 |
2/2✓ Branch 1 taken 1782457 times.
✓ Branch 2 taken 518290 times.
|
2300747 | for(IndexType i = 0; i < lhs.size(); i++) { |
376 |
2/2✓ Branch 2 taken 3129 times.
✓ Branch 3 taken 1779328 times.
|
1782457 | if(lhs[i] != rhs[i]) return false; |
377 | } | ||
378 | |||
379 | 518290 | return true; | |
380 | } | ||
381 | }; | ||
382 | |||
383 | /** | ||
384 | * @brief This is an ordered key comparer between two vectors of indexes | ||
385 | * @tparam TVectorIndex The type of vector indexes to be compared | ||
386 | */ | ||
387 | template<class TVectorIndex> | ||
388 | struct VectorIndexComparorLess | ||
389 | { | ||
390 | /** | ||
391 | * @brief This is the () operator | ||
392 | * @param lhs The first class to be compared | ||
393 | * @param rhs The second class to be compared | ||
394 | */ | ||
395 | 5363280 | bool operator()(const TVectorIndex& lhs, const TVectorIndex& rhs) const | |
396 | { | ||
397 |
2/2✓ Branch 2 taken 295263 times.
✓ Branch 3 taken 5068017 times.
|
5363280 | if(lhs.size() != rhs.size()) |
398 | 295263 | return lhs.size() < rhs.size(); | |
399 | |||
400 |
2/2✓ Branch 1 taken 6548327 times.
✓ Branch 2 taken 208996 times.
|
6757323 | for(IndexType i = 0; i < lhs.size(); i++) { |
401 |
2/2✓ Branch 2 taken 4859021 times.
✓ Branch 3 taken 1689306 times.
|
6548327 | if(lhs[i] != rhs[i]) return lhs[i] < rhs[i]; |
402 | } | ||
403 | |||
404 | 208996 | return false; | |
405 | } | ||
406 | }; | ||
407 | |||
408 | /** | ||
409 | * @brief This is a hasher for pairs | ||
410 | * @details Used for example for edges ids | ||
411 | */ | ||
412 | template<class TType1, class TType2> | ||
413 | struct PairHasher | ||
414 | { | ||
415 | /** | ||
416 | * @brief The () operator | ||
417 | * @param rPair The index pair to hash | ||
418 | */ | ||
419 | std::size_t operator()(const std::pair<TType1, TType2>& rPair) const | ||
420 | { | ||
421 | std::size_t seed = 0; | ||
422 | HashCombine<TType1>(seed, rPair.first); | ||
423 | HashCombine<TType2>(seed, rPair.second); | ||
424 | return seed; | ||
425 | } | ||
426 | }; | ||
427 | |||
428 | /** | ||
429 | * @brief This is a key comparer between two indexes pairs | ||
430 | * @details Used for example for the B&S | ||
431 | */ | ||
432 | template<class TType1, class TType2> | ||
433 | struct PairComparor | ||
434 | { | ||
435 | /** | ||
436 | * @brief The () operator | ||
437 | * @param rIndexPair1 The first index pair to hash | ||
438 | * @param rIndexPair2 The second index pair to hash | ||
439 | */ | ||
440 | bool operator()(const std::pair<TType1, TType2>& rPair1, const std::pair<TType1, TType2>& rPair2) const | ||
441 | { | ||
442 | return ((std::get<0>(rPair1) == std::get<0>(rPair2)) && (std::get<1>(rPair1) == std::get<1>(rPair2))); | ||
443 | } | ||
444 | }; | ||
445 | |||
446 | ///@} | ||
447 | ///@name felisce Classes | ||
448 | ///@{ | ||
449 | |||
450 | } // namespace felisce. | ||
451 | #endif | ||
452 |