PLaSK library
Loading...
Searching...
No Matches
cache.hpp
Go to the documentation of this file.
1/*
2 * This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3 * Copyright (c) 2022 Lodz University of Technology
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#ifndef PLASK__UTILS_CACHE_H
15#define PLASK__UTILS_CACHE_H
16
21#include <map>
22#include "../memory.hpp"
23
24namespace plask {
25
35template <typename Key, typename ValuePtr>
37
39 std::map<Key*, ValuePtr> map;
40
41};
42
48template <typename Key, typename ValuePtr>
50
52 void onEvent(typename Key::Event& evt) {
53 if (evt.isDelete()) this->map.erase(&evt.source());
54 }
55
56};
57
63template <typename Key, typename ValuePtr>
64struct CacheRemoveOnEachChange: public CacheRemoveStrategyBase<Key, ValuePtr> {
65
67 void onEvent(typename Key::Event& evt) {
68 auto* src = evt.source();
69 src->changedDisconnectMethod(this, &CacheRemoveOnEachChange::onEvent);
70 this->map.erase(src);
71 }
72
73};
74
75template <typename Key, typename ValuePtr, template<typename SKey, typename SValuePtr> class DeleteStrategy = CacheRemoveOnlyWhenDeleted >
76struct CacheBase: public DeleteStrategy<Key, ValuePtr> {
77
78 typedef typename ValuePtr::element_type Value;
79
82 clear();
83 }
84
90 void append(Key* index, ValuePtr value) {
91 this->map[index] = value;
92 // index->changed.at_front(boost::bind(method, obj, _1));
93 index->changedConnectMethod(this, &DeleteStrategy<Key, ValuePtr>::onEvent, boost::signals2::at_front);
94 }
95
102 append(index.get(), value);
103 }
104
122 this->append(index, result);
123 return result;
124 }
125
142 this->append(index, value);
143 return value;
144 }
145
163 this->append(index, result);
164 return result;
165 }
166
183 this->append(index, value);
184 return value;
185 }
186
190 void clear() {
191 for (auto i: this->map)
192 i.first->changedDisconnectMethod(this, &DeleteStrategy<Key, ValuePtr>::onEvent);
193 this->map.clear();
194 }
195
196};
197
210template <typename Key, typename Value, template<typename SKey, typename SValuePtr> class DeleteStrategy = CacheRemoveOnlyWhenDeleted >
211struct WeakCache: public CacheBase<Key, plask::weak_ptr<Value>, DeleteStrategy> {
212
221 auto iter = this->map.find(index);
222 if (iter != this->map.end()) {
223 if (auto res = iter->second.lock())
224 return res;
225 else {
226 iter->first->changedDisconnectMethod(this, &DeleteStrategy<Key, plask::weak_ptr<Value> >::onEvent);
227 this->map.erase(iter);
228 }
229 }
231 }
232
241 return get(index.get());
242 }
243
250 auto constr_iter = this->map.find(index);
251 if (constr_iter != this->map.end()) {
252 if (auto res = constr_iter->second.lock())
253 return res;
254 }
256 }
257
264 return get(index.get());
265 }
266
273 for(auto i = this->map.begin(); i != this->map.end(); )
274 if (i->second.expired()) {
275 i->first.changedDisconnectMethod(this, &DeleteStrategy<Key, plask::weak_ptr<Value> >::onEvent);
276 this->map.erase(i++);
277 }
278 else ++i;
279 }
280
281};
282
295template <typename Key, typename Value, template<typename SKey, typename SValuePtr> class DeleteStrategy = CacheRemoveOnlyWhenDeleted >
296struct StrongCache: public CacheBase<Key, plask::shared_ptr<Value>, DeleteStrategy> {
297
304 auto iter = this->map.find(index);
305 return iter != this->map.end() ? iter->second : plask::shared_ptr<Value>();
306 }
307
314 return get(index.get());
315 }
316
317};
318
319} // namespace plask
320
321
322#endif // CACHE_H