IceShard 1
A personal game engine project, with development focused on 2D/2.5D games.
Loading...
Searching...
No Matches
multi_hashmap.hxx
Go to the documentation of this file.
1
3
4#pragma once
5#include <ice/hashmap.hxx>
6
7namespace ice
8{
9
10 template<typename Type, ice::ContainerLogic Logic = ice::Constant_DefaultContainerLogic<Type>>
11 struct MultiHashMap : public ice::HashMap<Type, Logic>
12 {
13 using HashMap<Type, Logic>::HashMap;
14
22
23 struct ConstMultiIterator;
24
25 // API Specific to this extended type of a HashMap
26 template<ice::concepts::HashableKeyType HashableKeyT>
27 constexpr auto count_values(HashableKeyT const& key) noexcept -> SizeType;
28
29 template<typename Self, ice::concepts::HashableKeyType HashableKeyT>
30 constexpr auto find_values(
31 this Self const& self, HashableKeyT const& key
32 ) noexcept -> ConstMultiIterator;
33
34 template<
35 typename Self,
37 typename InValueType = typename std::remove_reference_t<Self>::ValueType
38 >
39 requires(std::convertible_to<InValueType, ice::container::ValueType<Self>>)
40 constexpr auto insert(
41 this Self&& self, HashableKeyT const& key, InValueType&& in_value
43
44 template<ice::concepts::HashableKeyType HashableKeyT>
45 constexpr void remove_all(HashableKeyT const& key) noexcept;
46 constexpr void remove_item(ConstMultiIterator& iterator);
47 };
48
49 template<typename Type, ice::ContainerLogic Logic>
50 struct MultiHashMap<Type, Logic>::ConstMultiIterator
51 {
55
56 constexpr ConstMultiIterator(std::nullptr_t) noexcept
58 , _entries{ nullptr }
59 , _values{ nullptr }
60 { }
61
63 ice::u32 current_entry,
64 EntryType const* entries,
65 ValueType const* values
66 ) noexcept
67 : _current{ current_entry }
68 , _entries{ entries }
69 , _values{ values }
70 { }
71
72 constexpr bool valid() const noexcept { return _current != ice::detail::hashmap::Constant_EndOfList; }
73 constexpr void next() noexcept
74 {
76
77 ice::u64 const expected_key = this->key();
78
79 do
80 {
83 {
84 _entries = nullptr;
85 _values = nullptr;
86 break;
87 }
88
89 // Test against the new key if we are not at the end.
90 } while (this->key() != expected_key);
91 }
92
93 constexpr auto key() const noexcept -> ice::u64 const& { return _entries[_current].key; }
94 constexpr auto value() const noexcept -> Type const& { return _values[_current]; }
95
96 constexpr bool operator==(ConstMultiIterator const& other) const noexcept
97 {
98 return _entries == other._entries && _current == other._current;
99 }
100
101 constexpr void operator++() noexcept { next(); }
102 constexpr auto operator*() const noexcept -> Type const& { return value(); }
103 };
104
105 template<typename Type, ice::ContainerLogic Logic>
106 template<ice::concepts::HashableKeyType HashableKeyT>
108 HashableKeyT const& key
109 ) noexcept -> SizeType
110 {
111 ice::u64 result = 0;
112
113 auto it = find_values(key);
114 while (it.valid())
115 {
116 result += 1;
117 it.next();
118 }
119 return { result, sizeof(ValueType) };
120 }
121
122 template<typename Type, ice::ContainerLogic Logic>
123 template<typename Self, ice::concepts::HashableKeyType HashableKeyT>
125 this Self const& self, HashableKeyT const& key
126 ) noexcept -> ConstMultiIterator
127 {
128 ice::u32 const index = ice::detail::hashmap::find_or_fail(self, ice::hash(key));
130 {
131 return { index, self._entries, self._data };
132 }
133 return { nullptr };
134 }
135
136 template<typename Type, ice::ContainerLogic Logic>
137 template<typename Self, ice::concepts::HashableKeyType HashableKeyT, typename InValueType>
138 requires(std::convertible_to<InValueType, ice::container::ValueType<Self>>)
140 this Self&& self, HashableKeyT const& key, InValueType&& in_value
142 {
143 if (self.is_full())
144 {
145 self.grow();
146 }
147
148 ice::u32 const index = ice::detail::hashmap::make(self, ice::hash(key));
149 if constexpr (Logic == ContainerLogic::Complex)
150 {
151 // If the index is below the current map._count we need to destroy the previous value.
152 if ((index + 1) < self._count)
153 {
154 ice::mem_destruct_at(self._data + index);
155 }
156
158 self._data + index,
159 ice::forward<InValueType>(in_value)
160 );
161 }
162 else
163 {
164 self._data[index] = in_value;
165 }
166
167 return self._data[index];
168 }
169
170 template<typename Type, ice::ContainerLogic Logic>
171 template<ice::concepts::HashableKeyType HashableKeyT>
172 inline constexpr void MultiHashMap<Type, Logic>::remove_all(HashableKeyT const& key) noexcept
173 {
174 ice::u64 const key_hash = ice::hash(key);
175 while (this->find(key_hash) != nullptr)
176 {
177 this->remove(key_hash);
178 }
179 }
180
181 template<typename Type, ice::ContainerLogic Logic>
183 {
186 {
187 iterator._current = iterator._entries[fr.entry_i].next;
189 }
190 }
191
192} // namespace ice
#define ICE_ASSERT_CORE(expression)
Definition assert_core.hxx:43
Definition container_concepts.hxx:83
ValueType< ContainerT > & ValueRef
Definition container_concepts.hxx:149
auto find(ContainerT const &map, ice::u64 key) noexcept -> FindResult
Definition hashmap_details.hxx:70
auto make(ContainerT &map, ice::u64 key) noexcept -> ice::u32
Definition hashmap_details.hxx:100
void erase(ContainerT &map, FindResult const fr) noexcept
Definition hashmap_details.hxx:127
auto find_or_fail(ContainerT const &map, ice::container::KeyType< ContainerT > key) noexcept -> ice::u32
Definition hashmap_details.hxx:201
static constexpr ice::u32 Constant_EndOfList
Definition hashmap_details.hxx:31
SPDX-License-Identifier: MIT.
Definition array.hxx:12
@ Complex
The collection handles complex data types and properly implements copy and move semantics.
Definition container_logic.hxx:19
std::uint64_t u64
Definition types.hxx:27
std::uint32_t u32
Definition types.hxx:26
void mem_destruct_at(T *location) noexcept
Definition mem_initializers.hxx:107
constexpr auto hash(ice::HeapString<> const &value) noexcept -> ice::u64
Definition heap_string.hxx:251
auto mem_construct_at(void *memory_ptr, Args &&... args) noexcept -> T *
Definition mem_initializers.hxx:12
Definition hashmap.hxx:107
Definition hashmap.hxx:42
A Map container designed for storing values using hashed values.
Definition hashmap.hxx:26
constexpr auto values(this Self &&self) noexcept -> ice::container::SpanType< Self >
Definition hashmap.hxx:340
Type ValueType
Definition hashmap.hxx:36
ConstIterator Iterator
Definition hashmap.hxx:38
constexpr auto find(this Self &&self, KeyType key) noexcept -> ice::container::ValuePtr< Self >
Definition hashmap.hxx:327
ice::ncount SizeType
Definition hashmap.hxx:39
ice::u64 KeyType
Definition hashmap.hxx:35
EntryType * _entries
Definition hashmap.hxx:52
HashMap(ice::Allocator &alloc) noexcept
Definition hashmap.hxx:132
constexpr bool remove(this Self &self, KeyType key) noexcept
Definition hashmap.hxx:320
Type const ConstContainerValueType
Definition hashmap.hxx:37
Definition multi_hashmap.hxx:51
constexpr void next() noexcept
Definition multi_hashmap.hxx:73
constexpr auto value() const noexcept -> Type const &
Definition multi_hashmap.hxx:94
constexpr ConstMultiIterator(std::nullptr_t) noexcept
Definition multi_hashmap.hxx:56
constexpr void operator++() noexcept
Definition multi_hashmap.hxx:101
ice::u32 _current
Definition multi_hashmap.hxx:52
constexpr auto operator*() const noexcept -> Type const &
Definition multi_hashmap.hxx:102
constexpr ConstMultiIterator(ice::u32 current_entry, EntryType const *entries, ValueType const *values) noexcept
Definition multi_hashmap.hxx:62
EntryType const * _entries
Definition multi_hashmap.hxx:53
ValueType const * _values
Definition multi_hashmap.hxx:54
constexpr auto key() const noexcept -> ice::u64 const &
Definition multi_hashmap.hxx:93
constexpr bool valid() const noexcept
Definition multi_hashmap.hxx:72
constexpr bool operator==(ConstMultiIterator const &other) const noexcept
Definition multi_hashmap.hxx:96
Definition multi_hashmap.hxx:12
constexpr auto insert(this Self &&self, HashableKeyT const &key, InValueType &&in_value) noexcept -> ice::container::ValueRef< Self >
Definition multi_hashmap.hxx:139
typename HashMap< Type, Logic >::ValueType ValueType
Definition multi_hashmap.hxx:17
typename HashMap< Type, Logic >::ConstContainerValueType ConstContainerValueType
Definition multi_hashmap.hxx:18
constexpr void remove_all(HashableKeyT const &key) noexcept
Definition multi_hashmap.hxx:172
typename HashMap< Type, Logic >::KeyType KeyType
Definition multi_hashmap.hxx:16
typename HashMap< Type, Logic >::Iterator Iterator
Definition multi_hashmap.hxx:20
constexpr void remove_item(ConstMultiIterator &iterator)
Definition multi_hashmap.hxx:182
typename HashMap< Type, Logic >::EntryType EntryType
Definition multi_hashmap.hxx:15
typename HashMap< Type, Logic >::ConstIterator ConstIterator
Definition multi_hashmap.hxx:21
constexpr auto count_values(HashableKeyT const &key) noexcept -> SizeType
Definition multi_hashmap.hxx:107
constexpr auto find_values(this Self const &self, HashableKeyT const &key) noexcept -> ConstMultiIterator
Definition multi_hashmap.hxx:124
typename HashMap< Type, Logic >::SizeType SizeType
Definition multi_hashmap.hxx:19
Definition hashmap_details.hxx:34
ice::u32 entry_i
Definition hashmap_details.hxx:37