From 3807e31cc5c0de2c1bb752afd3f45ca724518df1 Mon Sep 17 00:00:00 2001 From: Luigi Ballabio Date: Mon, 5 Apr 2021 16:16:10 +0200 Subject: [PATCH] Use equality-comparable function object. Comparison between `boost::bind` objects doesn't work in gcc when using C++20 mode. --- ql/patterns/observable.cpp | 50 +++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/ql/patterns/observable.cpp b/ql/patterns/observable.cpp index 87da71d0b8d..078a66eee28 100644 --- a/ql/patterns/observable.cpp +++ b/ql/patterns/observable.cpp @@ -87,21 +87,6 @@ namespace QuantLib { #else -#include - -#if defined(QL_USE_STD_FUNCTION) -#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-local-typedefs" -#endif - -#include - -#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)) -#pragma GCC diagnostic pop -#endif -#endif - #include namespace QuantLib { @@ -131,17 +116,35 @@ namespace QuantLib { signal_type sig_; }; + template + class ProxyUpdater { + T* proxy_; + public: + explicit ProxyUpdater(const ext::shared_ptr& observerProxy) + : proxy_(observerProxy.get()) {} + + void operator()() const { + proxy_->update(); + } + + bool operator==(const ProxyUpdater& other) const { + return proxy_ == other.proxy_; + } + + bool operator!=(const ProxyUpdater& other) const { + return proxy_ != other.proxy_; + } + }; + } - void Observable::registerObserver( - const ext::shared_ptr& observerProxy) { + void Observable::registerObserver(const ext::shared_ptr& observerProxy) { { boost::lock_guard lock(mutex_); observers_.insert(observerProxy); } - detail::Signal::signal_type::slot_type slot(&Observer::Proxy::update, - observerProxy.get()); + detail::Signal::signal_type::slot_type slot {detail::ProxyUpdater(observerProxy)}; #if defined(QL_USE_STD_SHARED_PTR) sig_->connect(slot.track_foreign(observerProxy)); #else @@ -149,9 +152,8 @@ namespace QuantLib { #endif } - void Observable::unregisterObserver( - const ext::shared_ptr& observerProxy, - bool disconnect) { + void Observable::unregisterObserver(const ext::shared_ptr& observerProxy, + bool disconnect) { { boost::lock_guard lock(mutex_); observers_.erase(observerProxy); @@ -165,9 +167,7 @@ namespace QuantLib { } if (disconnect) { - // signals2 needs boost::bind, std::bind does not work - sig_->disconnect(boost::bind(&Observer::Proxy::update, - observerProxy.get())); + sig_->disconnect(detail::ProxyUpdater(observerProxy)); } }