Plasma Engine  2.0
Loading...
Searching...
No Matches
ArrayMap_inl.h
1#pragma once
2
3template <typename KEY, typename VALUE>
5 : m_Data(pAllocator)
6{
7 m_bSorted = true;
8}
9
10template <typename KEY, typename VALUE>
12 : m_bSorted(rhs.m_bSorted)
13 , m_Data(pAllocator)
14{
15 m_Data = rhs.m_Data;
16}
17
18template <typename KEY, typename VALUE>
20{
21 m_bSorted = rhs.m_bSorted;
22 m_Data = rhs.m_Data;
23}
24
25template <typename KEY, typename VALUE>
26PL_ALWAYS_INLINE plUInt32 plArrayMapBase<KEY, VALUE>::GetCount() const
27{
28 return m_Data.GetCount();
29}
30
31template <typename KEY, typename VALUE>
32PL_ALWAYS_INLINE bool plArrayMapBase<KEY, VALUE>::IsEmpty() const
33{
34 return m_Data.IsEmpty();
35}
36
37template <typename KEY, typename VALUE>
39{
40 m_bSorted = true;
41 m_Data.Clear();
42}
44template <typename KEY, typename VALUE>
45template <typename CompatibleKeyType, typename CompatibleValueType>
46inline plUInt32 plArrayMapBase<KEY, VALUE>::Insert(CompatibleKeyType&& key, CompatibleValueType&& value)
47{
48 Pair& ref = m_Data.ExpandAndGetRef();
49 ref.key = std::forward<CompatibleKeyType>(key);
50 ref.value = std::forward<CompatibleValueType>(value);
51 m_bSorted = false;
52 return m_Data.GetCount() - 1;
53}
55template <typename KEY, typename VALUE>
57{
58 if (m_bSorted)
59 return;
60
61 m_bSorted = true;
62 m_Data.Sort();
63}
64
65template <typename KEY, typename VALUE>
66template <typename CompatibleKeyType>
67plUInt32 plArrayMapBase<KEY, VALUE>::Find(const CompatibleKeyType& key) const
68{
69 if (!m_bSorted)
70 {
71 m_Data.Sort();
72 }
73
74 plUInt32 lb = 0;
75 plUInt32 ub = m_Data.GetCount();
76
77 while (lb < ub)
78 {
79 const plUInt32 middle = lb + ((ub - lb) >> 1);
81 if (m_Data[middle].key < key)
82 {
83 lb = middle + 1;
84 }
85 else if (key < m_Data[middle].key)
86 {
87 ub = middle;
88 }
89 else // equal
90 {
91 return middle;
92 }
93 }
94
95 return plInvalidIndex;
96}
98template <typename KEY, typename VALUE>
99template <typename CompatibleKeyType>
100plUInt32 plArrayMapBase<KEY, VALUE>::LowerBound(const CompatibleKeyType& key) const
101{
102 if (!m_bSorted)
103 {
104 m_Data.Sort();
105 }
106
107 plUInt32 lb = 0;
108 plUInt32 ub = m_Data.GetCount();
109
110 while (lb < ub)
111 {
112 const plUInt32 middle = lb + ((ub - lb) >> 1);
114 if (m_Data[middle].key < key)
115 {
116 lb = middle + 1;
117 }
118 else
119 {
120 ub = middle;
122 }
123
124 if (lb == m_Data.GetCount())
125 return plInvalidIndex;
126
127 return lb;
128}
129
130template <typename KEY, typename VALUE>
131template <typename CompatibleKeyType>
132plUInt32 plArrayMapBase<KEY, VALUE>::UpperBound(const CompatibleKeyType& key) const
133{
134 if (!m_bSorted)
135 {
136 m_Data.Sort();
137 }
138
139 plUInt32 lb = 0;
140 plUInt32 ub = m_Data.GetCount();
141
142 while (lb < ub)
143 {
144 const plUInt32 middle = lb + ((ub - lb) >> 1);
145
146 if (key < m_Data[middle].key)
147 {
148 ub = middle;
149 }
150 else
151 {
152 lb = middle + 1;
153 }
154 }
155
156 if (ub == m_Data.GetCount())
157 return plInvalidIndex;
158
159 return ub;
160}
161
162template <typename KEY, typename VALUE>
163PL_ALWAYS_INLINE const KEY& plArrayMapBase<KEY, VALUE>::GetKey(plUInt32 uiIndex) const
164{
165 return m_Data[uiIndex].key;
166}
167
168template <typename KEY, typename VALUE>
169PL_ALWAYS_INLINE const VALUE& plArrayMapBase<KEY, VALUE>::GetValue(plUInt32 uiIndex) const
170{
171 return m_Data[uiIndex].value;
172}
173
174template <typename KEY, typename VALUE>
176{
177 return m_Data[uiIndex].value;
178}
179
180template <typename KEY, typename VALUE>
182{
183 m_bSorted = false;
184 return m_Data;
185}
186
187template <typename KEY, typename VALUE>
189{
190 return m_Data;
191}
192
193template <typename KEY, typename VALUE>
194template <typename CompatibleKeyType>
195VALUE& plArrayMapBase<KEY, VALUE>::FindOrAdd(const CompatibleKeyType& key, bool* out_pExisted)
196{
197 plUInt32 index = Find<CompatibleKeyType>(key);
198
199 if (out_pExisted)
200 *out_pExisted = index != plInvalidIndex;
201
202 if (index == plInvalidIndex)
203 {
204 index = Insert(key, VALUE());
205 }
206
207 return GetValue(index);
208}
209
210template <typename KEY, typename VALUE>
211template <typename CompatibleKeyType>
212PL_ALWAYS_INLINE VALUE& plArrayMapBase<KEY, VALUE>::operator[](const CompatibleKeyType& key)
213{
214 return FindOrAdd(key);
215}
216
217template <typename KEY, typename VALUE>
218PL_ALWAYS_INLINE const typename plArrayMapBase<KEY, VALUE>::Pair& plArrayMapBase<KEY, VALUE>::GetPair(plUInt32 uiIndex) const
219{
220 return m_Data[uiIndex];
221}
222
223template <typename KEY, typename VALUE>
224void plArrayMapBase<KEY, VALUE>::RemoveAtAndCopy(plUInt32 uiIndex, bool bKeepSorted)
225{
226 if (bKeepSorted && m_bSorted)
227 {
228 m_Data.RemoveAtAndCopy(uiIndex);
229 }
230 else
231 {
232 m_Data.RemoveAtAndSwap(uiIndex);
233 m_bSorted = false;
234 }
235}
236
237template <typename KEY, typename VALUE>
238template <typename CompatibleKeyType>
239bool plArrayMapBase<KEY, VALUE>::RemoveAndCopy(const CompatibleKeyType& key, bool bKeepSorted)
240{
241 const plUInt32 uiIndex = Find(key);
242
243 if (uiIndex == plInvalidIndex)
244 return false;
245
246 RemoveAtAndCopy(uiIndex, bKeepSorted);
247 return true;
248}
249
250template <typename KEY, typename VALUE>
251template <typename CompatibleKeyType>
252PL_ALWAYS_INLINE bool plArrayMapBase<KEY, VALUE>::Contains(const CompatibleKeyType& key) const
253{
254 return Find(key) != plInvalidIndex;
255}
256
257template <typename KEY, typename VALUE>
258template <typename CompatibleKeyType>
259bool plArrayMapBase<KEY, VALUE>::Contains(const CompatibleKeyType& key, const VALUE& value) const
260{
261 plUInt32 atpos = LowerBound(key);
262
263 if (atpos == plInvalidIndex)
264 return false;
265
266 while (atpos < m_Data.GetCount())
267 {
268 if (m_Data[atpos].key != key)
269 return false;
270
271 if (m_Data[atpos].value == value)
272 return true;
273
274 ++atpos;
275 }
276
277 return false;
278}
279
280
281template <typename KEY, typename VALUE>
282PL_ALWAYS_INLINE void plArrayMapBase<KEY, VALUE>::Reserve(plUInt32 uiSize)
283{
284 m_Data.Reserve(uiSize);
285}
286
287template <typename KEY, typename VALUE>
289{
290 m_Data.Compact();
291}
292
293template <typename KEY, typename VALUE>
295{
296 Sort();
297 rhs.Sort();
298
299 return m_Data == rhs.m_Data;
300}
301
302template <typename KEY, typename VALUE, typename A>
304 : plArrayMapBase<KEY, VALUE>(A::GetAllocator())
305{
306}
307
308template <typename KEY, typename VALUE, typename A>
310 : plArrayMapBase<KEY, VALUE>(pAllocator)
311{
312}
313
314template <typename KEY, typename VALUE, typename A>
316 : plArrayMapBase<KEY, VALUE>(rhs, A::GetAllocator())
317{
318}
319
320template <typename KEY, typename VALUE, typename A>
322 : plArrayMapBase<KEY, VALUE>(rhs, A::GetAllocator())
323{
324}
325
326template <typename KEY, typename VALUE, typename A>
328{
330}
331
332template <typename KEY, typename VALUE, typename A>
334{
336}
Base class for all memory allocators.
Definition Allocator.h:23
An associative container, similar to plMap, but all data is stored in a sorted contiguous array,...
Definition ArrayMap.h:14
bool operator==(const plArrayMapBase< KEY, VALUE > &rhs) const
Compares the two containers for equality.
Definition ArrayMap_inl.h:294
plArrayMapBase(plAllocator *pAllocator)
Constructor.
Definition ArrayMap_inl.h:4
VALUE & FindOrAdd(const CompatibleKeyType &key, bool *out_pExisted=nullptr)
Returns the value stored at the given key. If none exists, one is created. bExisted indicates whether...
Definition ArrayMap_inl.h:195
plDynamicArray< Pair > & GetData()
Returns a reference to the map data array.
Definition ArrayMap_inl.h:181
VALUE & operator[](const CompatibleKeyType &key)
Same as FindOrAdd.
void Sort() const
Ensures the internal data structure is sorted. This is done automatically every time a lookup needs t...
Definition ArrayMap_inl.h:56
bool RemoveAndCopy(const CompatibleKeyType &key, bool bKeepSorted=false)
Removes one element with the given key. Returns true, if one was found and removed....
Definition ArrayMap_inl.h:239
const Pair & GetPair(plUInt32 uiIndex) const
Returns the key/value pair at the given index.
Definition ArrayMap_inl.h:218
const VALUE & GetValue(plUInt32 uiIndex) const
Returns the value that is stored at the given index.
Definition ArrayMap_inl.h:169
void Clear()
Purges all elements from the map.
Definition ArrayMap_inl.h:38
bool IsEmpty() const
True if the map contains no elements.
Definition ArrayMap_inl.h:32
bool Contains(const CompatibleKeyType &key) const
Returns whether an element with the given key exists.
const KEY & GetKey(plUInt32 uiIndex) const
Returns the key that is stored at the given index.
Definition ArrayMap_inl.h:163
void RemoveAtAndCopy(plUInt32 uiIndex, bool bKeepSorted=false)
Removes the element at the given index.
Definition ArrayMap_inl.h:224
plUInt32 Insert(CompatibleKeyType &&key, CompatibleValueType &&value)
Always inserts a new value under the given key. Duplicates are allowed. Returns the index of the newl...
Definition ArrayMap_inl.h:46
plUInt32 GetCount() const
Returns the number of elements stored in the map.
Definition ArrayMap_inl.h:26
plUInt32 Find(const CompatibleKeyType &key) const
Returns an index to one element with the given key. If the key is inserted multiple times,...
Definition ArrayMap_inl.h:67
void operator=(const plArrayMapBase &rhs)
Copy assignment operator.
Definition ArrayMap_inl.h:19
void Reserve(plUInt32 uiSize)
Reserves enough memory to store size elements.
Definition ArrayMap_inl.h:282
void Compact()
Compacts the internal memory to not waste any space.
Definition ArrayMap_inl.h:288
plUInt32 UpperBound(const CompatibleKeyType &key) const
Returns the index to the first element with a key that is LARGER than the given key....
Definition ArrayMap_inl.h:132
plUInt32 LowerBound(const CompatibleKeyType &key) const
Returns the index to the first element with a key equal or larger than the given key....
Definition ArrayMap_inl.h:100
See plArrayMapBase for details.
Definition ArrayMap.h:149
Definition DynamicArray.h:81
Definition ArrayMap.h:19