summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobjectdefs_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qobjectdefs_impl.h')
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h94
1 files changed, 93 insertions, 1 deletions
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index c91259d559..da356095af 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -51,7 +51,7 @@
#endif
QT_BEGIN_NAMESPACE
-
+class QObject;
namespace QtPrivate {
template <typename T> struct RemoveRef { typedef T Type; };
@@ -352,6 +352,98 @@ namespace QtPrivate {
template <typename D> static D dummy();
typedef decltype(dummy<Functor>().operator()((dummy<ArgList>())...)) Value;
};
+
+ // internal base class (interface) containing functions required to call a slot managed by a pointer to function.
+ class QSlotObjectBase {
+ QAtomicInt m_ref;
+ // don't use virtual functions here; we don't want the
+ // compiler to create tons of per-polymorphic-class stuff that
+ // we'll never need. We just use one function pointer.
+ typedef void (*ImplFn)(int which, QSlotObjectBase* this_, QObject *receiver, void **args, bool *ret);
+ const ImplFn m_impl;
+ protected:
+ enum Operation {
+ Destroy,
+ Call,
+ Compare,
+
+ NumOperations
+ };
+ public:
+ explicit QSlotObjectBase(ImplFn fn) : m_ref(1), m_impl(fn) {}
+
+ inline int ref() Q_DECL_NOTHROW { return m_ref.ref(); }
+ inline void destroyIfLastRef() Q_DECL_NOTHROW
+ { if (!m_ref.deref()) m_impl(Destroy, this, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR); }
+
+ inline bool compare(void **a) { bool ret = false; m_impl(Compare, this, Q_NULLPTR, a, &ret); return ret; }
+ inline void call(QObject *r, void **a) { m_impl(Call, this, r, a, Q_NULLPTR); }
+ protected:
+ ~QSlotObjectBase() {}
+ private:
+ Q_DISABLE_COPY(QSlotObjectBase)
+ };
+
+ // implementation of QSlotObjectBase for which the slot is a pointer to member function of a QObject
+ // Args and R are the List of arguments and the returntype of the signal to which the slot is connected.
+ template<typename Func, typename Args, typename R> class QSlotObject : public QSlotObjectBase
+ {
+ typedef QtPrivate::FunctionPointer<Func> FuncType;
+ Func function;
+ static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret)
+ {
+ switch (which) {
+ case Destroy:
+ delete static_cast<QSlotObject*>(this_);
+ break;
+ case Call:
+ FuncType::template call<Args, R>(static_cast<QSlotObject*>(this_)->function, static_cast<typename FuncType::Object *>(r), a);
+ break;
+ case Compare:
+ *ret = *reinterpret_cast<Func *>(a) == static_cast<QSlotObject*>(this_)->function;
+ break;
+ case NumOperations: ;
+ }
+ }
+ public:
+ explicit QSlotObject(Func f) : QSlotObjectBase(&impl), function(f) {}
+ };
+ // implementation of QSlotObjectBase for which the slot is a functor (or lambda)
+ // N is the number of arguments
+ // Args and R are the List of arguments and the returntype of the signal to which the slot is connected.
+ template<typename Func, int N, typename Args, typename R> class QFunctorSlotObject : public QSlotObjectBase
+ {
+ typedef QtPrivate::Functor<Func, N> FuncType;
+ Func function;
+ static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret)
+ {
+ switch (which) {
+ case Destroy:
+ delete static_cast<QFunctorSlotObject*>(this_);
+ break;
+ case Call:
+ FuncType::template call<Args, R>(static_cast<QFunctorSlotObject*>(this_)->function, r, a);
+ break;
+ case Compare: // not implemented
+ case NumOperations:
+ Q_UNUSED(ret);
+ }
+ }
+ public:
+ explicit QFunctorSlotObject(Func f) : QSlotObjectBase(&impl), function(std::move(f)) {}
+ };
+
+ // typedefs for readability for when there are no parameters
+ template <typename Func>
+ using QSlotObjectWithNoArgs = QSlotObject<Func,
+ QtPrivate::List<>,
+ typename QtPrivate::FunctionPointer<Func>::ReturnType>;
+
+ template <typename Func, typename R>
+ using QFunctorSlotObjectWithNoArgs = QFunctorSlotObject<Func, 0, QtPrivate::List<>, R>;
+
+ template <typename Func>
+ using QFunctorSlotObjectWithNoArgsImplicitReturn = QFunctorSlotObjectWithNoArgs<Func, typename QtPrivate::FunctionPointer<Func>::ReturnType>;
}
QT_END_NAMESPACE