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 #include <memory>
17 
48 template <typename K, typename V> class ObjectMap
49 {
50 public:
52  {
53  }
54 
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  entries[i].value.reset(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.get();
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  std::unique_ptr<V> value;
302  if(index < entries.count()) {
303  entries[index].value.swap(value);
304  entries.remove(index);
305  }
306  return value.release();
307  }
308 
312  void clear()
313  {
314  entries.clear();
315  }
316 
317 protected:
321  struct Entry {
322  K key;
323  std::unique_ptr<V> value;
324 
325  Entry(const K& key, V* value) : key(key)
326  {
327  this->value.reset(value);
328  }
329  };
330 
332 
333 private:
334  // Copy constructor unsafe, so prevent access
335  ObjectMap(ObjectMap<K, V>& that);
336 };
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:111
Vector< Entry > entries
Definition: ObjectMap.h:331
Implementation of a HashMap for owned objects, i.e. anything created with new().
Definition: ObjectMap.h:48
K & keyAt(unsigned idx)
Definition: ObjectMap.h:145
Value valueAt(unsigned idx)
Definition: ObjectMap.h:167
Vector class template.
Definition: WVector.h:31
std::unique_ptr< V > value
Definition: ObjectMap.h:323
Class to provide safe access to mapped value.
Definition: ObjectMap.h:64
const V * operator[](const K &key) const
Get value for given key, if it exists.
Definition: ObjectMap.h:178
unsigned count() const
Get the number of entries in this map.
Definition: ObjectMap.h:125
Value operator[](const K &key)
Access map entry by reference.
Definition: ObjectMap.h:190
K key
Definition: ObjectMap.h:322
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:76
const V * valueAt(unsigned idx) const
Definition: ObjectMap.h:156
ObjectMap()
Definition: ObjectMap.h:51
~ObjectMap()
Definition: ObjectMap.h:55
void clear()
Clear the map of all entries.
Definition: ObjectMap.h:312
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:92
const K & getKey() const
Definition: ObjectMap.h:71
Entry(const K &key, V *value)
Definition: ObjectMap.h:325
An entry in the ObjectMap.
Definition: ObjectMap.h:321
const K & keyAt(unsigned idx) const
Definition: ObjectMap.h:135
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:67
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:81