idol
A C++ Framework for Optimization
Loading...
Searching...
No Matches
Map.h
1//
2// Created by henri on 01/09/22.
3//
4
5#ifndef OPTIMIZE_MAP_H
6#define OPTIMIZE_MAP_H
7
8
9#ifdef IDOL_USE_ROBINHOOD
10#include <robin_hood.h>
11
12#else
13#include <unordered_map>
14#endif
15
16#include "Pair.h"
17
18// Implements hash for pairs (non-symmetric by default (std::hash<idol::Pair<T, U>>) and symmetric impls)
19// See https://youngforest.github.io/2020/05/27/best-implement-to-use-pair-as-key-to-std-unordered-map-in-C/
20namespace idol::impl {
21
22#ifdef IDOL_USE_ROBINHOOD
23 template<class T, class EnableT = void> using hash = robin_hood::hash<T, EnableT>;
24#else
25 template<class A> using hash = std::hash<A>;
26#endif
27
28 template <typename T>
29 inline void hash_combine(std::size_t &seed, const T &val) {
30 seed ^= hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
31 }
32
33 // auxiliary generic functions to create a hash value using a seed
34 template <typename T> inline void hash_val(std::size_t &seed, const T &val) {
35 hash_combine(seed, val);
36 }
37
38 template <typename T, typename... Types>
39 inline void hash_val(std::size_t &seed, const T &val, const Types &... args) {
40 hash_combine(seed, val);
41 hash_val(seed, args...);
42 }
43
44 template <typename... Types>
45 inline std::size_t hash_val(const Types &... args) {
46 std::size_t seed = 0;
47 hash_val(seed, args...);
48 return seed;
49 }
50
51}
52
53template<class Key1, class Key2>
54struct std::hash<idol::Pair<Key1, Key2>> {
55 std::size_t operator()(const idol::Pair<Key1, Key2>& t_pair) const {
56 return idol::impl::hash_val(t_pair.first, t_pair.second);
57 }
58};
59
60template<class Key1, class Key2>
61struct std::hash<idol::CommutativePair<Key1, Key2>> {
62 std::size_t operator()(const idol::CommutativePair<Key1, Key2>& t_pair) const {
63 return idol::impl::hash_val(t_pair.first, t_pair.second);
64 }
65};
66
67#ifdef IDOL_USE_ROBINHOOD
68
69namespace idol {
70
71 template<
72 class Key,
73 class T,
74 class Hash = impl::hash<Key>,
75 class KeyEqual = std::equal_to<Key>
76 >
77 using Map = robin_hood::unordered_map<Key, T, Hash, KeyEqual>;
78
79}
80
81#else
82
83namespace idol {
84
85 template<
86 class KeyT,
87 class T,
88 class Hash = impl::hash<KeyT>,
89 class KeyEqual = std::equal_to<KeyT>,
90 class Allocator = std::allocator<std::pair<const KeyT, T> >
91 >
92 using Map = std::unordered_map<KeyT, T, Hash, KeyEqual, Allocator>;
93
94}
95
96#endif
97
98#endif //OPTIMIZE_MAP_H