1#ifndef GIMBAL_HASHMAP_HPP
2#define GIMBAL_HASHMAP_HPP
12 typename H=std::hash<K>>
13 struct HashMapHasherAdapter;
17 typename P=std::equal_to<K>>
18 struct HashMapEqualToAdapter;
23 typename H = std::hash<K>,
24 typename P = std::equal_to<K>>
26 public HashSet<std::pair<
const K, T>,
27 impl::HashMapHasherAdapter<K, T, H>,
28 impl::HashMapEqualToAdapter<K, T, P>>,
34 using HashSetType = HashSet<std::pair<
const K, T>,
35 impl::HashMapHasherAdapter<K, T, H>,
36 impl::HashMapEqualToAdapter<K, T, P>>;
37 using HashSetBaseType =
typename HashSetType::BaseType;
39 using mapped_type = T;
40 using value_type = std::pair<
const K, T>;
42 using difference_type = std::ptrdiff_t;
45 using reference = value_type&;
46 using const_reference =
const value_type&;
47 using pointer = value_type*;
48 using const_pointer =
const pointer;
49 using iterator =
typename HashSetType::iterator;
50 using const_iterator =
typename HashSetType::const_iterator;
52
53
54
55
56
58 auto getElement_(
const K& key)
const noexcept ->
const T&;
59 void setElement_(
const K& key,
const T& value)
noexcept;
63 HashMap(size_type capacity = 0,
66 Context* pCtx =
nullptr);
67 HashMap(size_type capacity,
70 HashMap(size_type capacity,
72 explicit HashMap(Context* pCtx);
74 HashMap(std::initializer_list<value_type> init,
75 size_type capacity = 0,
78 Context* pCtx =
nullptr);
79 HashMap(std::initializer_list<value_type> init,
83 HashMap(std::initializer_list<value_type> init,
89 void insert_or_assign(
const key_type& k, M&& obj)
noexcept;
91 bool erase(
const key_type& k)
noexcept;
93 auto at(
const key_type& key)
const ->
const mapped_type&;
94 auto at(
const key_type& key) -> mapped_type&;
96 auto find(
const key_type& key)
const noexcept -> const_iterator;
97 auto find(
const key_type& key)
noexcept -> iterator;
99 bool contains(
const key_type& key)
const noexcept;
107 typename H = std::hash<K>,
108 typename P = std::equal_to<K>>
109HashMap(std::initializer_list<std::pair<
const K, T>> list,
113 Context* pCtx=
nullptr) -> HashMap<K, T, H, P>;
126 struct HashMapHasherAdapter {
129 HashMapHasherAdapter(
const H& hasher_=H()):
132 Hash operator()(
const std::pair<K, V>& value)
const {
133 return hasher(value.first);
140 struct HashMapEqualToAdapter {
143 HashMapEqualToAdapter(
const P& pred_=P()):
146 bool operator()(
const std::pair<K, V>& lhs,
const std::pair<K, V>& rhs)
const {
147 return pred(lhs.first, rhs.first);
153template<
typename K,
typename T,
typename H,
typename P>
154inline HashMap<K, T, H, P>::HashMap(size_type capacity,
158 HashSetType(capacity, hash, pred, pCtx) {}
160template<
typename K,
typename T,
typename H,
typename P>
161inline HashMap<K, T, H, P>::HashMap(std::initializer_list<value_type> init,
166 HashMap(capacity < init.size()? init.size() : capacity, hash, pred, pCtx)
169 for(
auto item : init) {
170 HashSetType::insert(item);
174template<
typename K,
typename T,
typename H,
typename P>
175inline HashMap<K, T, H, P>::HashMap(size_type capacity,
178 HashMap(capacity, hash, P(), pCtx) {}
180template<
typename K,
typename T,
typename H,
typename P>
181inline HashMap<K, T, H, P>::HashMap(size_type capacity, Context* pCtx):
182 HashMap(capacity, H(), P(), pCtx) {}
184template<
typename K,
typename T,
typename H,
typename P>
185inline HashMap<K, T, H, P>::HashMap(Context* pCtx):
189template<
typename K,
typename T,
typename H,
typename P>
190inline HashMap<K, T, H, P>::HashMap(std::initializer_list<value_type> init,
194 HashMap(std::move(init), capacity, hash, P(), pCtx) {}
196template<
typename K,
typename T,
typename H,
typename P>
197inline HashMap<K, T, H, P>::HashMap(std::initializer_list<value_type> init,
200 HashMap(std::move(init), capacity, H(), pCtx) {}
202template<
typename K,
typename T,
typename H,
typename P>
203inline const T&
HashMap<K, T, H, P>::getElement_(
const K& key)
const noexcept {
207template<
typename K,
typename T,
typename H,
typename P>
208inline void HashMap<K, T, H, P>::setElement_(
const K& key,
const T& value)
noexcept {
209 insert_or_assign(key, value);
212template<
typename K,
typename T,
typename H,
typename P>
214inline void HashMap<K, T, H, P>::insert_or_assign(
const key_type& k, M&& obj)
noexcept {
215 std::pair<K, T> item { k, std::forward<M>(obj) };
216 HashSetType::insert_or_assign(item);
219template<
typename K,
typename T,
typename H,
typename P>
220inline bool HashMap<K, T, H, P>::erase(
const key_type& k)
noexcept {
221 std::pair<K, T> pair { k, T{} };
222 return HashSetType::erase(pair);
225template<
typename K,
typename T,
typename H,
typename P>
226inline auto HashMap<K, T, H, P>::at(
const key_type& k)
const ->
const mapped_type& {
227 std::pair<K, T> pair { k, T{} };
228 const auto& result = HashSetBaseType::at(pair);
229 return result.second;
232template<
typename K,
typename T,
typename H,
typename P>
233inline auto HashMap<K, T, H, P>::at(
const key_type& k) -> mapped_type& {
234 std::pair<K, T> pair { k, T{} };
235 auto& result = HashSetType::at(pair);
236 return result.second;
239template<
typename K,
typename T,
typename H,
typename P>
240inline auto HashMap<K, T, H, P>::find(
const key_type& k)
const noexcept -> const_iterator {
241 std::pair<K, T> pair (k, T{});
242 return HashSetType::find(pair);
245template<
typename K,
typename T,
typename H,
typename P>
246inline auto HashMap<K, T, H, P>::find(
const key_type& k)
noexcept -> iterator {
247 std::pair<K, T> pair (k, T{});
248 return HashSetType::find(pair);
251template<
typename K,
typename T,
typename H,
typename P>
252inline bool HashMap<K, T, H, P>::contains(
const key_type& k)
const noexcept {
253 std::pair<K, T> pair { k, T{} };
254 return HashSetType::contains(pair);