utility 2026.1.9
A comprehensive C++ utilities library tailored for the development of modern desktop and extended reality (XR) applications.
Loading...
Searching...
No Matches
cache.hpp
1/*
2 Copyright (c) 2026 ETIB Corporation
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in
6 the Software without restriction, including without limitation the rights to
7 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8 of the Software, and to permit persons to whom the Software is furnished to do
9 so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 SOFTWARE.
21 */
22
23#pragma once
24
25#include <map>
26#include <mutex>
27#include <optional>
28#include <shared_mutex>
29#include <utility>
30#include <functional>
31#include <concepts>
32
33namespace utility
34{
35
40 template<typename T>
41 concept CacheEntry = std::movable<T>;
42
48 template<typename Key, typename Compare = std::less<Key>>
49 concept CacheKey = requires(const Key &a, const Key &b, Compare comp) {
50 { comp(a, b) } -> std::convertible_to<bool>;
51 };
52
66 template<typename Key, CacheEntry Entry, typename Compare = std::less<Key>>
68 class Cache
69 {
70 private:
71 std::map<Key, Entry, Compare>
72 _entries;
74 mutable std::shared_mutex _mutex;
75
76 public:
80 Cache(void) = default;
81
85 ~Cache(void) = default;
86
90 Cache(const Cache &other) = delete;
91
96 Cache &operator=(const Cache &other) = delete;
97
101 Cache(Cache &&other) noexcept = delete;
102
107 Cache &operator=(Cache &&other) noexcept = delete;
108
114 bool contains(const Key &key) const
115 {
116 std::shared_lock<std::shared_mutex> guard(_mutex);
117 return _entries.find(key) != _entries.end();
118 }
119
126 std::optional<Entry> get(const Key &key) const
127 {
128 std::shared_lock<std::shared_mutex> guard(_mutex);
129 auto it = _entries.find(key);
130 if (it == _entries.end()) {
131 return std::nullopt;
132 }
133 return it->second;
134 }
135
141 void put(const Key &key, const Entry &value)
142 {
143 std::unique_lock<std::shared_mutex> guard(_mutex);
144 _entries.insert_or_assign(key, value);
145 }
146
153 void put(Key &&key, Entry &&value)
154 {
155 std::unique_lock<std::shared_mutex> guard(_mutex);
156 _entries.insert_or_assign(std::move(key), std::move(value));
157 }
158
170 template<typename... Args>
171 Entry &emplace(const Key &key, Args &&...args)
172 {
173 std::unique_lock<std::shared_mutex> guard(_mutex);
174 auto [it, inserted] =
175 _entries.try_emplace(key, std::forward<Args>(args)...);
176 return it->second;
177 }
178
190 template<typename... Args> Entry &emplace(Key &&key, Args &&...args)
191 {
192 std::unique_lock<std::shared_mutex> guard(_mutex);
193 auto [it, inserted] = _entries.try_emplace(
194 std::move(key), std::forward<Args>(args)...);
195 return it->second;
196 }
197
203 bool erase(const Key &key)
204 {
205 std::unique_lock<std::shared_mutex> guard(_mutex);
206 return _entries.erase(key) > 0;
207 }
208
215 const std::function<bool(const Key &, const Entry &)> &predicate)
216 {
217 std::unique_lock<std::shared_mutex> guard(_mutex);
218 for (auto it = _entries.begin(); it != _entries.end();) {
219 if (predicate(it->first, it->second)) {
220 it = _entries.erase(it);
221 } else {
222 ++it;
223 }
224 }
225 }
226
232 void apply(const std::function<void(const Key &, Entry &)> &function)
233 {
234 std::unique_lock<std::shared_mutex> guard(_mutex);
235 for (auto &[key, entry]: _entries) {
236 function(key, entry);
237 }
238 }
239
243 void clear(void)
244 {
245 std::unique_lock<std::shared_mutex> guard(_mutex);
246 _entries.clear();
247 }
248
253 std::map<Key, Entry, Compare>::size_type size(void) const
254 {
255 std::shared_lock<std::shared_mutex> guard(_mutex);
256 return _entries.size();
257 }
258
263 bool empty(void) const
264 {
265 std::shared_lock<std::shared_mutex> guard(_mutex);
266 return _entries.empty();
267 }
268 };
269
270} // namespace utility
A thread-safe cache for storing key-value pairs.
Definition cache.hpp:69
bool contains(const Key &key) const
Check if the cache contains a specific key.
Definition cache.hpp:114
~Cache(void)=default
Default destructor for the Cache class.
Cache(const Cache &other)=delete
Deleted copy constructor to prevent copying of the cache.
std::optional< Entry > get(const Key &key) const
Retrieve the value associated with a specific key.
Definition cache.hpp:126
Entry & emplace(const Key &key, Args &&...args)
Emplace a new entry in the cache with the given key and constructor arguments.
Definition cache.hpp:171
bool erase(const Key &key)
Remove an entry from the cache.
Definition cache.hpp:203
void put(Key &&key, Entry &&value)
Add or update a key-value pair in the cache using move semantics.
Definition cache.hpp:153
Cache(void)=default
Default constructor for the Cache class.
Cache & operator=(Cache &&other) noexcept=delete
Deleted move assignment operator to prevent moving of the cache.
bool empty(void) const
Check if the cache is empty.
Definition cache.hpp:263
void put(const Key &key, const Entry &value)
Add or update a key-value pair in the cache.
Definition cache.hpp:141
void erase_if(const std::function< bool(const Key &, const Entry &)> &predicate)
Remove entries from the cache based on a predicate.
Definition cache.hpp:214
Cache & operator=(const Cache &other)=delete
Deleted copy assignment operator to prevent copying of the cache.
std::map< Key, Entry, Compare >::size_type size(void) const
Get the number of entries in the cache.
Definition cache.hpp:253
void apply(const std::function< void(const Key &, Entry &)> &function)
Apply a function to each entry in the cache.
Definition cache.hpp:232
Entry & emplace(Key &&key, Args &&...args)
Emplace a new entry in the cache with the given key and constructor arguments using move semantics.
Definition cache.hpp:190
void clear(void)
Clear all entries from the cache.
Definition cache.hpp:243
Cache(Cache &&other) noexcept=delete
Deleted move constructor to prevent moving of the cache.
Concept to constrain cache entry type.
Definition cache.hpp:41
Concept to constrain cache key type.
Definition cache.hpp:49
The utility namespace contains classes and functions for the utility project.
Definition cache.hpp:34