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 = entries.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 = entries.indexOf(key);
228  return (index < 0) ? nullptr : entries[index].value.get();
229  }
230 
236  int indexOf(const K& key) const
237  {
238  return entries.indexOf(key);
239  }
240 
246  bool contains(const K& key) const
247  {
248  return entries.contains(key);
249  }
250 
255  void removeAt(unsigned index)
256  {
257  entries.remove(index);
258  }
259 
265  bool remove(const K& key)
266  {
267  int index = indexOf(key);
268  if(index < 0) {
269  return false;
270  }
271  removeAt(index);
272  return true;
273  }
274 
281  V* extract(const K& key)
282  {
283  int i = indexOf(key);
284  return (i < 0) ? nullptr : extractAt(i);
285  }
286 
293  V* extractAt(unsigned index)
294  {
295  std::unique_ptr<V> value;
296  if(index < entries.count()) {
297  entries[index].value.swap(value);
298  entries.remove(index);
299  }
300  return value.release();
301  }
302 
306  void clear()
307  {
308  entries.clear();
309  }
310 
311 protected:
315  struct Entry {
316  K key;
317  std::unique_ptr<V> value;
318 
319  bool operator==(const K& keyToFind) const
320  {
321  return key == keyToFind;
322  }
323 
324  Entry(const K& key, V* value) : key(key)
325  {
326  this->value.reset(value);
327  }
328  };
329 
331 
332 private:
333  // Copy constructor unsafe, so prevent access
334  ObjectMap(ObjectMap<K, V>& that);
335 };
long map(long, long, long, long, long)
void size_t const void * key
Definition: blake2s.h:33
Class to provide safe access to mapped value.
Definition: ObjectMap.h:65
V * operator->() const
Definition: ObjectMap.h:92
const K & getKey() const
Definition: ObjectMap.h:71
Value(ObjectMap< K, V > &map, const K &key)
Definition: ObjectMap.h:67
V * getValue() const
Definition: ObjectMap.h:76
V * extract()
Get the value for a given key and remove it from the map, without destroying it.
Definition: ObjectMap.h:111
bool remove()
Remove this value from the map.
Definition: ObjectMap.h:101
Value & operator=(V *newValue)
Definition: ObjectMap.h:81
Implementation of a HashMap for owned objects, i.e. anything created with new().
Definition: ObjectMap.h:49
Value valueAt(unsigned idx)
Definition: ObjectMap.h:167
unsigned count() const
Get the number of entries in this map.
Definition: ObjectMap.h:125
void removeAt(unsigned index)
Remove entry at given index.
Definition: ObjectMap.h:255
V * find(const K &key) const
Find the value for a given key, if it exists.
Definition: ObjectMap.h:225
~ObjectMap()
Definition: ObjectMap.h:55
ObjectMap()
Definition: ObjectMap.h:51
V * extract(const K &key)
Get the value for a given key and remove it from the map, without destroying it.
Definition: ObjectMap.h:281
V * extractAt(unsigned index)
Get the value at a given index and remove it from the map, without destroying it.
Definition: ObjectMap.h:293
void clear()
Clear the map of all entries.
Definition: ObjectMap.h:306
Value get(const K &key)
Get map entry value.
Definition: ObjectMap.h:200
const V * operator[](const K &key) const
Get value for given key, if it exists.
Definition: ObjectMap.h:178
int indexOf(const K &key) const
Get the index of a key.
Definition: ObjectMap.h:236
Vector< Entry > entries
Definition: ObjectMap.h:330
bool remove(const K &key)
Remove a key from this map.
Definition: ObjectMap.h:265
bool contains(const K &key) const
Check if a key is contained within this map.
Definition: ObjectMap.h:246
const K & keyAt(unsigned idx) const
Definition: ObjectMap.h:135
void set(const K &key, V *value)
Set a key value.
Definition: ObjectMap.h:209
const V * valueAt(unsigned idx) const
Definition: ObjectMap.h:156
Value operator[](const K &key)
Access map entry by reference.
Definition: ObjectMap.h:190
K & keyAt(unsigned idx)
Definition: ObjectMap.h:145
Vector class template.
Definition: WVector.h:32
Value
Definition: Components/IFS/src/include/IFS/Error.h:82
An entry in the ObjectMap.
Definition: ObjectMap.h:315
K key
Definition: ObjectMap.h:316
Entry(const K &key, V *value)
Definition: ObjectMap.h:324
std::unique_ptr< V > value
Definition: ObjectMap.h:317
bool operator==(const K &keyToFind) const
Definition: ObjectMap.h:319