QVariant: fix HasIsNullMethod for final classes
authorMarc Mutz <marc.mutz@kdab.com>
Fri, 2 Mar 2012 10:51:52 +0000 (11:51 +0100)
committerQt by Nokia <qt-info@nokia.com>
Thu, 8 Mar 2012 22:58:08 +0000 (23:58 +0100)
commit73a5ce5195bc27acf02d787787a69ec493c037c2
tree23319a94f7a34f0440decd5e68cfdc7219d1d06b
parentdbab994b2cdc5469cf53e3f6c5d09bc2d7b39ce9
QVariant: fix HasIsNullMethod for final classes

HasIsNullMethod uses the accepted C++98 idiom to
check for members that might be inherited from
baseclasses.

The technique, however, requires inheriting from
the type-under-test, which fails for C++11 final
classes.

Fortunately, under C++11 we have much better
support for static type introspection: sfinae
for expressions. We use this here (see decltype()
use in qvariant_p.h) to write a C++11 version of
HasIsNullMethod that works with final classes, too.

However, since this technique required decltype()
support in the compiler, Q_DECL_FINAL can no longer
be used for both method and class markup. So we
declare a new Q_DECL_FINAL_CLASS which is only
set iff the compiler supports decltype(), too.

MSVC 2005 and 2008 support a non-standard, but
sufficiently compatible, version of override/final,
but no decltype(). A later patch will use MSVC
'override/'sealed' to implement Q_DECL_{OVERRIDE,FINAL}
for these compilers, but I currently don't see a
version of HasIsNullMethod that could support these
two, so the split off of Q_DECL_FINAL_CLASS is in
anticipation of that commit. If someone _does_ find
an implementation of HasIsNullMethod that works on
MSVC2005 and 2008 sealed classes, then it's a simple
matter of s/Q_DECL_FINAL_CLASS/Q_DECL_FINAL/g.

This code has been tested on GCC 4.7 (prerelease)
and GCC 4.8 (prerelease).

Change-Id: I8700c8307d79a74d45fef0aec1c6027b4a922a43
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
src/corelib/global/qglobal.h
src/corelib/kernel/qvariant_p.h