funchelpers: Support traits for non-member functions
authorManuel Nickschas <sputnick@quassel-irc.org>
Mon, 15 Oct 2018 20:18:24 +0000 (22:18 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sun, 18 Nov 2018 10:06:43 +0000 (11:06 +0100)
Add a FuncHelper overload for non-member (free) functions. Rename
MemberFunction to FunctionTraits to reflect that enhancement.

src/common/funchelpers.h
src/uisupport/widgethelpers.h

index 01ee822..c56cdb9 100644 (file)
@@ -32,21 +32,27 @@ template<typename Func>
 struct FuncHelper : public FuncHelper<decltype(&Func::operator())>
 {};
 
-// Overload for member function with const call operator
-template<typename C, typename R, typename... Args>
-struct FuncHelper<R (C::*)(Args...) const> : public FuncHelper<R (C::*)(Args...)>
-{};
+// Overload for free function
+template<typename R, typename... Args>
+struct FuncHelper<R(*)(Args...)>
+{
+    using FunctionType = std::function<R(Args...)>;
+    using ReturnType = R;
+    using ArgsTuple = std::tuple<Args...>;
+};
 
 // Overload for member function with non-const call operator
 template<typename C, typename R, typename... Args>
-struct FuncHelper<R (C::*)(Args...)>
+struct FuncHelper<R(C::*)(Args...)> : public FuncHelper<R(*)(Args...)>
 {
     using ClassType = C;
-    using FunctionType = std::function<R(Args...)>;
-    using ReturnType = R;
-    using ArgsTuple = std::tuple<Args...>;
 };
 
+// Overload for member function with const call operator
+template<typename C, typename R, typename... Args>
+struct FuncHelper<R(C::*)(Args...) const> : public FuncHelper<R(C::*)(Args...)>
+{};
+
 /// @endcond
 
 }  // namespace detail
@@ -55,4 +61,4 @@ struct FuncHelper<R (C::*)(Args...)>
  * Provides traits for the given callable.
  */
 template<typename Callable>
-using MemberFunction = detail::FuncHelper<Callable>;
+using FunctionTraits = detail::FuncHelper<Callable>;
index 9ca6189..4efe75e 100644 (file)
@@ -66,7 +66,7 @@ bool tryConnectChangedSignal(const QObject* widget, const Receiver* receiver, Sl
     // If *alreadyConnected is true, just returns false to prevent multiple connections.
     static const auto tryConnect = [](const QObject* object, auto sig, auto receiver, auto slot, bool* alreadyConnected) {
         if (!*alreadyConnected) {
-            auto widget = qobject_cast<const typename MemberFunction<decltype(sig)>::ClassType*>(object);
+            auto widget = qobject_cast<const typename FunctionTraits<decltype(sig)>::ClassType*>(object);
             if (widget) {
                 *alreadyConnected = QObject::connect(widget, sig, receiver, slot);
                 return *alreadyConnected;