Expose QMetaTypeInterface::alignof in QMetaType

We already have the information in the QMetaTypeInterface, and provide
functions to access sizeof. Adding alignof support seems natural, and
should make it easier to handle over-aligned types.
This should also be helpful in QVariant.

Change-Id: I166be76f4b7d2d2e524a3a1e513bd2f361e887c1
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Fabian Kosmale 2020-07-29 16:34:44 +02:00
parent 61ccfefb25
commit cb80720287
3 changed files with 62 additions and 2 deletions

View File

@ -500,7 +500,7 @@ int QMetaType::id() const
This function is typically used together with construct()
to perform low-level management of the memory used by a type.
\sa QMetaType::construct(), QMetaType::sizeOf()
\sa QMetaType::construct(), QMetaType::sizeOf(), QMetaType::alignOf()
*/
int QMetaType::sizeOf() const
{
@ -509,6 +509,27 @@ int QMetaType::sizeOf() const
return 0;
}
/*!
\fn int QMetaType::alignOf() const
\since 6.0
Returns the alignment of the type in bytes (i.e. alignof(T),
where T is the actual type for which this QMetaType instance
was constructed for).
This function is typically used together with construct()
to perform low-level management of the memory used by a type.
\sa QMetaType::construct(), QMetaType::sizeOf()
*/
int QMetaType::alignOf() const
{
if (d_ptr)
return d_ptr->alignment;
return 0;
}
/*!
\fn TypeFlags QMetaType::flags() const
\since 5.0
@ -1585,7 +1606,7 @@ void QMetaType::destruct(int type, void *where)
This function is typically used together with construct()
to perform low-level management of the memory used by a type.
\sa construct()
\sa construct(), QMetaType::alignOf()
*/
int QMetaType::sizeOf(int type)
{

View File

@ -505,6 +505,7 @@ public:
bool isRegistered() const;
int id() const;
int sizeOf() const;
int alignOf() const;
TypeFlags flags() const;
const QMetaObject *metaObject() const;
QT_PREPEND_NAMESPACE(QByteArray) name() const;

View File

@ -197,6 +197,8 @@ private slots:
void sizeOf();
void sizeOfStaticLess_data();
void sizeOfStaticLess();
void alignOf_data();
void alignOf();
void flags_data();
void flags();
void flagsStaticLess_data();
@ -951,6 +953,42 @@ void tst_QMetaType::sizeOfStaticLess()
QCOMPARE(size_t(QMetaType(type).sizeOf()), size);
}
template <typename T>
auto getAlignOf()
{
if constexpr (std::is_same_v<T, void>)
return 0;
else
return alignof(T);
}
void tst_QMetaType::alignOf_data()
{
QTest::addColumn<int>("type");
QTest::addColumn<size_t>("size");
QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << size_t(0);
#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
QTest::newRow(#RealType) << int(QMetaType::MetaTypeName) << size_t(getAlignOf<RealType>());
FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW)
#undef ADD_METATYPE_TEST_ROW
QTest::newRow("Whity<double>") << ::qMetaTypeId<Whity<double> >() << alignof(Whity<double>);
QTest::newRow("Whity<int>") << ::qMetaTypeId<Whity<int> >() << alignof(Whity<int>);
QTest::newRow("Testspace::Foo") << ::qMetaTypeId<TestSpace::Foo>() << alignof(TestSpace::Foo);
QTest::newRow("-1") << -1 << size_t(0);
QTest::newRow("-124125534") << -124125534 << size_t(0);
QTest::newRow("124125534") << 124125534 << size_t(0);
}
void tst_QMetaType::alignOf()
{
QFETCH(int, type);
QFETCH(size_t, size);
QCOMPARE(size_t(QMetaType(type).alignOf()), size);
}
struct CustomMovable { CustomMovable() {} };
#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501
QT_BEGIN_NAMESPACE