QList: prepare for tag dispatching based on memory layout
Add one tag class for each of QList's three different memory layouts to QListData, and inherit QList<T>::MemoryLayout from exactly one of them. To simplify overloading, added tag classes that express the negation of the two extreme poles of memory layout (C-compatible and heap), too. The "missing" one could be added when needed, too. Change-Id: I45ea603731499fd3fdfb37d60a0a98fb22ac15ec Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
4c4940a744
commit
40d6e8adf5
@ -66,6 +66,14 @@ template <typename T> struct QListSpecialMethods { };
|
||||
template <> struct QListSpecialMethods<QByteArray>;
|
||||
|
||||
struct Q_CORE_EXPORT QListData {
|
||||
// tags for tag-dispatching of QList implementations,
|
||||
// based on QList's three different memory layouts:
|
||||
struct NotArrayCompatibleLayout {};
|
||||
struct NotIndirectLayout {};
|
||||
struct ArrayCompatibleLayout : NotIndirectLayout {}; // data laid out like a C array
|
||||
struct InlineWithPaddingLayout : NotArrayCompatibleLayout, NotIndirectLayout {}; // data laid out like a C array with padding
|
||||
struct IndirectLayout : NotArrayCompatibleLayout {}; // data allocated on the heap
|
||||
|
||||
struct Data {
|
||||
QtPrivate::RefCount ref;
|
||||
int alloc, begin, end;
|
||||
@ -99,6 +107,17 @@ struct Q_CORE_EXPORT QListData {
|
||||
template <typename T>
|
||||
class QList : public QListSpecialMethods<T>
|
||||
{
|
||||
public:
|
||||
struct MemoryLayout
|
||||
: QtPrivate::if_<
|
||||
QTypeInfo<T>::isStatic || QTypeInfo<T>::isLarge,
|
||||
QListData::IndirectLayout,
|
||||
typename QtPrivate::if_<
|
||||
sizeof(T) == sizeof(void*),
|
||||
QListData::ArrayCompatibleLayout,
|
||||
QListData::InlineWithPaddingLayout
|
||||
>::type>::type {};
|
||||
private:
|
||||
struct Node { void *v;
|
||||
#if defined(Q_CC_BOR)
|
||||
Q_INLINE_TEMPLATE T &t();
|
||||
|
@ -35,6 +35,17 @@
|
||||
#include <QtTest/QtTest>
|
||||
#include <QList>
|
||||
|
||||
template <typename T, class MemoryLayout>
|
||||
class is_qlist_array_memory_layout {
|
||||
struct No { char c; };
|
||||
struct Yes { No n[2]; };
|
||||
Q_STATIC_ASSERT(sizeof(No) != sizeof(Yes));
|
||||
static No check(...);
|
||||
static Yes check(MemoryLayout);
|
||||
public:
|
||||
enum { value = sizeof(check(typename QList<T>::MemoryLayout())) == sizeof(Yes) };
|
||||
};
|
||||
|
||||
struct Movable {
|
||||
Movable(char input = 'j')
|
||||
: i(input)
|
||||
@ -235,6 +246,27 @@ Q_STATIC_ASSERT(!QTypeInfo<Optimal>::isStatic);
|
||||
Q_STATIC_ASSERT(QTypeInfo<Optimal>::isComplex);
|
||||
Q_STATIC_ASSERT(QTypeInfo<Complex>::isStatic);
|
||||
Q_STATIC_ASSERT(QTypeInfo<Complex>::isComplex);
|
||||
// iow:
|
||||
Q_STATIC_ASSERT(( is_qlist_array_memory_layout<int, QListData::NotIndirectLayout> ::value));
|
||||
Q_STATIC_ASSERT((!is_qlist_array_memory_layout<int, QListData::IndirectLayout> ::value));
|
||||
|
||||
Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Optimal, QListData::InlineWithPaddingLayout> ::value));
|
||||
Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Optimal, QListData::NotArrayCompatibleLayout>::value));
|
||||
Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Optimal, QListData::NotIndirectLayout> ::value));
|
||||
Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Optimal, QListData::ArrayCompatibleLayout> ::value));
|
||||
Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Optimal, QListData::IndirectLayout> ::value));
|
||||
|
||||
Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Movable, QListData::InlineWithPaddingLayout> ::value));
|
||||
Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Movable, QListData::NotArrayCompatibleLayout>::value));
|
||||
Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Movable, QListData::NotIndirectLayout> ::value));
|
||||
Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Movable, QListData::ArrayCompatibleLayout> ::value));
|
||||
Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Movable, QListData::IndirectLayout> ::value));
|
||||
|
||||
Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Complex, QListData::InlineWithPaddingLayout> ::value));
|
||||
Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Complex, QListData::NotArrayCompatibleLayout>::value));
|
||||
Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Complex, QListData::NotIndirectLayout> ::value));
|
||||
Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Complex, QListData::ArrayCompatibleLayout> ::value));
|
||||
Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Complex, QListData::IndirectLayout> ::value));
|
||||
|
||||
class tst_QList : public QObject
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user