@@ -83,7 +83,7 @@ class retained_topic_map {
83
83
topic,
84
84
[this , &parent](MQTT_NS::string_view t) {
85
85
if (t == " +" || t == " #" ) {
86
- throw std::runtime_error ( " No wildcards allowed in retained topic name " );
86
+ throw_no_wildcards_allowed ( );
87
87
}
88
88
89
89
node_id_t parent_id = parent->id ;
@@ -94,7 +94,7 @@ class retained_topic_map {
94
94
if (entry == direct_index.end ()) {
95
95
entry = map.insert (path_entry (parent->id , t, next_node_id++)).first ;
96
96
if (next_node_id == max_node_id) {
97
- throw std::overflow_error ( " Maximum number of topics reached " );
97
+ throw_max_stored_topics ( );
98
98
}
99
99
}
100
100
else {
@@ -136,7 +136,7 @@ class retained_topic_map {
136
136
// Match all underlying topics when a hash entry is matched
137
137
// perform a breadth-first iteration over all items in the tree below
138
138
template <typename Output>
139
- void match_hash_entries (node_id_t parent, Output callback, bool ignore_system) const {
139
+ void match_hash_entries (node_id_t parent, Output&& callback, bool ignore_system) const {
140
140
std::deque<node_id_t > entries;
141
141
entries.push_back (parent);
142
142
std::deque<node_id_t > new_entries;
@@ -170,7 +170,7 @@ class retained_topic_map {
170
170
171
171
// Find all topics that match the specified topic filter
172
172
template <typename Output>
173
- void find_match (MQTT_NS::string_view topic_filter, Output callback) const {
173
+ void find_match (MQTT_NS::string_view topic_filter, Output&& callback) const {
174
174
std::deque<direct_const_iterator> entries;
175
175
entries.push_back (root);
176
176
@@ -212,7 +212,7 @@ class retained_topic_map {
212
212
}
213
213
);
214
214
215
- for (auto entry : entries) {
215
+ for (auto & entry : entries) {
216
216
if (entry->value ) {
217
217
callback (*entry->value );
218
218
}
@@ -247,11 +247,30 @@ class retained_topic_map {
247
247
void increase_topics (std::vector<direct_const_iterator> const &path) {
248
248
auto & direct_index = map.template get <direct_index_tag>();
249
249
250
- for (auto i : path) {
250
+ for (auto & i : path) {
251
251
direct_index.modify (i, [](path_entry &entry){ ++entry.count ; });
252
252
}
253
253
}
254
254
255
+ // Exceptions used
256
+ static void throw_max_stored_topics () { throw std::overflow_error (" Retained map maximum number of topics reached" ); }
257
+ static void throw_no_wildcards_allowed () { throw std::runtime_error (" Retained map no wildcards allowed in retained topic name" ); }
258
+
259
+ // Increase the map size (total number of topics stored)
260
+ void increase_map_size () {
261
+ if (map_size == std::numeric_limits<decltype (map_size)>::max ()) {
262
+ throw_max_stored_topics ();
263
+ }
264
+
265
+ ++map_size;
266
+ }
267
+
268
+ // Decrease the map size (total number of topics stored)
269
+ void decrease_map_size (size_t count) {
270
+ BOOST_ASSERT (map_size >= count);
271
+ map_size -= count;
272
+ }
273
+
255
274
public:
256
275
retained_topic_map ()
257
276
{
@@ -268,14 +287,14 @@ class retained_topic_map {
268
287
if (path.empty ()) {
269
288
auto new_topic = this ->create_topic (topic);
270
289
direct_index.modify (new_topic, [&value](path_entry &entry) mutable { entry.value .emplace (std::forward<V>(value)); });
271
- ++map_size ;
290
+ increase_map_size () ;
272
291
return 1 ;
273
292
}
274
293
275
294
if (!path.back ()->value ) {
276
295
this ->increase_topics (path);
277
296
direct_index.modify (path.back (), [&value](path_entry &entry) mutable { entry.value .emplace (std::forward<V>(value)); });
278
- ++map_size ;
297
+ increase_map_size () ;
279
298
return 1 ;
280
299
}
281
300
@@ -285,14 +304,15 @@ class retained_topic_map {
285
304
}
286
305
287
306
// Find all stored topics that math the specified topic_filter
288
- void find (MQTT_NS::string_view topic_filter, std::function< void (Value const &) > const & callback) const {
289
- find_match (topic_filter, callback);
307
+ template <typename Output>
308
+ void find (MQTT_NS::string_view topic_filter, Output&& callback) const {
309
+ find_match (topic_filter, std::forward<Output>(callback));
290
310
}
291
311
292
312
// Remove a stored value at the specified topic
293
313
std::size_t erase (MQTT_NS::string_view topic) {
294
314
auto result = erase_topic (topic);
295
- map_size -= result;
315
+ decrease_map_size ( result) ;
296
316
return result;
297
317
}
298
318
0 commit comments