From d9307fa8b67189b9db0eee44cdf2bf5238afeb08 Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Wed, 10 Jun 2015 02:59:24 +0200 Subject: [PATCH] add make_weak_wrapped_callback --- fluent++/Callback.h | 27 +++++++++++++++++++++++++++ fluent++/WeakCallbackContainer.h | 10 +++++++++- test.cpp | 7 +++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/fluent++/Callback.h b/fluent++/Callback.h index 6af4ff5..7627498 100644 --- a/fluent++/Callback.h +++ b/fluent++/Callback.h @@ -51,6 +51,19 @@ namespace detail template using unwrap_callback = do_unwrap_callback<::fu::argument_type_of_t<_CTy>>; + template + struct WeakProxyFactory + { + static Callback CreateProxy(WeakCallback const& weak_callback) + { + return [=](Args&&... args) + { + if (auto const callback = weak_callback.lock()) + (*callback)(args...); + }; + } + }; + } // detail template @@ -70,4 +83,18 @@ inline shared_callback_of_t<_CTy> (std::forward>(callback)); } +template +inline auto make_weak_wrapped_callback(WeakCallback const& wrapped_callback) + -> Callback +{ + return detail::WeakProxyFactory::CreateProxy(wrapped_callback); +} + +template +inline auto make_weak_wrapped_callback(SharedCallback const& wrapped_callback) + -> Callback +{ + return make_weak_wrapped_callback(WeakCallback(wrapped_callback)); +} + #endif /// _CALLBACK_H_ diff --git a/fluent++/WeakCallbackContainer.h b/fluent++/WeakCallbackContainer.h index 8439697..287f76f 100644 --- a/fluent++/WeakCallbackContainer.h +++ b/fluent++/WeakCallbackContainer.h @@ -42,6 +42,7 @@ class WeakCallbackContainer struct ProxyFactory<_CTy, std::tuple> { // Creates a weak proxy callback which prevents invoking to an invalid context. + // Removes itself from the owner with the given handler. static callback_of_t<_CTy> CreateProxy(std::weak_ptr const& weak_owner, size_t const handle, weak_callback_of_t<_CTy> const& weak_callback) { @@ -82,7 +83,7 @@ public: } template - auto operator()(_CTy&& callback) + auto Wrap(_CTy&& callback) -> callback_of_t<_CTy> { // Create the shared callback @@ -98,6 +99,13 @@ public: return std::move(proxy); } + template + inline auto operator()(_CTy&& callback) + -> decltype(Wrap(std::declval<_CTy>())) + { + return Wrap(std::forward<_CTy>(callback)); + } + boost::optional GetLastCallbackHandle() const { if (handle == 0L) diff --git a/test.cpp b/test.cpp index a1ed309..0fb5dd8 100644 --- a/test.cpp +++ b/test.cpp @@ -92,5 +92,12 @@ int main(int argc, char** argv) // This will never be executed because the CallbackContainer was deallocated and its weak callback proxies are crash safe. weak_cb_test(); + SharedCallback<> weak_2 = make_shared_callback([] + { + + }); + + auto wrapped = make_weak_wrapped_callback(weak_2); + return 0; }