Cbeam
Loading...
Searching...
No Matches
thread_safe_map.hpp
Go to the documentation of this file.
1/*
2Copyright (c) 2025 acrion innovations GmbH
3Authors: Stefan Zipproth, s.zipproth@acrion.ch
4
5This file is part of Cbeam, see https://github.com/acrion/cbeam and https://cbeam.org
6
7Cbeam is offered under a commercial and under the AGPL license.
8For commercial licensing, contact us at https://acrion.ch/sales. For AGPL licensing, see below.
9
10AGPL licensing:
11
12Cbeam is free software: you can redistribute it and/or modify
13it under the terms of the GNU Affero General Public License as published by
14the Free Software Foundation, either version 3 of the License, or
15(at your option) any later version.
16
17Cbeam is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU Affero General Public License for more details.
21
22You should have received a copy of the GNU Affero General Public License
23along with Cbeam. If not, see <https://www.gnu.org/licenses/>.
24*/
25
26#pragma once
27
29#include <cbeam/error/out_of_range.hpp> // for cbeam::error::out_of_range
30#include <cbeam/error/runtime_error.hpp> // for cbeam::error::runtime_error
31#include <cbeam/lifecycle/scoped_set.hpp> // for cbeam::lifecycle::scoped_set
32
33#include <cassert> // for assert
34#include <stdexcept> // for std::out_of_range
35#include <cstddef> // for std::size_t
36
37#include <atomic> // for std::atomic
38#include <map> // for std::map
39#include <mutex> // for std::recursive_mutex, std::lock_guard
40#include <string> // for std::string, std::allocator
41#include <utility> // for std::pair
42
43namespace cbeam::container
44{
49 template <typename Key, typename Value>
50 class thread_safe_map : public thread_safe_container<std::map<Key, Value>>
51 {
52 public:
59 Value& at(const Key& key, const std::string& what_arg = "Key not found")
60 {
61 std::lock_guard<std::recursive_mutex> lock(this->_mutex);
62 if (this->_is_being_modified)
63 {
64 throw cbeam::error::runtime_error("cbeam::container::thread_safe_map::at: not allowed during destruction of the map.");
65 }
66
67 try
68 {
69 return this->_container.at(key);
70 }
71 catch (const std::out_of_range&)
72 {
73 throw cbeam::error::out_of_range(what_arg);
74 }
75 }
76
83 auto find(const Key& key, const std::string& what_arg = {})
84 {
85 std::lock_guard<std::recursive_mutex> lock(this->_mutex);
86 if (this->_is_being_modified)
87 {
88 throw cbeam::error::runtime_error("cbeam::container::thread_safe_map::find: not allowed during modification of the map.");
89 }
90 auto it = this->_container.find(key);
91 if (!what_arg.empty() && it == this->_container.end())
92 {
93 throw cbeam::error::out_of_range(what_arg);
94 }
95 return it;
96 }
97
102 Value& operator[](const Key& key)
103 {
104 std::lock_guard<std::recursive_mutex> lock(this->_mutex);
105 if (this->_is_being_modified)
106 {
107 throw cbeam::error::runtime_error("cbeam::container::thread_safe_map::operator[]: not allowed during modification of the map.");
108 }
109 return this->_container[key];
110 }
111
116 std::size_t erase(const Key& key)
117 {
118 std::lock_guard<std::recursive_mutex> lock(this->_mutex);
119 if (this->_is_being_modified)
120 {
121 throw cbeam::error::runtime_error("cbeam::container::thread_safe_map::erase: not allowed during modification of the map.");
122 }
124 return this->_container.erase(key);
125 }
126
137 typename std::map<Key, Value>::iterator erase(typename std::map<Key, Value>::iterator position)
138 {
139 std::lock_guard<std::recursive_mutex> lock(this->_mutex);
140 if (this->_is_being_modified)
141 {
142 throw cbeam::error::runtime_error("cbeam::container::thread_safe_map::erase: not allowed during modification of the map.");
143 }
144 lifecycle::scoped_set modifying(this->_is_being_modified, true);
145 return this->_container.erase(position);
146 }
147
151 std::size_t count(const Key& key) const
152 {
153 std::lock_guard<std::recursive_mutex> lock(this->_mutex);
154 return this->_container.count(key);
155 }
156
157 std::pair<typename std::map<Key, Value>::iterator, bool> insert(const Key& key, const Value& value)
158 {
159 std::lock_guard<std::recursive_mutex> lock(this->_mutex);
160 if (this->_is_being_modified)
161 {
162 throw cbeam::error::runtime_error("cbeam::container::thread_safe_map::insert: not allowed during modification of the map.");
163 }
164 lifecycle::scoped_set modifying(this->_is_being_modified, true);
165 return this->_container.insert({key, value});
166 }
167
178 std::pair<typename std::map<Key, Value>::iterator, bool> insert(const std::pair<Key, Value>& pair)
179 {
180 std::lock_guard<std::recursive_mutex> lock(this->_mutex);
181 if (this->_is_being_modified)
182 {
183 throw cbeam::error::runtime_error("cbeam::container::thread_safe_map::insert: not allowed during modification of the map.");
184 }
185 lifecycle::scoped_set modifying(this->_is_being_modified, true);
186 return this->_container.insert(pair);
187 }
188 };
189}
std::map< Key, Value > _container
Definition thread_safe_container.hpp:156
std::atomic< bool > _is_being_modified
Definition thread_safe_container.hpp:157
std::recursive_mutex _mutex
Definition thread_safe_container.hpp:155
Thread-safe wrapper for std::map.
Definition thread_safe_map.hpp:51
std::pair< typename std::map< Key, Value >::iterator, bool > insert(const std::pair< Key, Value > &pair)
Inserts a new element or assigns to the current element if the key already exists.
Definition thread_safe_map.hpp:178
Value & operator[](const Key &key)
Access or insert specified element.
Definition thread_safe_map.hpp:102
std::map< Key, Value >::iterator erase(typename std::map< Key, Value >::iterator position)
Removes the element at the specified position.
Definition thread_safe_map.hpp:137
auto find(const Key &key, const std::string &what_arg={})
Finds an element with a specific key.
Definition thread_safe_map.hpp:83
std::size_t erase(const Key &key)
Removes the element with the specified key.
Definition thread_safe_map.hpp:116
std::size_t count(const Key &key) const
Returns the number of elements matching specific key.
Definition thread_safe_map.hpp:151
std::pair< typename std::map< Key, Value >::iterator, bool > insert(const Key &key, const Value &value)
Definition thread_safe_map.hpp:157
Value & at(const Key &key, const std::string &what_arg="Key not found")
Access specified element with bounds checking.
Definition thread_safe_map.hpp:59
A Cbeam-specific out_of_range error that also behaves like std::out_of_range.
Definition out_of_range.hpp:50
A Cbeam-specific runtime error that also acts like std::runtime_error.
Definition runtime_error.hpp:46
A helper that sets the given variable to a new value, and restores the original value on destruction.
Definition scoped_set.hpp:61
Offers advanced container types with unique approaches to stability and interprocess sharing....
Definition buffer.hpp:44