diff options
Diffstat (limited to 'src/corelib/kernel/qobjectdefs_impl.h')
-rw-r--r-- | src/corelib/kernel/qobjectdefs_impl.h | 94 |
1 files changed, 93 insertions, 1 deletions
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index 29ab77b269..b9f2e47e32 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; }; @@ -350,6 +350,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 |