ObjectMap.h
Go to the documentation of this file.
1 /****
2  * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
3  * Created 2015 by Skurydin Alexey
4  * http://github.com/SmingHub/Sming
5  * All files of the Sming Core are provided under the LGPL v3 license.
6  *
7  * ObjectMap.h
8  *
9  * @author: 31 Jul 2018 - Mikee47 <mike@sillyhouse.net>
10  *
11  */
12 
13 #pragma once
14 
15 #include "WVector.h"
16 
47 template <typename K, typename V> class ObjectMap
48 {
49 public:
51  {
52  }
53 
55  {
56  clear();
57  }
58 
63  class Value
64  {
65  public:
66  Value(ObjectMap<K, V>& map, const K& key) : map(map), key(key)
67  {
68  }
69 
70  const K& getKey() const
71  {
72  return key;
73  }
74 
75  V* getValue() const
76  {
77  return map.find(key);
78  }
79 
80  Value& operator=(V* newValue)
81  {
82  map.set(key, newValue);
83  return *this;
84  }
85 
86  operator V*() const
87  {
88  return getValue();
89  }
90 
91  V* operator->() const
92  {
93  return getValue();
94  }
95 
100  bool remove()
101  {
102  return map.remove(key);
103  }
104 
110  V* extract()
111  {
112  return map.extract(key);
113  }
114 
115  private:
116  ObjectMap<K, V>& map;
117  K key;
118  };
119 
124  unsigned count() const
125  {
126  return entries.count();
127  }
128 
129  /*
130  * @brief Get a key at a specified index, non-modifiable
131  * @param idx the index to get the key at
132  * @return The key at index idx
133  */
134  const K& keyAt(unsigned idx) const
135  {
136  return entries[idx].key;
137  }
138 
139  /*
140  * @brief Get a key at a specified index
141  * @param idx the index to get the key at
142  * @return Reference to the key at index idx
143  */
144  K& keyAt(unsigned idx)
145  {
146  return entries[idx].key;
147  }
148 
149  /*
150  * @brief Get a value at a specified index, non-modifiable
151  * @param idx the index to get the value at
152  * @retval The value at index idx
153  * @note The caller must not use `delete` on the returned value
154  */
155  const V* valueAt(unsigned idx) const
156  {
157  return entries[idx].value;
158  }
159 
160  /*
161  * @brief Get a value at a specified index
162  * @param idx the index to get the value at
163  * @retval Value Reference to value at index idx
164  * @see `operator[]`
165  */
166  Value valueAt(unsigned idx)
167  {
168  return Value(*this, entries[idx].key);
169  }
170 
177  const V* operator[](const K& key) const
178  {
179  return find(key);
180  }
181 
189  Value operator[](const K& key)
190  {
191  return get(key);
192  }
193 
199  Value get(const K& key)
200  {
201  return Value(*this, key);
202  }
203 
208  void set(const K& key, V* value)
209  {
210  int i = indexOf(key);
211  if(i >= 0) {
212  delete entries[i].value;
213  entries[i].value = value;
214  } else {
215  entries.addElement(new Entry(key, value));
216  }
217  }
218 
225  V* find(const K& key) const
226  {
227  int index = indexOf(key);
228  return (index < 0) ? nullptr : entries[index].value;
229  }
230 
236  int indexOf(const K& key) const
237  {
238  for(unsigned i = 0; i < entries.count(); i++) {
239  if(entries[i].key == key) {
240  return i;
241  }
242  }
243  return -1;
244  }
245 
251  bool contains(const K& key) const
252  {
253  return indexOf(key) >= 0;
254  }
255 
260  void removeAt(unsigned index)
261  {
262  entries.remove(index);
263  }
264 
270  bool remove(const K& key)
271  {
272  int index = indexOf(key);
273  if(index < 0) {
274  return false;
275  } else {
276  removeAt(index);
277  return true;
278  }
279  }
280 
287  V* extract(const K& key)
288  {
289  int i = indexOf(key);
290  return (i < 0) ? nullptr : extractAt(i);
291  }
292 
299  V* extractAt(unsigned index)
300  {
301  V* value = nullptr;
302  if(index < entries.count()) {
303  value = entries[index].value;
304  entries[index].value = nullptr;
305  entries.remove(index);
306  }
307  return value;
308  }
309 
313  void clear()
314  {
315  entries.clear();
316  }
317 
318 protected:
322  struct Entry {
323  K key;
324  V* value = nullptr;
325 
326  Entry(const K& key, V* value) : key(key), value(value)
327  {
328  }
329 
331  {
332  delete value;
333  }
334  };
335 
337 
338 private:
339  // Copy constructor unsafe, so prevent access
340  ObjectMap(ObjectMap<K, V>& that);
341 };
void removeAt(unsigned index)
Remove entry at given index.
Definition: ObjectMap.h:260
V * extract()
Get the value for a given key and remove it from the map, without destroying it.
Definition: ObjectMap.h:110
Vector< Entry > entries
Definition: ObjectMap.h:336
Implementation of a HashMap for owned objects, i.e. anything created with new().
Definition: ObjectMap.h:47
K & keyAt(unsigned idx)
Definition: ObjectMap.h:144
Value valueAt(unsigned idx)
Definition: ObjectMap.h:166
Vector class template.
Definition: WVector.h:29
Class to provide safe access to mapped value.
Definition: ObjectMap.h:63
const V * operator[](const K &key) const
Get value for given key, if it exists.
Definition: ObjectMap.h:177
unsigned count() const
Get the number of entries in this map.
Definition: ObjectMap.h:124
Value operator[](const K &key)
Access map entry by reference.
Definition: ObjectMap.h:189
K key
Definition: ObjectMap.h:323
~Entry()
Definition: ObjectMap.h:330
bool contains(const K &key) const
Check if a key is contained within this map.
Definition: ObjectMap.h:251
V * getValue() const
Definition: ObjectMap.h:75
const V * valueAt(unsigned idx) const
Definition: ObjectMap.h:155
ObjectMap()
Definition: ObjectMap.h:50
~ObjectMap()
Definition: ObjectMap.h:54
void clear()
Clear the map of all entries.
Definition: ObjectMap.h:313
V * extractAt(unsigned index)
Get the value at a given index and remove it from the map, without destroying it. ...
Definition: ObjectMap.h:299
int indexOf(const K &key) const
Get the index of a key.
Definition: ObjectMap.h:236
V * operator->() const
Definition: ObjectMap.h:91
const K & getKey() const
Definition: ObjectMap.h:70
Entry(const K &key, V *value)
Definition: ObjectMap.h:326
An entry in the ObjectMap.
Definition: ObjectMap.h:322
const K & keyAt(unsigned idx) const
Definition: ObjectMap.h:134
V * extract(const K &key)
Get the value for a given key and remove it from the map, without destroying it.
Definition: ObjectMap.h:287
Value(ObjectMap< K, V > &map, const K &key)
Definition: ObjectMap.h:66
V * find(const K &key) const
Find the value for a given key, if it exists.
Definition: ObjectMap.h:225
Value & operator=(V *newValue)
Definition: ObjectMap.h:80