Use Q_STATIC_ASSERT to report error about missing Q_OBJECT
Q_STATIC_ASSERT gives better error with C++11 enabled. Aslo the qt_check_for_QOBJECT_macro had warning on some compiler since it used null reference Change-Id: Ic6115da800064b00c50a5762f0b79f5f656bf750 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
6b9d125621
commit
7d7e8ae3fa
@ -148,8 +148,8 @@ public:
|
||||
static inline QMetaMethod fromSignal(Func signal)
|
||||
{
|
||||
typedef QtPrivate::FunctionPointer<Func> SignalType;
|
||||
reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(
|
||||
*reinterpret_cast<typename SignalType::Object *>(0));
|
||||
Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
|
||||
"No Q_OBJECT in the class with the signal");
|
||||
return fromSignalImpl(&SignalType::Object::staticMetaObject,
|
||||
reinterpret_cast<void **>(&signal));
|
||||
}
|
||||
|
@ -217,7 +217,9 @@ public:
|
||||
{
|
||||
typedef QtPrivate::FunctionPointer<Func1> SignalType;
|
||||
typedef QtPrivate::FunctionPointer<Func2> SlotType;
|
||||
reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0));
|
||||
|
||||
Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
|
||||
"No Q_OBJECT in the class with the signal");
|
||||
|
||||
//compilation error if the arguments does not match.
|
||||
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
|
||||
@ -246,6 +248,9 @@ public:
|
||||
typedef QtPrivate::FunctionPointer<Func1> SignalType;
|
||||
typedef QtPrivate::FunctionPointer<Func2> SlotType;
|
||||
|
||||
Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
|
||||
"No Q_OBJECT in the class with the signal");
|
||||
|
||||
//compilation error if the arguments does not match.
|
||||
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
|
||||
"The slot requires more arguments than the signal provides.");
|
||||
@ -307,6 +312,9 @@ public:
|
||||
Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<SlotReturnType, typename SignalType::ReturnType>::value),
|
||||
"Return type of the slot is not compatible with the return type of the signal.");
|
||||
|
||||
Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
|
||||
"No Q_OBJECT in the class with the signal");
|
||||
|
||||
return connectImpl(sender, reinterpret_cast<void **>(&signal), sender, 0,
|
||||
new QtPrivate::QFunctorSlotObject<Func2, SlotArgumentCount,
|
||||
typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value,
|
||||
@ -335,7 +343,9 @@ public:
|
||||
{
|
||||
typedef QtPrivate::FunctionPointer<Func1> SignalType;
|
||||
typedef QtPrivate::FunctionPointer<Func2> SlotType;
|
||||
reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0));
|
||||
|
||||
Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
|
||||
"No Q_OBJECT in the class with the signal");
|
||||
|
||||
//compilation error if the arguments does not match.
|
||||
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
|
||||
@ -477,18 +487,18 @@ inline QT_DEPRECATED QList<T> qFindChildren(const QObject *o, const QRegExp &re)
|
||||
template <class T>
|
||||
inline T qobject_cast(QObject *object)
|
||||
{
|
||||
#if !defined(QT_NO_QOBJECT_CHECK)
|
||||
reinterpret_cast<T>(object)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(object));
|
||||
#endif
|
||||
typedef typename QtPrivate::remove_cv<typename QtPrivate::remove_pointer<T>::type>::type ObjType;
|
||||
Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
|
||||
"qobject_cast require the type to have a Q_OBJECT macro");
|
||||
return static_cast<T>(reinterpret_cast<T>(object)->staticMetaObject.cast(object));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T qobject_cast(const QObject *object)
|
||||
{
|
||||
#if !defined(QT_NO_QOBJECT_CHECK)
|
||||
reinterpret_cast<T>(object)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(const_cast<QObject *>(object)));
|
||||
#endif
|
||||
typedef typename QtPrivate::remove_cv<typename QtPrivate::remove_pointer<T>::type>::type ObjType;
|
||||
Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
|
||||
"qobject_cast require the type to have a Q_OBJECT macro");
|
||||
return static_cast<T>(reinterpret_cast<T>(object)->staticMetaObject.cast(object));
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,6 @@ namespace QtPrivate {
|
||||
public:
|
||||
explicit QFunctorSlotObject(const Func &f) : QSlotObjectBase(&impl), function(f) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -316,7 +316,8 @@ inline QMetaObject::Connection QObjectPrivate::connect(const typename QtPrivate:
|
||||
{
|
||||
typedef QtPrivate::FunctionPointer<Func1> SignalType;
|
||||
typedef QtPrivate::FunctionPointer<Func2> SlotType;
|
||||
reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0));
|
||||
Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
|
||||
"No Q_OBJECT in the class with the signal");
|
||||
|
||||
//compilation error if the arguments does not match.
|
||||
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
|
||||
@ -343,7 +344,8 @@ bool QObjectPrivate::disconnect(const typename QtPrivate::FunctionPointer< Func1
|
||||
{
|
||||
typedef QtPrivate::FunctionPointer<Func1> SignalType;
|
||||
typedef QtPrivate::FunctionPointer<Func2> SlotType;
|
||||
reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0));
|
||||
Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
|
||||
"No Q_OBJECT in the class with the signal");
|
||||
//compilation error if the arguments does not match.
|
||||
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
|
||||
"Signal and slot arguments are not compatible.");
|
||||
|
@ -480,6 +480,16 @@ public:
|
||||
inline const QMetaObject *QMetaObject::superClass() const
|
||||
{ return d.superdata; }
|
||||
|
||||
namespace QtPrivate {
|
||||
/* Trait that tells is a the Object has a Q_OBJECT macro */
|
||||
template <typename Object> struct HasQ_OBJECT_Macro {
|
||||
template <typename T>
|
||||
static char test(int (T::*)(QMetaObject::Call, int, void **));
|
||||
static int test(int (Object::*)(QMetaObject::Call, int, void **));
|
||||
enum { Value = sizeof(test(&Object::qt_metacall)) == sizeof(int) };
|
||||
};
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QOBJECTDEFS_H
|
||||
|
@ -5931,5 +5931,9 @@ void tst_QObject::qmlConnect()
|
||||
#endif
|
||||
}
|
||||
|
||||
// Test for QtPrivate::HasQ_OBJECT_Macro
|
||||
Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value);
|
||||
Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value);
|
||||
|
||||
QTEST_MAIN(tst_QObject)
|
||||
#include "tst_qobject.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user