Cleanup v_construct and friends

Streamline code using if constexpr and remove some unused code paths.

Change-Id: I602acffab4b3e53fab9e2433856f6b7e8210cc60
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Lars Knoll 2020-07-10 14:36:58 +02:00
parent fb0968049f
commit 68c4449d2f

View File

@ -63,34 +63,19 @@ QT_BEGIN_NAMESPACE
template<typename T>
struct QVariantIntegrator
{
static const bool CanUseInternalSpace = sizeof(T) <= sizeof(QVariant::Private::Data);
static constexpr bool CanUseInternalSpace = sizeof(T) <= sizeof(QVariant::Private::Data);
typedef std::integral_constant<bool, CanUseInternalSpace> CanUseInternalSpace_t;
};
static_assert(QVariantIntegrator<double>::CanUseInternalSpace);
static_assert(QVariantIntegrator<long int>::CanUseInternalSpace);
static_assert(QVariantIntegrator<qulonglong>::CanUseInternalSpace);
#ifdef Q_CC_SUN // Sun CC picks the wrong overload, so introduce awful hack
// takes a type, returns the internal void* pointer cast
// to a pointer of the input type
template <typename T>
inline T *v_cast(const QVariant::Private *nd, T * = 0)
{
QVariant::Private *d = const_cast<QVariant::Private *>(nd);
return !QVariantIntegrator<T>::CanUseInternalSpace
? static_cast<T *>(d->data.shared->ptr)
: static_cast<T *>(static_cast<void *>(&d->data.c));
}
#else // every other compiler in this world
template <typename T>
inline const T *v_cast(const QVariant::Private *d, T * = nullptr)
{
return !QVariantIntegrator<T>::CanUseInternalSpace
? static_cast<const T *>(d->data.shared->data())
: static_cast<const T *>(static_cast<const void *>(&d->data.c));
: static_cast<const T *>(static_cast<const void *>(&d->data));
}
template <typename T>
@ -98,69 +83,20 @@ inline T *v_cast(QVariant::Private *d, T * = nullptr)
{
return !QVariantIntegrator<T>::CanUseInternalSpace
? static_cast<T *>(d->data.shared->data())
: static_cast<T *>(static_cast<void *>(&d->data.c));
}
#endif
template <class T>
inline void v_construct_helper(QVariant::Private *x, const T &t, std::true_type)
{
new (&x->data) T(t);
x->is_shared = false;
}
template <class T>
inline void v_construct_helper(QVariant::Private *x, const T &t, std::false_type)
{
x->data.shared = QVariant::PrivateShared::create(QMetaType::fromType<T>());
new (x->data.shared->data()) T(t);
x->is_shared = true;
}
template <class T>
inline void v_construct_helper(QVariant::Private *x, std::true_type)
{
new (&x->data) T();
x->is_shared = false;
}
template <class T>
inline void v_construct_helper(QVariant::Private *x, std::false_type)
{
x->data.shared = QVariant::PrivateShared::create(QMetaType::fromType<T>());
new (x->data.shared->data()) T();
x->is_shared = true;
: static_cast<T *>(static_cast<void *>(&d->data));
}
template <class T>
inline void v_construct(QVariant::Private *x, const T &t)
{
// dispatch
v_construct_helper(x, t, typename QVariantIntegrator<T>::CanUseInternalSpace_t());
}
// constructs a new variant if copy is 0, otherwise copy-constructs
template <class T>
inline void v_construct(QVariant::Private *x, const void *copy, T * = nullptr)
{
if (copy)
v_construct<T>(x, *static_cast<const T *>(copy));
else
v_construct_helper<T>(x, typename QVariantIntegrator<T>::CanUseInternalSpace_t());
}
// deletes the internal structures
template <class T>
inline void v_clear(QVariant::Private *d, T* = nullptr)
{
if (!QVariantIntegrator<T>::CanUseInternalSpace) {
delete static_cast<T *>(d->data.shared->data());
if constexpr (QVariantIntegrator<T>::CanUseInternalSpace) {
new (&x->data) T(t);
x->is_shared = false;
} else {
v_cast<T>(d)->~T();
x->data.shared = QVariant::PrivateShared::create(QMetaType::fromType<T>());
new (x->data.shared->data()) T(t);
x->is_shared = true;
}
}
Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler();