Sming Framework API
Sming - Open Source framework for high efficiency WiFi SoC ESP8266 native development with C++ language.
ObjectMap.h
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 #ifndef _SMING_CORE_DATA_OBJECT_MAP_H_
14 #define _SMING_CORE_DATA_OBJECT_MAP_H_
15 
16 #include "WVector.h"
17 
48 template <typename K, typename V> class ObjectMap
49 {
50 public:
51  ObjectMap()
52  {
53  }
54 
55  ~ObjectMap()
56  {
57  clear();
58  }
59 
64  class Value
65  {
66  public:
67  Value(ObjectMap<K, V>& map, const K& key) : map(map), key(key)
68  {
69  }
70 
71  const K& getKey() const
72  {
73  return key;
74  }
75 
76  V* getValue() const
77  {
78  return map.find(key);
79  }
80 
81  Value& operator=(V* newValue)
82  {
83  map.set(key, newValue);
84  return *this;
85  }
86 
87  operator V*() const
88  {
89  return getValue();
90  }
91 
92  V* operator->() const
93  {
94  return getValue();
95  }
96 
101  bool remove()
102  {
103  return map.remove(key);
104  }
105 
111  V* extract()
112  {
113  return map.extract(key);
114  }
115 
116  private:
117  ObjectMap<K, V>& map;
118  K key;
119  };
120 
125  unsigned count() const
126  {
127  return entries.count();
128  }
129 
130  /*
131  * @brief Get a key at a specified index, non-modifiable
132  * @param idx the index to get the key at
133  * @return The key at index idx
134  */
135  const K& keyAt(unsigned idx) const
136  {
137  return entries[idx].key;
138  }
139 
140  /*
141  * @brief Get a key at a specified index
142  * @param idx the index to get the key at
143  * @return Reference to the key at index idx
144  */
145  K& keyAt(unsigned idx)
146  {
147  return entries[idx].key;
148  }
149 
150  /*
151  * @brief Get a value at a specified index, non-modifiable
152  * @param idx the index to get the value at
153  * @retval The value at index idx
154  * @note The caller must not use `delete` on the returned value
155  */
156  const V* valueAt(unsigned idx) const
157  {
158  return entries[idx].value;
159  }
160 
161  /*
162  * @brief Get a value at a specified index
163  * @param idx the index to get the value at
164  * @retval Value Reference to value at index idx
165  * @see `operator[]`
166  */
167  Value valueAt(unsigned idx)
168  {
169  return Value(*this, entries[idx].key);
170  }
171 
178  const V* operator[](const K& key) const
179  {
180  return find(key);
181  }
182 
190  Value operator[](const K& key)
191  {
192  return get(key);
193  }
194 
200  Value get(const K& key)
201  {
202  return Value(*this, key);
203  }
204 
209  void set(const K& key, V* value)
210  {
211  int i = indexOf(key);
212  if(i >= 0) {
213  delete entries[i].value;
214  entries[i].value = value;
215  } else {
216  entries.addElement(new Entry(key, value));
217  }
218  }
219 
226  V* find(const K& key) const
227  {
228  int index = indexOf(key);
229  return (index < 0) ? nullptr : entries[index].value;
230  }
231 
237  int indexOf(const K& key) const
238  {
239  for(unsigned i = 0; i < entries.count(); i++) {
240  if(entries[i].key == key) {
241  return i;
242  }
243  }
244  return -1;
245  }
246 
252  bool contains(const K& key) const
253  {
254  return indexOf(key) >= 0;
255  }
256 
261  void removeAt(unsigned index)
262  {
263  entries.remove(index);
264  }
265 
271  bool remove(const K& key)
272  {
273  int index = indexOf(key);
274  if(index < 0) {
275  return false;
276  } else {
277  removeAt(index);
278  return true;
279  }
280  }
281 
288  V* extract(const K& key)
289  {
290  int i = indexOf(key);
291  return (i < 0) ? nullptr : extractAt(i);
292  }
293 
300  V* extractAt(unsigned index)
301  {
302  V* value = nullptr;
303  if(index < entries.count()) {
304  value = entries[index].value;
305  entries[index].value = nullptr;
306  entries.remove(index);
307  }
308  return value;
309  }
310 
314  void clear()
315  {
316  entries.clear();
317  }
318 
319 protected:
323  struct Entry {
324  K key;
325  V* value = nullptr;
326 
327  Entry(const K& key, V* value) : key(key), value(value)
328  {
329  }
330 
331  ~Entry()
332  {
333  delete value;
334  }
335  };
336 
337  Vector<Entry> entries;
338 
339 private:
340  // Copy constructor unsafe, so prevent access
341  ObjectMap(ObjectMap<K, V>& that);
342 };
343 
344 #endif // _SMING_CORE_DATA_OBJECT_MAP_H_
void removeAt(unsigned index)
Remove entry at given index.
Definition: ObjectMap.h:261
V * extract()
Get the value for a given key and remove it from the map, without destroying it.
Definition: ObjectMap.h:111
Implementation of a HashMap for owned objects, i.e. anything created with new().
Definition: ObjectMap.h:48
bool contains(const K &key) const
Check if a key is contained within this map.
Definition: ObjectMap.h:252
Definition: WVector.h:26
Class to provide safe access to mapped value.
Definition: ObjectMap.h:64
void set(const K &key, V *value)
Set a key value.
Definition: ObjectMap.h:209
Value operator[](const K &key)
Access map entry by reference.
Definition: ObjectMap.h:190
bool remove(const K &key)
Remove a key from this map.
Definition: ObjectMap.h:271
void clear()
Clear the map of all entries.
Definition: ObjectMap.h:314
int indexOf(const K &key) const
Get the index of a key.
Definition: ObjectMap.h:237
unsigned count() const
Get the number of entries in this map.
Definition: ObjectMap.h:125
V * extractAt(unsigned index)
Get the value at a given index and remove it from the map, without destroying it. ...
Definition: ObjectMap.h:300
An entry in the ObjectMap.
Definition: ObjectMap.h:323
V * extract(const K &key)
Get the value for a given key and remove it from the map, without destroying it.
Definition: ObjectMap.h:288
const V * operator[](const K &key) const
Get value for given key, if it exists.
Definition: ObjectMap.h:178
V * find(const K &key) const
Find the value for a given key, if it exists.
Definition: ObjectMap.h:226