knx
ETS configurable knx-stack
simple_map.h
Go to the documentation of this file.
1 #pragma once
2 
3 // Provides a simple unordered map which is based on two arrays of different data types, namely K and V.
4 // One array is used for the keys, the other array is used for the values.
5 // Tracking of free/occupied slots in the arrays is realized by a bitmask of size uint64_t.
6 // As a result the maximum size of the map is 64 entries.
7 // If a non-primitive data type is required for the key by using a "class" or "struct",
8 // then the operator== has to be provided by that class/struct:
9 // bool operator ==(const K&) const { return true/false; }
10 
11 template <typename K, typename V, int SIZE>
12 class Map
13 {
14  public:
15  Map()
16  {
17  static_assert (SIZE <= 64, "Map is too big! Max. 64 elements.");
18  }
19 
20  void clear()
21  {
22  _validEntries = 0;
23  }
24 
25  bool empty()
26  {
27  return (_validEntries == 0);
28  }
29 
30  uint8_t size()
31  {
32  uint8_t size = 0;
33 
34  for (uint8_t i = 0; i < SIZE; i++)
35  {
36  size += (((_validEntries >> i) & 0x01) == 0x01) ? 1 : 0;
37  }
38 
39  return size;
40  }
41 
42  bool insert(K key, V value)
43  {
44  uint8_t index = getNextFreeIndex();
45 
46  if (index != noFreeEntryFoundIndex)
47  {
48  keys[index] = key;
49  values[index] = value;
50 
51  _validEntries |= 1 << index;
52  return true;
53  }
54 
55  // No free space
56  return false;
57  }
58 
59  bool insertOrAssign(K key, V value)
60  {
61  // Try to find the key
62  for (uint8_t i = 0; i < SIZE; i++)
63  {
64  // Check if this array slot is occupied
65  if ((_validEntries >> i) & 0x01)
66  {
67  // Key found?
68  if (keys[i] == key)
69  {
70  values[i] = value;
71  return true;
72  }
73  }
74  }
75 
76  // Key does not exist, add it if enough space
77  return insert(key, value);
78  }
79 
80  bool erase(K key)
81  {
82  for (uint8_t i = 0; i < SIZE; i++)
83  {
84  if ((_validEntries >> i) & 0x01)
85  {
86  if (keys[i] == key)
87  {
88  _validEntries &= ~(1 << i);
89  return true;
90  }
91  }
92  }
93 
94  return false;
95  }
96 
97  V* get(K key)
98  {
99  // Try to find the key
100  for (uint8_t i = 0; i < SIZE; i++)
101  {
102  // Check if this array slot is occupied
103  if ((_validEntries >> i) & 0x01)
104  {
105  // Key found?
106  if (keys[i] == key)
107  {
108  return &values[i];
109  }
110  }
111  }
112 
113  return nullptr;
114  }
115 
116  private:
117  uint8_t getNextFreeIndex()
118  {
119  for (uint8_t i = 0; i < SIZE; i++)
120  {
121  if (((_validEntries >> i) & 0x01) == 0)
122  {
123  return i;
124  }
125  }
126 
127  return noFreeEntryFoundIndex;
128  }
129 
130  uint64_t _validEntries{0};
131  K keys[SIZE];
132  V values[SIZE];
133  static constexpr uint8_t noFreeEntryFoundIndex = 255;
134 };
Definition: simple_map.h:13
bool insertOrAssign(K key, V value)
Definition: simple_map.h:59
uint8_t size()
Definition: simple_map.h:30
bool empty()
Definition: simple_map.h:25
Map()
Definition: simple_map.h:15
bool insert(K key, V value)
Definition: simple_map.h:42
bool erase(K key)
Definition: simple_map.h:80
V * get(K key)
Definition: simple_map.h:97
void clear()
Definition: simple_map.h:20