From 514d460e5746f3eac47c280e0a3ce792644888e3 Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Thu, 24 Mar 2016 22:17:39 +0000 Subject: [PATCH] refs #628 Refactor CWorker::invoke into a free function and expand its API. --- src/blackmisc/invoke.h | 56 ++++++++++++++++++++++++++++++++++++++++++ src/blackmisc/worker.h | 19 +++----------- 2 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 src/blackmisc/invoke.h diff --git a/src/blackmisc/invoke.h b/src/blackmisc/invoke.h new file mode 100644 index 000000000..ed6137c4c --- /dev/null +++ b/src/blackmisc/invoke.h @@ -0,0 +1,56 @@ +/* Copyright (C) 2015 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_INVOKE_H +#define BLACKMISC_INVOKE_H + +#include + +namespace BlackMisc +{ + //! \cond PRIVATE + namespace Private + { + + // Our own version of C++17 std::invoke(). + template ::value>> + decltype(auto) invoke(F ptr, T &&object) + { + return std::forward(object).*ptr; + } + template ::value>> + decltype(auto) invoke(F ptr, T &&object, Ts &&... args) + { + return (std::forward(object).*ptr)(std::forward(args)...); + } + template >::value>> + decltype(auto) invoke(F &&func, Ts &&... args) + { + return std::forward(func)(std::forward(args)...); + } + + // Like invoke() but ignores the first argument if callable is not a member function. For uniform calling of callables with slot semantics. + template ::value>> + decltype(auto) invokeSlot(F ptr, T *object, Ts &&... args) + { + return (object->*ptr)(std::forward(args)...); + } + template >::value>> + decltype(auto) invokeSlot(F &&func, T *, Ts &&... args) + { + return std::forward(func)(std::forward(args)...); + } + + } + //! \endcond +} + +#endif \ No newline at end of file diff --git a/src/blackmisc/worker.h b/src/blackmisc/worker.h index e8735cf3f..6e52c5b07 100644 --- a/src/blackmisc/worker.h +++ b/src/blackmisc/worker.h @@ -15,6 +15,7 @@ #include "blackmiscexport.h" #include "variant.h" #include "stacktrace.h" +#include "invoke.h" #include #include #include @@ -109,7 +110,7 @@ namespace BlackMisc Q_ASSERT(context->thread() == QThread::currentThread()); QMutexLocker lock(&m_finishedMutex); connect(this, &CWorkerBase::finished, context, functor); - if (m_finished) { invoke(context, functor); } + if (m_finished) { Private::invokeSlot(functor, context); } } //! Connects to a functor which will be called when the task is finished. @@ -185,20 +186,6 @@ namespace BlackMisc emit finished(); } - //! Uniform way to invoke either a functor or a method. - template - static auto invoke(T *object, F func, Ts &&... args) -> std::enable_if_t::value> - { - return (object->*func)(std::forward(args)...); - } - - //! Uniform way to invoke either a functor or a method. - template - static auto invoke(T *, F func, Ts &&... args) -> std::enable_if_t::value> - { - return func(std::forward(args)...); - } - private: virtual void quit() noexcept {} virtual void quitAndWait() noexcept { waitForFinished(); } @@ -250,7 +237,7 @@ namespace BlackMisc void thenWithResult(T *context, F functor) { Q_ASSERT_X(m_result.canConvert(), Q_FUNC_INFO, "Type in thenWithResult must match return type of task"); - then(context, [this, context, functor]() { invoke(context, functor, this->result()); }); + then(context, [this, context, functor]() { Private::invokeSlot(functor, context, this->result()); }); } //! Returns the result of the task, waiting for it to finish if necessary.