Skip to content

Commit

Permalink
Use equality-comparable function object.
Browse files Browse the repository at this point in the history
Comparison between `boost::bind` objects doesn't work
in gcc when using C++20 mode.
  • Loading branch information
lballabio committed Apr 5, 2021
1 parent 81d0f5b commit 3807e31
Showing 1 changed file with 25 additions and 25 deletions.
50 changes: 25 additions & 25 deletions ql/patterns/observable.cpp
Expand Up @@ -87,21 +87,6 @@ namespace QuantLib {

#else

#include <ql/functional.hpp>

#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 <boost/bind/bind.hpp>

#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4))
#pragma GCC diagnostic pop
#endif
#endif

#include <boost/signals2/signal_type.hpp>

namespace QuantLib {
Expand Down Expand Up @@ -131,27 +116,44 @@ namespace QuantLib {
signal_type sig_;
};

template <class T>
class ProxyUpdater {
T* proxy_;
public:
explicit ProxyUpdater(const ext::shared_ptr<T>& observerProxy)
: proxy_(observerProxy.get()) {}

void operator()() const {
proxy_->update();
}

bool operator==(const ProxyUpdater<T>& other) const {
return proxy_ == other.proxy_;
}

bool operator!=(const ProxyUpdater<T>& other) const {
return proxy_ != other.proxy_;
}
};

}

void Observable::registerObserver(
const ext::shared_ptr<Observer::Proxy>& observerProxy) {
void Observable::registerObserver(const ext::shared_ptr<Observer::Proxy>& observerProxy) {
{
boost::lock_guard<boost::recursive_mutex> 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<Observer::Proxy>(observerProxy)};
#if defined(QL_USE_STD_SHARED_PTR)
sig_->connect(slot.track_foreign(observerProxy));
#else
sig_->connect(slot.track(observerProxy));
#endif
}

void Observable::unregisterObserver(
const ext::shared_ptr<Observer::Proxy>& observerProxy,
bool disconnect) {
void Observable::unregisterObserver(const ext::shared_ptr<Observer::Proxy>& observerProxy,
bool disconnect) {
{
boost::lock_guard<boost::recursive_mutex> lock(mutex_);
observers_.erase(observerProxy);
Expand All @@ -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<Observer::Proxy>(observerProxy));
}
}

Expand Down

0 comments on commit 3807e31

Please sign in to comment.