FastLED 3.9.3
Loading...
Searching...
No Matches
fixed_map.h
1#pragma once
2
3#include <stdint.h>
4#include <stddef.h>
5
6#include "namespace.h"
7#include "fixed_vector.h"
8
9FASTLED_NAMESPACE_BEGIN
10
11// A simple unordered map implementation with a fixed size.
12// The user is responsible for making sure that the inserts
13// do not exceed the capacity of the set, otherwise they will
14// fail. Because of this limitation, this set is not a drop in
15// replacement for std::map.
16template<typename Key, typename Value, size_t N>
17class FixedMap {
18public:
19 struct Pair {
20 Key first = Key();
21 Value second = Value();
22 Pair(const Key& k, const Value& v) : first(k), second(v) {}
23 };
24
26 typedef typename VectorType::iterator iterator;
27 typedef typename VectorType::const_iterator const_iterator;
28
29
30 // Constructor
31 constexpr FixedMap() = default;
32
33 iterator begin() {
34 return data.begin();
35 }
36 iterator end() {
37 return data.end();
38 }
39 const_iterator begin() const {
40 return data.begin();
41 }
42 const_iterator end() const {
43 return data.end();
44 }
45
46 iterator find(const Key& key) {
47 for (auto it = begin(); it != end(); ++it) {
48 if (it->first == key) {
49 return it;
50 }
51 }
52 return end();
53 }
54
55 const_iterator find(const Key& key) const {
56 for (auto it = begin(); it != end(); ++it) {
57 if (it->first == key) {
58 return it;
59 }
60 }
61 return end();
62 }
63
64 // We differ from the std standard here so that we don't allow
65 // dereferencing the end iterator.
66 bool get(const Key& key, Value* value) const {
67 const_iterator it = find(key);
68 if (it != end()) {
69 *value = it->second;
70 return true;
71 }
72 return false;
73 }
74
75 Value get(const Key& key, bool* has=nullptr) const {
76 const_iterator it = find(key);
77 if (it != end()) {
78 if (has) {
79 *has = true;
80 }
81 return it->second;
82 }
83 if (has) {
84 *has = false;
85 }
86 return Value();
87 }
88
89 bool insert(const Key& key, const Value& value) {
90 iterator it = find(key);
91 if (it == end()) {
92 if (data.size() < N) {
93 data.push_back(Pair(key, value));
94 return true;
95 }
96 }
97 return false;
98 }
99
100 bool update(const Key& key, const Value& value, bool insert_if_missing = true) {
101 iterator it = find(key);
102 if (it != end()) {
103 it->second = value;
104 return true;
105 } else if (insert_if_missing) {
106 return insert(key, value);
107 }
108 return false;
109 }
110
111 Value& operator[](const Key& key) {
112 iterator it = find(key);
113 if (it != end()) {
114 return it->second;
115 }
116 data.push_back(Pair(key, Value()));
117 return data.back().second;
118 }
119
120 const Value& operator[](const Key& key) const {
121 const_iterator it = find(key);
122 if (it != end()) {
123 return it->second;
124 }
125 static Value default_value;
126 return default_value;
127 }
128
129 bool next(const Key& key, Key* next_key, bool allow_rollover = false) const {
130 const_iterator it = find(key);
131 if (it != end()) {
132 ++it;
133 if (it != end()) {
134 *next_key = it->first;
135 return true;
136 } else if (allow_rollover && !empty()) {
137 *next_key = begin()->first;
138 return true;
139 }
140 }
141 return false;
142 }
143
144 bool prev(const Key& key, Key* prev_key, bool allow_rollover = false) const {
145 const_iterator it = find(key);
146 if (it != end()) {
147 if (it != begin()) {
148 --it;
149 *prev_key = it->first;
150 return true;
151 } else if (allow_rollover && !empty()) {
152 *prev_key = data[data.size() - 1].first;
153 return true;
154 }
155 }
156 return false;
157 }
158
159
160 // Get the current size of the vector
161 constexpr size_t size() const {
162 return data.size();
163 }
164
165 constexpr bool empty() const {
166 return data.empty();
167 }
168
169 // Get the capacity of the vector
170 constexpr size_t capacity() const {
171 return N;
172 }
173
174 // Clear the vector
175 void clear() {
176 data.clear();
177 }
178
179 bool has(const Key& it) const {
180 return find(it) != end();
181 }
182private:
183 VectorType data;
184};
185
186FASTLED_NAMESPACE_END