summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2014-10-01 10:56:14 +0200
committerMarc Mutz <marc.mutz@kdab.com>2015-02-17 15:05:07 +0000
commit40d6e8adf5e3cc45b3bd4a94ad3b57f9444e447f (patch)
treea61304672e4d2e1bdb58794f80a17b40faddf9d6
parent4c4940a744558fc8faa713439d7e27e26b52774d (diff)
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>
-rw-r--r--src/corelib/tools/qlist.h19
-rw-r--r--tests/auto/corelib/tools/qlist/tst_qlist.cpp32
2 files changed, 51 insertions, 0 deletions
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 023dafb223..255816d0ba 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -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();
diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp
index 95744051e4..1207986dde 100644
--- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp
+++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp
@@ -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
{