QVariant: make the HasIsNullMethod check work across all compilers (maybe)

Currently, we have a C++11 version that requires Q_COMPILER_DECLTYPE
support, and can deal with final classes, and a C++98 version that
doesn't require any C++11 features, but fails on final classes.

What we're missing is a version that works for MSVC v8 and v9
(2005 and 2008), which sport the 'sealed' non-standard keywords
but lack decltype support. So far, we tried to solve the problem
by making class-level final special (Q_DECL_FINAL_CLASS), not
defining that macro for these two compilers, even though we did
define Q_DECL_FINAL, the method-level keyword.

This new formulation, taken from
  http://stackoverflow.com/a/9655327/134841
supposedly supports all compilers with a minor #ifdef for
MSVC which doesn't like applying sizeof() the way we do.

However, testing has shown this to blow up on OSX.

So we use the less intrusive approach: add this variant as
a third version, only used by VC 2005 and 2008.

Change-Id: If1945f8a6e9ed36cb68212fa781d5e29eb2a082d
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
bb10
Marc Mutz 2012-07-10 15:27:48 +02:00 committed by Qt by Nokia
parent 9090e0d9c6
commit 7e0fa2fc75
1 changed files with 12 additions and 0 deletions

View File

@ -224,6 +224,18 @@ class QVariantIsNull
public:
static const bool Value = (sizeof(test<T>(0)) == sizeof(Yes));
};
#elif defined(Q_CC_MSVC) && _MSC_VER >= 1400 // MSVC 2005, 2008 version: no decltype, but 'sealed' classes (>=2010 has decltype)
template<typename T>
class HasIsNullMethod {
struct Yes { char unused[1]; };
struct No { char unused[2]; };
Q_STATIC_ASSERT(sizeof(Yes) != sizeof(No));
template<class C> static Yes test(char (*)[(&C::isNull == 0) + 1]);
template<class C> static No test(...);
public:
static const bool Value = (sizeof(test<T>(0)) == sizeof(Yes));
};
#else // C++98 version (doesn't work for final classes)
template<typename T, bool IsClass = QTypeInfo<T>::isComplex>
class HasIsNullMethod