Introduce Q_STATIC_ASSERT

Example of message of failed assert (gcc 4.6, file tst_qglobal.cpp:300):
tst_qglobal.cpp:300:92: error: invalid application of ‘sizeof’
to incomplete type ‘QStaticAssertFailure<false>’

Change-Id: Ic1798094f718eaad388d754034115aafbbb6bd5e
Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
This commit is contained in:
Jędrzej Nowacki 2011-10-14 12:58:54 +02:00 committed by Qt by Nokia
parent 0b6d4a2d65
commit 663cd17718
2 changed files with 77 additions and 0 deletions

View File

@ -1785,6 +1785,15 @@ Q_CORE_EXPORT void qt_assert_x(const char *where, const char *what, const char *
# endif
#endif
// Intentionally undefined
template <bool Test> class QStaticAssertFailure;
template <> class QStaticAssertFailure<true> {};
#define Q_STATIC_ASSERT_PRIVATE_JOIN(A, B) Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B)
#define Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) A ## B
#define Q_STATIC_ASSERT(...) \
enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __LINE__) = sizeof(QStaticAssertFailure<bool(__VA_ARGS__)>)}
Q_CORE_EXPORT void qt_check_pointer(const char *, int);
Q_CORE_EXPORT void qBadAlloc();

View File

@ -52,6 +52,7 @@ private slots:
void qassert();
void qtry();
void checkptr();
void qstaticassert();
};
void tst_QGlobal::qIsNull()
@ -267,5 +268,72 @@ void tst_QGlobal::checkptr()
QCOMPARE(q_check_ptr(c), c);
}
// Check Q_STATIC_ASSERT, It should compile
// note that, we are not able to test Q_STATIC_ASSERT(false), to do it manually someone has
// to replace expressions (in the asserts) one by one to false, and check if it breaks build.
class MyTrue
{
public:
MyTrue()
{
Q_STATIC_ASSERT(true);
Q_STATIC_ASSERT(!false);
}
~MyTrue()
{
Q_STATIC_ASSERT(true);
Q_STATIC_ASSERT(!false);
}
Q_STATIC_ASSERT(true);
Q_STATIC_ASSERT(!false);
};
struct MyExpresion
{
void foo()
{
Q_STATIC_ASSERT(sizeof(MyTrue) > 0);
Q_STATIC_ASSERT(sizeof(MyTrue) > 0);
}
private:
Q_STATIC_ASSERT(sizeof(MyTrue) > 0);
Q_STATIC_ASSERT(sizeof(MyTrue) > 0);
};
struct TypeDef
{
typedef int T;
Q_STATIC_ASSERT(sizeof(T));
};
template<typename T1, typename T2>
struct Template
{
static const bool True = true;
typedef typename T1::T DependentType;
Q_STATIC_ASSERT(True);
Q_STATIC_ASSERT(!!True);
Q_STATIC_ASSERT(sizeof(DependentType));
Q_STATIC_ASSERT(!!sizeof(DependentType));
};
struct MyTemplate
{
Q_STATIC_ASSERT(Template<TypeDef, int>::True);
Q_STATIC_ASSERT(!!Template<TypeDef, int>::True);
};
void tst_QGlobal::qstaticassert()
{
// Force compilation of these classes
MyTrue tmp1;
MyExpresion tmp2;
MyTemplate tmp3;
Q_UNUSED(tmp1);
Q_UNUSED(tmp2);
Q_UNUSED(tmp3);
QVERIFY(true); // if the test compiles it has passed.
}
QTEST_MAIN(tst_QGlobal)
#include "tst_qglobal.moc"