From d9af70b624305b7c705b792da357c2ad94ff5473 Mon Sep 17 00:00:00 2001 From: klausspanderen Date: Sun, 30 Sep 2018 17:43:44 +0200 Subject: [PATCH 1/3] --enable-thread-safe-observer-pattern works with --enable-std-pointers closes #546 --- configure.ac | 4 +++- ql/patterns/observable.cpp | 4 ++++ ql/patterns/observable.hpp | 21 +++++++++++++++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 5ada077960a..f716fa0450f 100644 --- a/configure.ac +++ b/configure.ac @@ -261,7 +261,9 @@ AC_ARG_ENABLE([thread-safe-observer-pattern], enable it if you want to use QuantLib via the SWIG layer within the JVM or .NET eco system or any environment with an - async garbage collector.]), + async garbage collector. C++-17 is required + if this option is used together with + --enable-std-pointers]), [ql_use_tsop=$enableval], [ql_use_tsop=no]) AC_MSG_RESULT([$ql_use_tsop]) diff --git a/ql/patterns/observable.cpp b/ql/patterns/observable.cpp index 271390fba37..41895051353 100644 --- a/ql/patterns/observable.cpp +++ b/ql/patterns/observable.cpp @@ -129,7 +129,11 @@ namespace QuantLib { detail::Signal::signal_type::slot_type slot(&Observer::Proxy::update, observerProxy.get()); + #if defined(QL_USE_STD_SHARED_PTR) + sig_->connect(slot.track_foreign(observerProxy)); + #else sig_->connect(slot.track(observerProxy)); + #endif } void Observable::unregisterObserver( diff --git a/ql/patterns/observable.hpp b/ql/patterns/observable.hpp index 8f170de3e57..d2870aa0014 100644 --- a/ql/patterns/observable.hpp +++ b/ql/patterns/observable.hpp @@ -264,14 +264,26 @@ namespace QuantLib { #include #include + + namespace QuantLib { + namespace ext { + + #if defined(QL_USE_STD_SHARED_PTR) + using std::enable_shared_from_this; + #else + using boost::enable_shared_from_this; + #endif + + } + class Observable; class ObservableSettings; //! Object that gets notified when a given observable changes /*! \ingroup patterns */ - class Observer : public boost::enable_shared_from_this { + class Observer : public ext::enable_shared_from_this { friend class Observable; friend class ObservableSettings; public: @@ -318,9 +330,14 @@ namespace QuantLib { void update() const { boost::lock_guard lock(mutex_); if (active_) { + // c++17 is required if used with std::shared_ptr const ext::weak_ptr o = observer_->weak_from_this(); - if (!o._empty()) { + + //check for empty weak reference + //https://stackoverflow.com/questions/45507041/how-to-check-if-weak-ptr-is-empty-non-assigned + const ext::weak_ptr empty; + if (o.owner_before(empty) || empty.owner_before(o)) { const ext::shared_ptr obs(o.lock()); if (obs) obs->update(); From d910c039fdfd5a61d4578dbbaa170dcbf68cfbfa Mon Sep 17 00:00:00 2001 From: klausspanderen Date: Wed, 3 Oct 2018 12:24:54 +0200 Subject: [PATCH 2/3] move definitions to share_ptr.hpp --- ql/patterns/observable.hpp | 11 ----------- ql/shared_ptr.hpp | 2 ++ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/ql/patterns/observable.hpp b/ql/patterns/observable.hpp index d2870aa0014..e05f3e27261 100644 --- a/ql/patterns/observable.hpp +++ b/ql/patterns/observable.hpp @@ -267,17 +267,6 @@ namespace QuantLib { namespace QuantLib { - namespace ext { - - #if defined(QL_USE_STD_SHARED_PTR) - using std::enable_shared_from_this; - #else - using boost::enable_shared_from_this; - #endif - - } - - class Observable; class ObservableSettings; diff --git a/ql/shared_ptr.hpp b/ql/shared_ptr.hpp index 718ad333789..d2dd6ba2df0 100644 --- a/ql/shared_ptr.hpp +++ b/ql/shared_ptr.hpp @@ -43,12 +43,14 @@ namespace QuantLib { using std::make_shared; using std::static_pointer_cast; using std::dynamic_pointer_cast; + using std::enable_shared_from_this; #else using boost::shared_ptr; using boost::weak_ptr; using boost::make_shared; using boost::static_pointer_cast; using boost::dynamic_pointer_cast; + using boost::enable_shared_from_this; #endif } From 9dd4c1eb904db5d2787703ac33a2b81e0f78eb28 Mon Sep 17 00:00:00 2001 From: klausspanderen Date: Wed, 3 Oct 2018 12:42:47 +0200 Subject: [PATCH 3/3] move include as well --- ql/patterns/observable.hpp | 1 - ql/shared_ptr.hpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/patterns/observable.hpp b/ql/patterns/observable.hpp index e05f3e27261..6ee8e43c127 100644 --- a/ql/patterns/observable.hpp +++ b/ql/patterns/observable.hpp @@ -261,7 +261,6 @@ namespace QuantLib { #include #include #include -#include #include diff --git a/ql/shared_ptr.hpp b/ql/shared_ptr.hpp index d2dd6ba2df0..4cda6694f14 100644 --- a/ql/shared_ptr.hpp +++ b/ql/shared_ptr.hpp @@ -31,6 +31,7 @@ #else #include #include +#include #endif namespace QuantLib {