26 #ifndef CASADI_GENERIC_SHARED_HPP
27 #define CASADI_GENERIC_SHARED_HPP
29 #include "casadi_common.hpp"
30 #include "exception.hpp"
31 #include <unordered_map>
34 #ifdef CASADI_WITH_THREAD
35 #ifdef CASADI_WITH_THREAD_MINGW
36 #include <mingw.mutex.h>
47 template<
typename Shared,
typename Internal>
52 template<
typename Shared,
typename Internal>
53 class GenericSharedInternal;
55 template<
typename Shared,
typename Internal>
56 class GenericWeakRefInternal;
59 template<
typename Shared,
typename Internal>
63 template<
class B,
class S>
friend const B
shared_cast(
const S& A);
89 void own(Internal* node);
96 void assign(Internal* node);
99 Internal* get()
const;
102 casadi_int getCount()
const;
108 Internal* operator->()
const;
112 std::string debug_repr()
const;
116 bool is_null()
const;
123 casadi_int __hash__()
const;
140 template<
typename Shared,
typename Internal>
160 Shared shared()
const;
170 bool shared_if_alive(Shared& shared)
const;
182 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
183 std::shared_ptr<std::mutex> get_mutex()
const;
207 template<
class B,
class S>
211 typename S::internal_base_type* ptr = A.get();
217 if (!B::test_cast(ptr))
return ret;
229 template<
class B,
class S>
232 return shared_cast<B, S>(A_copy);
241 template<
typename K,
typename T>
244 void tocache(
const K& key,
const T& f,
bool needs_lock=
true) {
245 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
250 cache_.insert(std::make_pair(key, f));
252 for (
auto it = cache_.begin(); it!=cache_.end(); ++it) {
253 if (!it->second.alive()) {
268 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
270 std::lock_guard<std::mutex> lock(mtx_);
272 if (!incache(key, f,
false)) {
273 tocache(key, f,
false);
276 bool incache(
const K& key, T& f,
bool needs_lock=
true)
const {
277 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
281 auto it = cache_.find(key);
282 typename T::base_type temp;
283 if (it!=cache_.end() && it->second.shared_if_alive(temp)) {
284 f = shared_cast<T>(temp);
290 void cache(std::vector<K>& keys, std::vector<T>& entries)
const {
291 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
293 std::lock_guard<std::mutex> lock(mtx_);
298 for (
auto&& cf : cache_) {
299 typename T::base_type temp;
300 if (cf.second.shared_if_alive(temp)) {
301 keys.push_back(cf.first);
302 entries.push_back(shared_cast<T>(temp));
307 std::unordered_map<K,
310 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
311 mutable std::mutex mtx_;
317 #pragma GCC diagnostic push
318 #if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ == 12)
319 #pragma GCC diagnostic ignored "-Wuse-after-free"
326 template<
typename K,
typename T>
329 void tocache(
const K& key,
const T& f,
bool needs_lock=
true) {
330 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
335 const void* k = key.get();
336 pre_cache_.insert(std::make_pair(k, key));
337 cache_.insert(std::make_pair(k, f));
339 for (
auto it = pre_cache_.begin(); it!=pre_cache_.end(); ++it) {
340 if (!it->second.alive()) {
341 pre_cache_.erase(it);
342 cache_.erase(it->first);
356 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
358 std::lock_guard<std::mutex> lock(mtx_);
360 if (!incache(key, f,
false)) {
361 tocache(key, f,
false);
364 bool incache(
const K& key, T& f,
bool needs_lock=
true)
const {
365 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
369 const void* k = key.get();
370 auto it = pre_cache_.find(k);
372 if (it!=pre_cache_.end() && it->second.shared_if_alive(temp)) {
373 auto it2 = cache_.find(k);
381 std::unordered_map<
const void*,
384 std::unordered_map<const void*, T> cache_;
385 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
386 mutable std::mutex mtx_;
390 #pragma GCC diagnostic pop
friend const B shared_cast(const S &A)
Typecast a shared object to a base class to a shared object to a derived class,.
GenericShared(const GenericShared &ref)
Copy constructor (shallow copy)
GenericShared()
Default constructor.
~GenericShared()
Destructor.
friend B shared_cast(S &A)
Typecast a shared object to a base class to a shared object to a derived class,.
void tocache_if_missing(const K &key, T &f)
void tocache(const K &key, const T &f, bool needs_lock=true)
bool incache(const K &key, T &f, bool needs_lock=true) const
void tocache(const K &key, const T &f, bool needs_lock=true)
bool incache(const K &key, T &f, bool needs_lock=true) const
void cache(std::vector< K > &keys, std::vector< T > &entries) const
void tocache_if_missing(const K &key, T &f)
B shared_cast(S &A)
Typecast a shared object to a base class to a shared object to a derived class,.