summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/arch/qatomic_symbian.h12
-rw-r--r--src/corelib/global/qglobal.cpp87
-rw-r--r--src/corelib/global/qglobal.h33
-rw-r--r--src/corelib/global/qlibraryinfo.cpp3
-rw-r--r--src/corelib/global/qmalloc.cpp58
-rw-r--r--src/corelib/global/qnamespace.h16
-rw-r--r--src/corelib/global/qnamespace.qdoc51
-rw-r--r--src/corelib/io/qprocess_unix.cpp18
-rw-r--r--src/corelib/kernel/qmetaobject.cpp9
-rw-r--r--src/corelib/kernel/qobject.cpp146
-rw-r--r--src/corelib/plugin/qlibrary.cpp3
-rw-r--r--src/corelib/statemachine/qstate.cpp31
-rw-r--r--src/corelib/statemachine/qstate.h4
-rw-r--r--src/corelib/statemachine/qstate_p.h2
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp30
-rw-r--r--src/corelib/statemachine/qstatemachine.h8
-rw-r--r--src/corelib/statemachine/qstatemachine_p.h2
-rw-r--r--src/corelib/tools/qcontiguouscache.cpp10
-rw-r--r--src/corelib/tools/qcontiguouscache.h147
-rw-r--r--src/corelib/tools/qhash.cpp28
-rw-r--r--src/corelib/tools/qhash.h37
-rw-r--r--src/corelib/tools/qmap.cpp32
-rw-r--r--src/corelib/tools/qmap.h21
-rw-r--r--src/corelib/tools/qvector.cpp29
-rw-r--r--src/corelib/tools/qvector.h22
25 files changed, 488 insertions, 351 deletions
diff --git a/src/corelib/arch/qatomic_symbian.h b/src/corelib/arch/qatomic_symbian.h
index 5880120..3721aca 100644
--- a/src/corelib/arch/qatomic_symbian.h
+++ b/src/corelib/arch/qatomic_symbian.h
@@ -42,8 +42,6 @@
#ifndef QATOMIC_SYMBIAN_H
#define QATOMIC_SYMBIAN_H
-QT_BEGIN_HEADER
-
#if defined(Q_CC_RVCT)
# define QT_NO_ARM_EABI
# include <QtCore/qatomic_arm.h>
@@ -51,6 +49,16 @@ QT_BEGIN_HEADER
# include <QtCore/qatomic_generic.h>
#endif
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+// Empty, but needed to avoid warnings
+
+QT_END_NAMESPACE
+
QT_END_HEADER
#endif // QATOMIC_SYMBIAN_H
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 7d47944..5578091 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -960,7 +960,7 @@ QT_BEGIN_NAMESPACE
\relates <QtGlobal>
Turns the major, minor and patch numbers of a version into an
- integer, 0xMMNNPP (MM = major, NN = minor, PP = patch). This can
+ integer, 0xMMNNPP (MM = major, NN = minor, PP = patch). This can
be compared with another similarly processed version id.
\sa QT_VERSION
@@ -1795,7 +1795,7 @@ QSysInfo::S60Version QSysInfo::s60Version()
TInt err = fileFinder.FindWildByDir(qt_S60Filter, qt_S60SystemInstallDir, contents);
if (err == KErrNone) {
err = contents->Sort(EDescending|ESortByName);
- if (err == KErrNone) {
+ if (err == KErrNone && contents->Count() > 0 && (*contents)[0].iName.Length() >= 12) {
TInt major = (*contents)[0].iName[9] - '0';
TInt minor = (*contents)[0].iName[11] - '0';
if (major == 3) {
@@ -1808,6 +1808,12 @@ QSysInfo::S60Version QSysInfo::s60Version()
if (minor == 0) {
return cachedS60Version = SV_S60_5_0;
}
+ else if (minor == 1) {
+ return cachedS60Version = SV_S60_5_1;
+ }
+ else if (minor == 2) {
+ return cachedS60Version = SV_S60_5_2;
+ }
}
}
delete contents;
@@ -1822,12 +1828,10 @@ QSysInfo::S60Version QSysInfo::s60Version()
return cachedS60Version = SV_S60_3_2;
# elif defined(__S60_50__)
return cachedS60Version = SV_S60_5_0;
-# else
- return cachedS60Version = SV_S60_Unknown;
# endif
-# else
- return cachedS60Version = SV_S60_Unknown;
# endif
+ //If reaching here, it was not possible to determine the version
+ return cachedS60Version = SV_S60_Unknown;
}
QSysInfo::SymbianVersion QSysInfo::symbianVersion()
{
@@ -1838,6 +1842,10 @@ QSysInfo::SymbianVersion QSysInfo::symbianVersion()
return SV_9_3;
case SV_S60_5_0:
return SV_9_4;
+ case SV_S60_5_1:
+ return SV_9_4;
+ case SV_S60_5_2:
+ return SV_9_4;
default:
return SV_Unknown;
}
@@ -2513,10 +2521,19 @@ Q_GLOBAL_STATIC(SeedStorage, randTLS) // Thread Local Storage for seed value
void qsrand(uint seed)
{
#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
- SeedStorageType *pseed = randTLS()->localData();
- if (!pseed)
- randTLS()->setLocalData(pseed = new SeedStorageType);
- *pseed = seed;
+ SeedStorage *seedStorage = randTLS();
+ if (seedStorage) {
+ SeedStorageType *pseed = seedStorage->localData();
+ if (!pseed)
+ seedStorage->setLocalData(pseed = new SeedStorageType);
+ *pseed = seed;
+ } else {
+ //golbal static seed storage should always exist,
+ //except after being deleted by QGlobalStaticDeleter.
+ //But since it still can be called from destructor of another
+ //global static object, fallback to sqrand(seed)
+ srand(seed);
+ }
#else
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
@@ -2536,21 +2553,24 @@ void qsrand(uint seed)
void qsrand()
{
#if (defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
- SeedStorageType *pseed = randTLS()->localData();
- if (pseed) {
- // already seeded
- return;
- }
- randTLS()->setLocalData(pseed = new SeedStorageType);
- // start beyond 1 to avoid the sequence reset
- static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2);
- *pseed = QDateTime::currentDateTime().toTime_t()
- + quintptr(&pseed)
- + serial.fetchAndAddRelaxed(1);
+ SeedStorage *seedStorage = randTLS();
+ if (seedStorage) {
+ SeedStorageType *pseed = seedStorage->localData();
+ if (pseed) {
+ // already seeded
+ return;
+ }
+ seedStorage->setLocalData(pseed = new SeedStorageType);
+ // start beyond 1 to avoid the sequence reset
+ static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2);
+ *pseed = QDateTime::currentDateTime().toTime_t()
+ + quintptr(&pseed)
+ + serial.fetchAndAddRelaxed(1);
#if defined(Q_OS_WIN)
- // for Windows the srand function must still be called.
- srand(*pseed);
+ // for Windows the srand function must still be called.
+ srand(*pseed);
#endif
+ }
#elif defined(Q_OS_WIN)
static unsigned int seed = 0;
@@ -2560,7 +2580,7 @@ void qsrand()
seed = GetTickCount();
srand(seed);
-#else
+#else
// Symbian?
#endif // defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
@@ -2584,12 +2604,21 @@ void qsrand()
int qrand()
{
#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
- SeedStorageType *pseed = randTLS()->localData();
- if (!pseed) {
- randTLS()->setLocalData(pseed = new SeedStorageType);
- *pseed = 1;
+ SeedStorage *seedStorage = randTLS();
+ if (seedStorage) {
+ SeedStorageType *pseed = seedStorage->localData();
+ if (!pseed) {
+ seedStorage->setLocalData(pseed = new SeedStorageType);
+ *pseed = 1;
+ }
+ return rand_r(pseed);
+ } else {
+ //golbal static seed storage should always exist,
+ //except after being deleted by QGlobalStaticDeleter.
+ //But since it still can be called from destructor of another
+ //global static object, fallback to qrand()
+ return rand();
}
- return rand_r(pseed);
#else
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 5ee1815..d113e02 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1207,6 +1207,11 @@ class QDataStream;
# else
# define Q_SVG_EXPORT Q_DECL_IMPORT
# endif
+# if defined(QT_BUILD_DECLARATIVE_LIB)
+# define Q_DECLARATIVE_EXPORT Q_DECL_EXPORT
+# else
+# define Q_DECLARATIVE_EXPORT Q_DECL_IMPORT
+# endif
# if defined(QT_BUILD_OPENGL_LIB)
# define Q_OPENGL_EXPORT Q_DECL_EXPORT
# else
@@ -1259,6 +1264,7 @@ class QDataStream;
# define Q_SQL_EXPORT Q_DECL_IMPORT
# define Q_NETWORK_EXPORT Q_DECL_IMPORT
# define Q_SVG_EXPORT Q_DECL_IMPORT
+# define Q_DECLARATIVE_EXPORT Q_DECL_IMPORT
# define Q_CANVAS_EXPORT Q_DECL_IMPORT
# define Q_OPENGL_EXPORT Q_DECL_IMPORT
# define Q_MULTIMEDIA_EXPORT Q_DECL_IMPORT
@@ -1287,6 +1293,7 @@ class QDataStream;
# define Q_SQL_EXPORT Q_DECL_EXPORT
# define Q_NETWORK_EXPORT Q_DECL_EXPORT
# define Q_SVG_EXPORT Q_DECL_EXPORT
+# define Q_DECLARATIVE_EXPORT Q_DECL_EXPORT
# define Q_OPENGL_EXPORT Q_DECL_EXPORT
# define Q_MULTIMEDIA_EXPORT Q_DECL_EXPORT
# define Q_OPENVG_EXPORT Q_DECL_EXPORT
@@ -1301,6 +1308,7 @@ class QDataStream;
# define Q_SQL_EXPORT
# define Q_NETWORK_EXPORT
# define Q_SVG_EXPORT
+# define Q_DECLARATIVE_EXPORT
# define Q_OPENGL_EXPORT
# define Q_MULTIMEDIA_EXPORT
# define Q_XML_EXPORT
@@ -1478,17 +1486,26 @@ public:
#ifdef Q_OS_SYMBIAN
enum SymbianVersion {
SV_Unknown = 0x0000,
+ //These are the Symbian Ltd versions 9.2-9.4
SV_9_2 = 10,
SV_9_3 = 20,
- SV_9_4 = 30
+ SV_9_4 = 30,
+ //Following values are the symbian foundation versions, i.e. Symbian^1 == SV_SF_1
+ SV_SF_1 = SV_9_4,
+ SV_SF_2 = 40,
+ SV_SF_3 = 50,
+ SV_SF_4 = 60
};
static SymbianVersion symbianVersion();
enum S60Version {
SV_S60_None = 0,
SV_S60_Unknown = 1,
- SV_S60_3_1 = 10,
- SV_S60_3_2 = 20,
- SV_S60_5_0 = 30
+ SV_S60_3_1 = SV_9_2,
+ SV_S60_3_2 = SV_9_3,
+ SV_S60_5_0 = SV_9_4,
+ //versions beyond 5.0 are to be confirmed - it is better to use symbian version
+ SV_S60_5_1 = SV_SF_2,
+ SV_S60_5_2 = SV_SF_3
};
static S60Version s60Version();
#endif
@@ -2065,6 +2082,9 @@ Q_DECLARE_TYPEINFO(long double, Q_PRIMITIVE_TYPE);
Q_CORE_EXPORT void *qMalloc(size_t size);
Q_CORE_EXPORT void qFree(void *ptr);
Q_CORE_EXPORT void *qRealloc(void *ptr, size_t size);
+Q_CORE_EXPORT void *qMallocAligned(size_t size, size_t alignment);
+Q_CORE_EXPORT void *qReallocAligned(void *ptr, size_t size, size_t oldsize, size_t alignment);
+Q_CORE_EXPORT void qFreeAligned(void *ptr);
Q_CORE_EXPORT void *qMemCopy(void *dest, const void *src, size_t n);
Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n);
@@ -2459,6 +2479,7 @@ Q_CORE_EXPORT int qt_symbian_exception2Error(const std::exception& ex);
#define QT_MODULE_SCRIPTTOOLS 0x10000
#define QT_MODULE_OPENVG 0x20000
#define QT_MODULE_MULTIMEDIA 0x40000
+#define QT_MODULE_DECLARATIVE 0x80000
/* Qt editions */
#define QT_EDITION_CONSOLE (QT_MODULE_CORE \
@@ -2489,6 +2510,7 @@ Q_CORE_EXPORT int qt_symbian_exception2Error(const std::exception& ex);
| QT_MODULE_QT3SUPPORTLIGHT \
| QT_MODULE_QT3SUPPORT \
| QT_MODULE_SVG \
+ | QT_MODULE_DECLARATIVE \
| QT_MODULE_GRAPHICSVIEW \
| QT_MODULE_HELP \
| QT_MODULE_TEST \
@@ -2560,6 +2582,9 @@ QT_LICENSED_MODULE(Qt3Support)
#if (QT_EDITION & QT_MODULE_SVG)
QT_LICENSED_MODULE(Svg)
#endif
+#if (QT_EDITION & QT_MODULE_DECLARATIVE)
+QT_LICENSED_MODULE(Declarative)
+#endif
#if (QT_EDITION & QT_MODULE_ACTIVEQT)
QT_LICENSED_MODULE(ActiveQt)
#endif
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 32693e0..15a06d7 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -215,8 +215,7 @@ QLibraryInfo::buildKey()
QDate
QLibraryInfo::buildDate()
{
- return QDate();
- //return QDate::fromString(QString::fromLatin1(qt_configure_installation + 12), Qt::ISODate);
+ return QDate::fromString(QString::fromLatin1(qt_configure_installation + 12), Qt::ISODate);
}
/*!
diff --git a/src/corelib/global/qmalloc.cpp b/src/corelib/global/qmalloc.cpp
index a9f103c..4aab1bd 100644
--- a/src/corelib/global/qmalloc.cpp
+++ b/src/corelib/global/qmalloc.cpp
@@ -65,4 +65,62 @@ void *qRealloc(void *ptr, size_t size)
return ::realloc(ptr, size);
}
+void *qMallocAligned(size_t size, size_t alignment)
+{
+ return qReallocAligned(0, size, 0, alignment);
+}
+
+void *qReallocAligned(void *oldptr, size_t newsize, size_t oldsize, size_t alignment)
+{
+ // fake an aligned allocation
+ Q_UNUSED(oldsize);
+
+ void *actualptr = oldptr ? static_cast<void **>(oldptr)[-1] : 0;
+ if (alignment <= sizeof(void*)) {
+ // special, fast case
+ void **newptr = static_cast<void **>(qRealloc(actualptr, newsize + sizeof(void*)));
+ if (!newptr)
+ return 0;
+ if (newptr == actualptr) {
+ // realloc succeeded without reallocating
+ return oldptr;
+ }
+
+ *newptr = newptr;
+ return newptr + 1;
+ }
+
+ union { void *ptr; void **pptr; quintptr n; } real, faked;
+
+ // qMalloc returns pointers aligned at least at sizeof(size_t) boundaries
+ // but usually more (8- or 16-byte boundaries).
+ // So we overallocate by alignment-sizeof(size_t) bytes, so we're guaranteed to find a
+ // somewhere within the first alignment-sizeof(size_t) that is properly aligned.
+
+ // However, we need to store the actual pointer, so we need to allocate actually size +
+ // alignment anyway.
+
+ real.ptr = qRealloc(actualptr, newsize + alignment);
+ if (!real.ptr)
+ return 0;
+
+ faked.n = real.n + alignment;
+ faked.n &= ~(alignment - 1);
+
+ // now save the value of the real pointer at faked-sizeof(void*)
+ // by construction, alignment > sizeof(void*) and is a power of 2, so
+ // faked-sizeof(void*) is properly aligned for a pointer
+ faked.pptr[-1] = real.ptr;
+
+ return faked.ptr;
+}
+
+void qFreeAligned(void *ptr)
+{
+ if (!ptr)
+ return;
+ void **ptr2 = static_cast<void **>(ptr);
+ free(ptr2[-1]);
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index aeaca54..0ee9cd2 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -1715,14 +1715,12 @@ public:
LastGestureType = ~0u
};
- enum GestureContext
+ enum GestureFlag
{
- WidgetGesture = 0,
- WidgetWithChildrenGesture = 3,
-
- ItemGesture = WidgetGesture,
- ItemWithChildrenGesture = WidgetWithChildrenGesture
+ DontStartGestureOnChildren = 0x01,
+ ReceivePartialGestures = 0x02
};
+ Q_DECLARE_FLAGS(GestureFlags, GestureFlag)
enum NavigationMode
{
@@ -1732,11 +1730,6 @@ public:
NavigationModeCursorAuto,
NavigationModeCursorForceVisible
};
-
- enum RenderHint {
- QualityHint,
- PerformanceHint
- };
}
#ifdef Q_MOC_RUN
;
@@ -1757,6 +1750,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MatchFlags)
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TextInteractionFlags)
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodHints)
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TouchPointStates)
+Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::GestureFlags)
typedef bool (*qInternalCallback)(void **);
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 4e369c9..5ac3675 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -2910,34 +2910,36 @@
\value PanGesture A Pan gesture.
\value PinchGesture A Pinch gesture.
\value SwipeGesture A Swipe gesture.
- \value CustomGesture User-defined gesture ID.
- \value LastGestureType Last user gesture ID.
+ \value CustomGesture A flag that can be used to test if the gesture is a
+ user-defined gesture ID.
+ \omitvalue LastGestureType
User-defined gestures are registered with the
- QApplication::registerGestureRecognizer() function which generates a custom gesture ID
- in the range of values from CustomGesture to LastGestureType.
+ QGestureRecognizer::registerRecognizer() function which generates a custom
+ gesture ID with the Qt::CustomGesture flag set.
- \sa QGesture, QWidget::grabGesture()
+ \sa QGesture, QWidget::grabGesture(), QGraphicsObject::grabGesture()
*/
/*!
- \enum Qt::GestureContext
+ \enum Qt::GestureFlag
\since 4.6
- This enum type describes the context of a gesture.
+ This enum type describes additional flags that can be used when subscribing
+ to a gesture.
- For a QGesture to trigger, the gesture recognizer should filter events for
- a widget tree. This enum describes for which widget the gesture recognizer
- should filter events:
+ \value DontStartGestureOnChildren By default gestures can start on the
+ widget or over any of its children. Use this flag to disable this and allow
+ a gesture to start on the widget only.
- \value WidgetGesture Gestures can only start over the widget itself.
- \value WidgetWithChildrenGesture Gestures can start on the widget or over
- any of its children.
- \value ItemGesture Gestures can only start over the item itself.
- \value ItemWithChildrenGesture Gestures can start on the item or over
- any of its children.
+ \value ReceivePartialGestures Allows any ignored gesture events to be
+ propagated to parent widgets which have specified this hint. By default
+ only gestures that are in the Qt::GestureStarted state are propagated and
+ the widget always gets the full gesture sequence starting with a gesture in
+ the Qt::GestureStarted state and ending with a gesture in the
+ Qt::GestureFinished or Qt::GestureCanceled states.
- \sa QWidget::grabGesture()
+ \sa QWidget::grabGesture(), QGraphicsObject::grabGesture()
*/
/*!
@@ -2965,18 +2967,3 @@
\sa QApplication::setNavigationMode()
\sa QApplication::navigationMode()
*/
-
-/*!
- \enum Qt::RenderHint
- \since 4.6
-
- This enum describes the possible hints that can be used to control various
- rendering operations.
-
- \value QualityHint Indicates that rendering quality is the most important factor,
- at the potential cost of lower performance.
-
- \value PerformanceHint Indicates that rendering performance is the most important factor,
- at the potential cost of lower quality.
-*/
-
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 99296c7..f040d16 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -108,6 +108,10 @@ QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
+// POSIX requires PIPE_BUF to be 512 or larger
+// so we will use 512
+static const int errorBufferMax = 512;
+
#ifdef Q_OS_INTEGRITY
static inline char *strdup(const char *data)
{
@@ -752,18 +756,19 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv
}
// notify failure
+ QString error = qt_error_string(errno);
#if defined (QPROCESS_DEBUG)
- fprintf(stderr, "QProcessPrivate::execChild() failed, notifying parent process\n");
+ fprintf(stderr, "QProcessPrivate::execChild() failed (%s), notifying parent process\n", qPrintable(error));
#endif
- qt_safe_write(childStartedPipe[1], "", 1);
+ qt_safe_write(childStartedPipe[1], error.data(), error.length() * sizeof(QChar));
qt_safe_close(childStartedPipe[1]);
childStartedPipe[1] = -1;
}
bool QProcessPrivate::processStarted()
{
- char c;
- int i = qt_safe_read(childStartedPipe[0], &c, 1);
+ ushort buf[errorBufferMax];
+ int i = qt_safe_read(childStartedPipe[0], &buf, sizeof buf);
if (startupSocketNotifier) {
startupSocketNotifier->setEnabled(false);
startupSocketNotifier->deleteLater();
@@ -775,6 +780,11 @@ bool QProcessPrivate::processStarted()
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::processStarted() == %s", i <= 0 ? "true" : "false");
#endif
+
+ // did we read an error message?
+ if (i > 0)
+ q_func()->setErrorString(QString::fromUtf16(buf, i / sizeof(QChar)));
+
return i <= 0;
}
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index f98c449..6e6da19 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -574,8 +574,8 @@ int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject, co
if (i >= 0 && m && m->d.superdata) {
int conflict = m->d.superdata->indexOfMethod(signal);
if (conflict >= 0)
- qWarning("QMetaObject::indexOfSignal:%s: Conflict with %s::%s",
- m->d.stringdata, m->d.superdata->d.stringdata, signal);
+ qWarning("QMetaObject::indexOfSignal: signal %s from %s redefined in %s",
+ signal, m->d.superdata->d.stringdata, m->d.stringdata);
}
#endif
return i;
@@ -2237,7 +2237,10 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
// -1 (unchanged): normal qt_metacall, result stored in argv[0]
// changed: result stored directly in value, return the value of status
int status = -1;
- void *argv[] = { 0, &v, &status };
+ // the flags variable is used by the declarative module to implement
+ // interception of property writes.
+ int flags = 0;
+ void *argv[] = { 0, &v, &status, &flags };
if (t == QVariant::LastType)
argv[0] = &v;
else
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 5303975..1260d47 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -582,7 +582,7 @@ int QMetaCallEvent::placeMetaCall(QObject *object)
QObjects organize themselves in object trees. When you create a
QObject with another object as parent, the object will
automatically add itself to the parent's children() list. The
- parent takes ownership of the object i.e. it will automatically
+ parent takes ownership of the object; i.e., it will automatically
delete its children in its destructor. You can look for an object
by name and optionally type using findChild() or findChildren().
@@ -646,7 +646,7 @@ int QMetaCallEvent::placeMetaCall(QObject *object)
to be stored in one of the container classes. You must store
pointers.
- \section2 Auto-Connection
+ \section1 Auto-Connection
Qt's meta-object system provides a mechanism to automatically connect
signals and slots between QObject subclasses and their children. As long
@@ -660,7 +660,7 @@ int QMetaCallEvent::placeMetaCall(QObject *object)
given in the \l{Using a Designer UI File in Your Application} section of
the \QD manual.
- \section2 Dynamic Properties
+ \section1 Dynamic Properties
From Qt 4.2, dynamic properties can be added to and removed from QObject
instances at run-time. Dynamic properties do not need to be declared at
@@ -673,6 +673,15 @@ int QMetaCallEvent::placeMetaCall(QObject *object)
and both standard Qt widgets and user-created forms can be given dynamic
properties.
+ \section1 Internationalization (i18n)
+
+ All QObject subclasses support Qt's translation features, making it possible
+ to translate an application's user interface into different languages.
+
+ To make user-visible text translatable, it must be wrapped in calls to
+ the tr() function. This is explained in detail in the
+ \l{Writing Source Code for Translation} document.
+
\sa QMetaObject, QPointer, QObjectCleanupHandler, Q_DISABLE_COPY()
{Object Trees and Object Ownership}
*/
@@ -2150,65 +2159,10 @@ void QObject::deleteLater()
otherwise returns \a sourceText itself if no appropriate translated string
is available.
- See the sections below on Disambiguation and Handling Plurals for more
- information about the optional \a disambiguation and \a n parameters.
-
- QObject and its subclasses obtain translated strings from any translator
- objects that have been installed on the application object; see the
- QTranslator documentation for details about this mechanism.
-
- A translatable string is referenced by its translation context;
- this is the name of the QObject subclass whose tr() function is invoked,
- as in the following example:
-
+ Example:
\snippet mainwindows/sdi/mainwindow.cpp implicit tr context
\dots
- Here, the context is \c MainWindow because it is the \c MainWindow::tr()
- function that is invoked. Translation contexts can be given explicitly
- by fully qualifying the call to tr(); for example:
-
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp explicit tr context
-
- This call obtains the translated text for "Page up" from the \c QScrollBar
- context.
-
- \section1 Defining Translation Contexts
-
- The translation context for QObject and each QObject subclass is the
- class name itself. Developers subclassing QObject must use the
- Q_OBJECT macro in their class definition to override the translation
- context. This macro sets the context to the name of the subclass.
-
- If Q_OBJECT is not used in a class definition, the context will be
- inherited from the base class. For example, since all QObject-based
- classes in Qt provide a context, a new QWidget subclass defined without
- a Q_OBJECT macro will use the "QWidget" context if its tr() function
- is invoked.
-
- \section1 Translator Comments
-
- Developers can include information about each translatable string to
- help translators with the translation process. These are extracted
- when \l lupdate is used to process the source files. The recommended
- way to add comments is to annotate the tr() calls in your code with
- comments of the form:
-
- \tt{//: ...}
-
- or
-
- \tt{\begincomment: ... \endcomment}
-
- Examples:
-
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 40
-
- In these examples, the comments will be associated with the strings
- passed to tr() in the context of each call.
-
- \section1 Disambiguation
-
If the same \a sourceText is used in different roles within the
same context, an additional identifying string may be passed in
\a disambiguation (0 by default). In Qt 4.4 and earlier, this was
@@ -2217,76 +2171,12 @@ void QObject::deleteLater()
Example:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 17
+ \dots
- \section1 Meta Data
-
- Additional data can be attached to each translatable message.
- The syntax:
-
- \tt{//= <id>}
-
- can be used to give the message a unique identifier to support tools
- which need it.
- The syntax:
-
- \tt{//~ <field name> <field contents>}
-
- can be used to attach meta data to the message. The field name should consist
- of a domain prefix (possibly the conventional file extension of the file format
- the field is inspired by), a hyphen and the actual field name in
- underscore-delimited notation. For storage in TS files, the field name together
- with the prefix "extra-" will form an XML element name. The field contents will
- be XML-escaped, but otherwise appear verbatim as the element's contents.
- Any number of unique fields can be added to each message.
-
- Example:
-
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp meta data
-
- Meta data appearing right in front of a magic TRANSLATOR comment applies to the
- whole TS file.
-
- \section1 Character Encodings
-
- You can set the encoding for \a sourceText by calling QTextCodec::setCodecForTr().
- By default \a sourceText is assumed to be in Latin-1 encoding.
-
- \section1 Handling Plurals
-
- If \a n >= 0, all occurrences of \c %n in the resulting string
- are replaced with a decimal representation of \a n. In addition,
- depending on \a n's value, the translation text may vary.
-
- Example:
-
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 18
-
- The table below shows what string is returned depending on the
- active translation:
-
- \table
- \header \o \o{3,1} Active Translation
- \header \o \a n \o No Translation \o French \o English
- \row \o 0 \o "0 message(s) saved" \o "0 message sauvegard\unicode{0xE9}" \o "0 message\bold{s} saved"
- \row \o 1 \o "1 message(s) saved" \o "1 message sauvegard\unicode{0xE9}" \o "1 message saved"
- \row \o 2 \o "2 message(s) saved" \o "2 message\bold{s} sauvegard\unicode{0xE9}\bold{s}" \o "2 message\bold{s} saved"
- \row \o 37 \o "37 message(s) saved" \o "37 message\bold{s} sauvegard\unicode{0xE9}\bold{s}" \o "37 message\bold{s} saved"
- \endtable
-
- This idiom is more flexible than the traditional approach; e.g.,
-
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 19
-
- because it also works with target languages that have several
- plural forms (e.g., Irish has a special "dual" form that should
- be used when \c n is 2), and it handles the \e n == 0 case
- correctly for languages such as French that require the singular.
- See the \l{Qt Linguist Manual} for details.
-
- Instead of \c %n, you can use \c %Ln to produce a localized
- representation of \a n. The conversion uses the default locale,
- set using QLocale::setDefault(). (If no default locale was
- specified, the "C" locale is used.)
+ See \l{Writing Source Code for Translation} for a detailed description of
+ Qt's translation mechanisms in general, and the
+ \l{Writing Source Code for Translation#Disambiguation}{Disambiguation}
+ section for information on disambiguation.
\warning This method is reentrant only if all translators are
installed \e before calling this method. Installing or removing
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 2b463a1..6496876 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -659,7 +659,10 @@ bool QLibraryPrivate::isPlugin(QSettings *settings)
#endif
if (!pHnd) {
#ifdef Q_OS_WIN
+ //avoid 'Bad Image' message box
+ UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
hTempModule = ::LoadLibraryEx((wchar_t*)QDir::toNativeSeparators(fileName).utf16(), 0, DONT_RESOLVE_DLL_REFERENCES);
+ SetErrorMode(oldmode);
#else
# if defined(Q_OS_SYMBIAN)
//Guard against accidentally trying to load non-plugin libraries by making sure the stub exists
diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp
index 5dc310b..cf718a5 100644
--- a/src/corelib/statemachine/qstate.cpp
+++ b/src/corelib/statemachine/qstate.cpp
@@ -140,10 +140,10 @@ void QStatePrivate::emitFinished()
emit q->finished();
}
-void QStatePrivate::emitPolished()
+void QStatePrivate::emitPropertiesAssigned()
{
Q_Q(QState);
- emit q->polished();
+ emit q->propertiesAssigned();
}
/*!
@@ -229,7 +229,7 @@ QList<QAbstractTransition*> QStatePrivate::transitions() const
Instructs this state to set the property with the given \a name of the given
\a object to the given \a value when the state is entered.
- \sa polished()
+ \sa propertiesAssigned()
*/
void QState::assignProperty(QObject *object, const char *name,
const QVariant &value)
@@ -287,15 +287,14 @@ void QState::setErrorState(QAbstractState *state)
/*!
Adds the given \a transition. The transition has this state as the source.
- This state takes ownership of the transition. If the transition is successfully
- added, the function will return the \a transition pointer. Otherwise it will return null.
+ This state takes ownership of the transition.
*/
-QAbstractTransition *QState::addTransition(QAbstractTransition *transition)
+void QState::addTransition(QAbstractTransition *transition)
{
Q_D(QState);
if (!transition) {
qWarning("QState::addTransition: cannot add null transition");
- return 0;
+ return ;
}
transition->setParent(this);
@@ -304,18 +303,17 @@ QAbstractTransition *QState::addTransition(QAbstractTransition *transition)
QAbstractState *t = targets.at(i).data();
if (!t) {
qWarning("QState::addTransition: cannot add transition to null state");
- return 0;
+ return ;
}
if ((QAbstractStatePrivate::get(t)->machine() != d->machine())
&& QAbstractStatePrivate::get(t)->machine() && d->machine()) {
qWarning("QState::addTransition: cannot add transition "
"to a state in a different state machine");
- return 0;
+ return ;
}
}
if (machine() != 0 && machine()->configuration().contains(this))
QStateMachinePrivate::get(machine())->registerTransitions(this);
- return transition;
}
/*!
@@ -380,7 +378,8 @@ QAbstractTransition *QState::addTransition(QAbstractState *target)
return 0;
}
UnconditionalTransition *trans = new UnconditionalTransition(target);
- return addTransition(trans);
+ addTransition(trans);
+ return trans;
}
/*!
@@ -493,9 +492,15 @@ bool QState::event(QEvent *e)
*/
/*!
- \fn QState::polished()
+ \fn QState::propertiesAssigned()
+
+ This signal is emitted when all properties have been assigned their final value. If the state
+ assigns a value to one or more properties for which an animation exists (either set on the
+ transition or as a default animation on the state machine), then the signal will not be emitted
+ until all such animations have finished playing.
- This signal is emitted when all properties have been assigned their final value.
+ If there are no relevant animations, or no property assignments defined for the state, then
+ the signal will be emitted immediately before the state is entered.
\sa QState::assignProperty(), QAbstractTransition::addAnimation()
*/
diff --git a/src/corelib/statemachine/qstate.h b/src/corelib/statemachine/qstate.h
index 7a47447..423f940 100644
--- a/src/corelib/statemachine/qstate.h
+++ b/src/corelib/statemachine/qstate.h
@@ -76,7 +76,7 @@ public:
QAbstractState *errorState() const;
void setErrorState(QAbstractState *state);
- QAbstractTransition *addTransition(QAbstractTransition *transition);
+ void addTransition(QAbstractTransition *transition);
QSignalTransition *addTransition(QObject *sender, const char *signal, QAbstractState *target);
QAbstractTransition *addTransition(QAbstractState *target);
void removeTransition(QAbstractTransition *transition);
@@ -94,7 +94,7 @@ public:
Q_SIGNALS:
void finished();
- void polished();
+ void propertiesAssigned();
protected:
void onEntry(QEvent *event);
diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h
index 34c8838..7fe6279 100644
--- a/src/corelib/statemachine/qstate_p.h
+++ b/src/corelib/statemachine/qstate_p.h
@@ -94,7 +94,7 @@ public:
QList<QAbstractTransition*> transitions() const;
void emitFinished();
- void emitPolished();
+ void emitPropertiesAssigned();
QAbstractState *errorState;
QAbstractState *initialState;
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index ea5587e..cf951c9 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -159,12 +159,12 @@ QT_BEGIN_NAMESPACE
\brief the restore policy for states of this state machine.
The default value of this property is
- QStateMachine::DoNotRestoreProperties.
+ QStateMachine::DontRestoreProperties.
*/
#ifndef QT_NO_ANIMATION
/*!
- \property QStateMachine::animationsEnabled
+ \property QStateMachine::animated
\brief whether animations are enabled
@@ -187,10 +187,10 @@ QStateMachinePrivate::QStateMachinePrivate()
stop = false;
stopProcessingReason = EventQueueEmpty;
error = QStateMachine::NoError;
- globalRestorePolicy = QStateMachine::DoNotRestoreProperties;
+ globalRestorePolicy = QStateMachine::DontRestoreProperties;
signalEventGenerator = 0;
#ifndef QT_NO_ANIMATION
- animationsEnabled = true;
+ animated = true;
#endif
}
@@ -744,7 +744,7 @@ void QStateMachinePrivate::applyProperties(const QList<QAbstractTransition*> &tr
// Find the animations to use for the state change.
QList<QAbstractAnimation*> selectedAnimations;
- if (animationsEnabled) {
+ if (animated) {
for (int i = 0; i < transitionList.size(); ++i) {
QAbstractTransition *transition = transitionList.at(i);
@@ -809,7 +809,7 @@ void QStateMachinePrivate::applyProperties(const QList<QAbstractTransition*> &tr
if (anim->state() == QAbstractAnimation::Running) {
// The animation is still running. This can happen if the
// animation is a group, and one of its children just finished,
- // and that caused a state to emit its polished() signal, and
+ // and that caused a state to emit its propertiesAssigned() signal, and
// that triggered a transition in the machine.
// Just stop the animation so it is correctly restarted again.
anim->stop();
@@ -831,7 +831,7 @@ void QStateMachinePrivate::applyProperties(const QList<QAbstractTransition*> &tr
}
}
- // Emit polished signal for entered states that have no animated properties.
+ // Emit propertiesAssigned signal for entered states that have no animated properties.
for (int i = 0; i < enteredStates.size(); ++i) {
QState *s = toStandardState(enteredStates.at(i));
if (s
@@ -839,7 +839,7 @@ void QStateMachinePrivate::applyProperties(const QList<QAbstractTransition*> &tr
&& !animationsForState.contains(s)
#endif
)
- QStatePrivate::get(s)->emitPolished();
+ QStatePrivate::get(s)->emitPropertiesAssigned();
}
}
@@ -1130,7 +1130,7 @@ void QStateMachinePrivate::_q_animationFinished()
animations.removeOne(anim);
if (animations.isEmpty()) {
animationsForState.erase(it);
- QStatePrivate::get(toStandardState(state))->emitPolished();
+ QStatePrivate::get(toStandardState(state))->emitPropertiesAssigned();
}
}
@@ -1726,7 +1726,7 @@ QStateMachine::~QStateMachine()
already been saved by the state machine, it will not be overwritten until the property has been
successfully restored.
- \value DoNotRestoreProperties The state machine should not save the initial values of properties
+ \value DontRestoreProperties The state machine should not save the initial values of properties
and restore them later.
\value RestoreProperties The state machine should save the initial values of properties
and restore them later.
@@ -1776,7 +1776,7 @@ QStateMachine::RestorePolicy QStateMachine::globalRestorePolicy() const
/*!
Sets the restore policy of the state machine to \a restorePolicy. The default
- restore policy is QAbstractState::DoNotRestoreProperties.
+ restore policy is QAbstractState::DontRestoreProperties.
\sa globalRestorePolicy()
*/
@@ -2146,19 +2146,19 @@ void QStateMachine::onExit(QEvent *event)
/*!
Returns whether animations are enabled for this state machine.
*/
-bool QStateMachine::animationsEnabled() const
+bool QStateMachine::isAnimated() const
{
Q_D(const QStateMachine);
- return d->animationsEnabled;
+ return d->animated;
}
/*!
Sets whether animations are \a enabled for this state machine.
*/
-void QStateMachine::setAnimationsEnabled(bool enabled)
+void QStateMachine::setAnimated(bool enabled)
{
Q_D(QStateMachine);
- d->animationsEnabled = enabled;
+ d->animated = enabled;
}
/*!
diff --git a/src/corelib/statemachine/qstatemachine.h b/src/corelib/statemachine/qstatemachine.h
index 13b6fe2..ff2b667 100644
--- a/src/corelib/statemachine/qstatemachine.h
+++ b/src/corelib/statemachine/qstatemachine.h
@@ -67,7 +67,7 @@ class Q_CORE_EXPORT QStateMachine : public QState
Q_PROPERTY(RestorePolicy globalRestorePolicy READ globalRestorePolicy WRITE setGlobalRestorePolicy)
Q_ENUMS(RestorePolicy)
#ifndef QT_NO_ANIMATION
- Q_PROPERTY(bool animationsEnabled READ animationsEnabled WRITE setAnimationsEnabled)
+ Q_PROPERTY(bool animated READ isAnimated WRITE setAnimated)
#endif
public:
class SignalEvent : public QEvent
@@ -109,7 +109,7 @@ public:
};
enum RestorePolicy {
- DoNotRestoreProperties,
+ DontRestoreProperties,
RestoreProperties
};
@@ -133,8 +133,8 @@ public:
bool isRunning() const;
#ifndef QT_NO_ANIMATION
- bool animationsEnabled() const;
- void setAnimationsEnabled(bool enabled);
+ bool isAnimated() const;
+ void setAnimated(bool enabled);
void addDefaultAnimation(QAbstractAnimation *animation);
QList<QAbstractAnimation *> defaultAnimations() const;
diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h
index 01c9361..aad5c67 100644
--- a/src/corelib/statemachine/qstatemachine_p.h
+++ b/src/corelib/statemachine/qstatemachine_p.h
@@ -207,7 +207,7 @@ public:
QSet<QAbstractState *> pendingErrorStatesForDefaultEntry;
#ifndef QT_NO_ANIMATION
- bool animationsEnabled;
+ bool animated;
QPair<QList<QAbstractAnimation*>, QList<QAbstractAnimation*> >
initializeAnimation(QAbstractAnimation *abstractAnimation,
diff --git a/src/corelib/tools/qcontiguouscache.cpp b/src/corelib/tools/qcontiguouscache.cpp
index b0ed701..dd7cab6 100644
--- a/src/corelib/tools/qcontiguouscache.cpp
+++ b/src/corelib/tools/qcontiguouscache.cpp
@@ -56,6 +56,16 @@ void QContiguousCacheData::dump() const
}
#endif
+QContiguousCacheData *QContiguousCacheData::allocate(int size, int alignment)
+{
+ return static_cast<QContiguousCacheData *>(qMallocAligned(size, alignment));
+}
+
+void QContiguousCacheData::free(QContiguousCacheData *data)
+{
+ qFreeAligned(data);
+}
+
/*! \class QContiguousCache
\brief The QContiguousCache class is a template class that provides a contiguous cache.
\ingroup tools
diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h
index ad78d1f..3785938 100644
--- a/src/corelib/tools/qcontiguouscache.h
+++ b/src/corelib/tools/qcontiguouscache.h
@@ -62,6 +62,15 @@ struct Q_CORE_EXPORT QContiguousCacheData
int start;
int offset;
uint sharable : 1;
+ uint reserved : 31;
+
+ // total is 24 bytes (HP-UX aCC: 40 bytes)
+ // the next entry is already aligned to 8 bytes
+ // there will be an 8 byte gap here if T requires 16-byte alignment
+ // (such as long double on 64-bit platforms, __int128, __float128)
+
+ static QContiguousCacheData *allocate(int size, int alignment);
+ static void free(QContiguousCacheData *data);
#ifdef QT_QCONTIGUOUSCACHE_DEBUG
void dump() const;
@@ -69,33 +78,32 @@ struct Q_CORE_EXPORT QContiguousCacheData
};
template <typename T>
-struct QContiguousCacheTypedData
+struct QContiguousCacheTypedData: private QContiguousCacheData
{
- QBasicAtomicInt ref;
- int alloc;
- int count;
- int start;
- int offset;
- uint sharable : 1;
- // uint unused : 31;
-
- // total is 24 bytes (HP-UX aCC: 40 bytes)
- // the next entry is already aligned to 8 bytes
- // there will be an 8 byte gap here if T requires 16-byte alignment
- // (such as long double on 64-bit platforms, __int128, __float128)
-
+ // private inheritance to avoid aliasing warningss
T array[1];
+
+ static inline void free(QContiguousCacheTypedData *data) { QContiguousCacheData::free(data); }
};
template<typename T>
class QContiguousCache {
typedef QContiguousCacheTypedData<T> Data;
- union { QContiguousCacheData *p; QContiguousCacheTypedData<T> *d; };
+ union { QContiguousCacheData *d; QContiguousCacheTypedData<T> *p; };
public:
+ // STL compatibility
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef ptrdiff_t difference_type;
+ typedef int size_type;
+
explicit QContiguousCache(int capacity = 0);
QContiguousCache(const QContiguousCache<T> &v) : d(v.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
- inline ~QContiguousCache() { if (!d) return; if (!d->ref.deref()) free(d); }
+ inline ~QContiguousCache() { if (!d) return; if (!d->ref.deref()) free(p); }
inline void detach() { if (d->ref != 1) detach_helper(); }
inline bool isDetached() const { return d->ref == 1; }
@@ -128,10 +136,10 @@ public:
inline int firstIndex() const { return d->offset; }
inline int lastIndex() const { return d->offset + d->count - 1; }
- inline const T &first() const { Q_ASSERT(!isEmpty()); return d->array[d->start]; }
- inline const T &last() const { Q_ASSERT(!isEmpty()); return d->array[(d->start + d->count -1) % d->alloc]; }
- inline T &first() { Q_ASSERT(!isEmpty()); detach(); return d->array[d->start]; }
- inline T &last() { Q_ASSERT(!isEmpty()); detach(); return d->array[(d->start + d->count -1) % d->alloc]; }
+ inline const T &first() const { Q_ASSERT(!isEmpty()); return p->array[d->start]; }
+ inline const T &last() const { Q_ASSERT(!isEmpty()); return p->array[(d->start + d->count -1) % d->alloc]; }
+ inline T &first() { Q_ASSERT(!isEmpty()); detach(); return p->array[d->start]; }
+ inline T &last() { Q_ASSERT(!isEmpty()); detach(); return p->array[(d->start + d->count -1) % d->alloc]; }
void removeFirst();
T takeFirst();
@@ -156,23 +164,32 @@ private:
// count the padding at the end
return reinterpret_cast<const char *>(&(reinterpret_cast<const Data *>(this))->array[1]) - reinterpret_cast<const char *>(this);
}
+ int alignOfTypedData() const
+ {
+#ifdef Q_ALIGNOF
+ return qMax<int>(sizeof(void*), Q_ALIGNOF(Data));
+#else
+ return 0;
+#endif
+ }
};
template <typename T>
void QContiguousCache<T>::detach_helper()
{
- union { QContiguousCacheData *p; QContiguousCacheTypedData<T> *d; } x;
+ union { QContiguousCacheData *d; QContiguousCacheTypedData<T> *p; } x;
- x.p = malloc(d->alloc);
+ x.d = malloc(d->alloc);
x.d->ref = 1;
x.d->count = d->count;
x.d->start = d->start;
x.d->offset = d->offset;
x.d->alloc = d->alloc;
x.d->sharable = true;
+ x.d->reserved = 0;
- T *dest = x.d->array + x.d->start;
- T *src = d->array + d->start;
+ T *dest = x.p->array + x.d->start;
+ T *src = p->array + d->start;
int oldcount = x.d->count;
while (oldcount--) {
if (QTypeInfo<T>::isComplex) {
@@ -181,15 +198,15 @@ void QContiguousCache<T>::detach_helper()
*dest = *src;
}
dest++;
- if (dest == x.d->array + x.d->alloc)
- dest = x.d->array;
+ if (dest == x.p->array + x.d->alloc)
+ dest = x.p->array;
src++;
- if (src == d->array + d->alloc)
- src = d->array;
+ if (src == p->array + d->alloc)
+ src = p->array;
}
if (!d->ref.deref())
- free(d);
+ free(p);
d = x.d;
}
@@ -199,14 +216,14 @@ void QContiguousCache<T>::setCapacity(int asize)
if (asize == d->alloc)
return;
detach();
- union { QContiguousCacheData *p; QContiguousCacheTypedData<T> *d; } x;
- x.p = malloc(asize);
+ union { QContiguousCacheData *d; QContiguousCacheTypedData<T> *p; } x;
+ x.d = malloc(asize);
x.d->alloc = asize;
x.d->count = qMin(d->count, asize);
x.d->offset = d->offset + d->count - x.d->count;
x.d->start = x.d->offset % x.d->alloc;
- T *dest = x.d->array + (x.d->start + x.d->count-1) % x.d->alloc;
- T *src = d->array + (d->start + d->count-1) % d->alloc;
+ T *dest = x.p->array + (x.d->start + x.d->count-1) % x.d->alloc;
+ T *src = p->array + (d->start + d->count-1) % d->alloc;
int oldcount = x.d->count;
while (oldcount--) {
if (QTypeInfo<T>::isComplex) {
@@ -214,15 +231,15 @@ void QContiguousCache<T>::setCapacity(int asize)
} else {
*dest = *src;
}
- if (dest == x.d->array)
- dest = x.d->array + x.d->alloc;
+ if (dest == x.p->array)
+ dest = x.p->array + x.d->alloc;
dest--;
- if (src == d->array)
- src = d->array + d->alloc;
+ if (src == p->array)
+ src = p->array + d->alloc;
src--;
}
/* free old */
- free(d);
+ free(p);
d = x.d;
}
@@ -232,24 +249,24 @@ void QContiguousCache<T>::clear()
if (d->ref == 1) {
if (QTypeInfo<T>::isComplex) {
int oldcount = d->count;
- T * i = d->array + d->start;
- T * e = d->array + d->alloc;
+ T * i = p->array + d->start;
+ T * e = p->array + d->alloc;
while (oldcount--) {
i->~T();
i++;
if (i == e)
- i = d->array;
+ i = p->array;
}
}
d->count = d->start = d->offset = 0;
} else {
- union { QContiguousCacheData *p; QContiguousCacheTypedData<T> *d; } x;
- x.p = malloc(d->alloc);
+ union { QContiguousCacheData *d; QContiguousCacheTypedData<T> *p; } x;
+ x.d = malloc(d->alloc);
x.d->ref = 1;
x.d->alloc = d->alloc;
x.d->count = x.d->start = x.d->offset = 0;
x.d->sharable = true;
- if (!d->ref.deref()) free(d);
+ if (!d->ref.deref()) free(p);
d = x.d;
}
}
@@ -257,13 +274,13 @@ void QContiguousCache<T>::clear()
template <typename T>
inline QContiguousCacheData *QContiguousCache<T>::malloc(int aalloc)
{
- return static_cast<QContiguousCacheData *>(qMalloc(sizeOfTypedData() + (aalloc - 1) * sizeof(T)));
+ return QContiguousCacheData::allocate(sizeOfTypedData() + (aalloc - 1) * sizeof(T), alignOfTypedData());
}
template <typename T>
QContiguousCache<T>::QContiguousCache(int cap)
{
- p = malloc(cap);
+ d = malloc(cap);
d->ref = 1;
d->alloc = cap;
d->count = d->start = d->offset = 0;
@@ -303,16 +320,16 @@ void QContiguousCache<T>::free(Data *x)
{
if (QTypeInfo<T>::isComplex) {
int oldcount = d->count;
- T * i = d->array + d->start;
- T * e = d->array + d->alloc;
+ T * i = p->array + d->start;
+ T * e = p->array + d->alloc;
while (oldcount--) {
i->~T();
i++;
if (i == e)
- i = d->array;
+ i = p->array;
}
}
- qFree(x);
+ x->free(x);
}
template <typename T>
void QContiguousCache<T>::append(const T &value)
@@ -320,10 +337,10 @@ void QContiguousCache<T>::append(const T &value)
detach();
if (QTypeInfo<T>::isComplex) {
if (d->count == d->alloc)
- (d->array + (d->start+d->count) % d->alloc)->~T();
- new (d->array + (d->start+d->count) % d->alloc) T(value);
+ (p->array + (d->start+d->count) % d->alloc)->~T();
+ new (p->array + (d->start+d->count) % d->alloc) T(value);
} else {
- d->array[(d->start+d->count) % d->alloc] = value;
+ p->array[(d->start+d->count) % d->alloc] = value;
}
if (d->count == d->alloc) {
@@ -349,12 +366,12 @@ void QContiguousCache<T>::prepend(const T &value)
d->count++;
else
if (d->count == d->alloc)
- (d->array + d->start)->~T();
+ (p->array + d->start)->~T();
if (QTypeInfo<T>::isComplex)
- new (d->array + d->start) T(value);
+ new (p->array + d->start) T(value);
else
- d->array[d->start] = value;
+ p->array[d->start] = value;
}
template<typename T>
@@ -364,9 +381,9 @@ void QContiguousCache<T>::insert(int pos, const T &value)
detach();
if (containsIndex(pos)) {
if(QTypeInfo<T>::isComplex)
- new (d->array + pos % d->alloc) T(value);
+ new (p->array + pos % d->alloc) T(value);
else
- d->array[pos % d->alloc] = value;
+ p->array[pos % d->alloc] = value;
} else if (pos == d->offset-1)
prepend(value);
else if (pos == d->offset+d->count)
@@ -378,18 +395,18 @@ void QContiguousCache<T>::insert(int pos, const T &value)
d->start = pos % d->alloc;
d->count = 1;
if (QTypeInfo<T>::isComplex)
- new (d->array + d->start) T(value);
+ new (p->array + d->start) T(value);
else
- d->array[d->start] = value;
+ p->array[d->start] = value;
}
}
template <typename T>
inline const T &QContiguousCache<T>::at(int pos) const
-{ Q_ASSERT_X(pos >= d->offset && pos - d->offset < d->count, "QContiguousCache<T>::at", "index out of range"); return d->array[pos % d->alloc]; }
+{ Q_ASSERT_X(pos >= d->offset && pos - d->offset < d->count, "QContiguousCache<T>::at", "index out of range"); return p->array[pos % d->alloc]; }
template <typename T>
inline const T &QContiguousCache<T>::operator[](int pos) const
-{ Q_ASSERT_X(pos >= d->offset && pos - d->offset < d->count, "QContiguousCache<T>::at", "index out of range"); return d->array[pos % d->alloc]; }
+{ Q_ASSERT_X(pos >= d->offset && pos - d->offset < d->count, "QContiguousCache<T>::at", "index out of range"); return p->array[pos % d->alloc]; }
template <typename T>
inline T &QContiguousCache<T>::operator[](int pos)
@@ -397,7 +414,7 @@ inline T &QContiguousCache<T>::operator[](int pos)
detach();
if (!containsIndex(pos))
insert(pos, T());
- return d->array[pos % d->alloc];
+ return p->array[pos % d->alloc];
}
template <typename T>
@@ -407,7 +424,7 @@ inline void QContiguousCache<T>::removeFirst()
detach();
d->count--;
if (QTypeInfo<T>::isComplex)
- (d->array + d->start)->~T();
+ (p->array + d->start)->~T();
d->start = (d->start + 1) % d->alloc;
d->offset++;
}
@@ -419,7 +436,7 @@ inline void QContiguousCache<T>::removeLast()
detach();
d->count--;
if (QTypeInfo<T>::isComplex)
- (d->array + (d->start + d->count) % d->alloc)->~T();
+ (p->array + (d->start + d->count) % d->alloc)->~T();
}
template <typename T>
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index f33aba9..c82c389 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -166,29 +166,38 @@ static int countBits(int hint)
const int MinNumBits = 4;
QHashData QHashData::shared_null = {
- 0, 0, Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, MinNumBits, 0, 0, true
+ 0, 0, Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, MinNumBits, 0, 0, true, false, 0
};
void *QHashData::allocateNode()
{
- void *ptr = qMalloc(nodeSize);
+ return allocateNode(0);
+}
+
+void *QHashData::allocateNode(int nodeAlign)
+{
+ void *ptr = strictAlignment ? qMallocAligned(nodeSize, nodeAlign) : qMalloc(nodeSize);
Q_CHECK_PTR(ptr);
return ptr;
}
void QHashData::freeNode(void *node)
{
- qFree(node);
+ if (strictAlignment)
+ qFreeAligned(node);
+ else
+ qFree(node);
}
QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize)
{
- return detach_helper( node_duplicate, 0, nodeSize );
+ return detach_helper2( node_duplicate, 0, nodeSize, 0 );
}
-QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *),
- void (*node_delete)(Node *),
- int nodeSize)
+QHashData *QHashData::detach_helper2(void (*node_duplicate)(Node *, void *),
+ void (*node_delete)(Node *),
+ int nodeSize,
+ int nodeAlign)
{
union {
QHashData *d;
@@ -204,6 +213,8 @@ QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *),
d->numBits = numBits;
d->numBuckets = numBuckets;
d->sharable = true;
+ d->strictAlignment = nodeAlign > 8;
+ d->reserved = 0;
if (numBuckets) {
QT_TRY {
@@ -222,7 +233,7 @@ QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *),
Node *oldNode = buckets[i];
while (oldNode != this_e) {
QT_TRY {
- Node *dup = static_cast<Node *>(allocateNode());
+ Node *dup = static_cast<Node *>(allocateNode(nodeAlign));
QT_TRY {
node_duplicate(oldNode, dup);
@@ -262,6 +273,7 @@ void QHashData::free_helper(void (*node_delete)(Node *))
while (cur != this_e) {
Node *next = cur->next;
node_delete(cur);
+ freeNode(cur);
cur = next;
}
}
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index b65f1d3..1918229 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -125,12 +125,15 @@ struct Q_CORE_EXPORT QHashData
short numBits;
int numBuckets;
uint sharable : 1;
+ uint strictAlignment : 1;
+ uint reserved : 30;
- void *allocateNode();
+ void *allocateNode(); // ### Qt5 remove me
+ void *allocateNode(int nodeAlign);
void freeNode(void *node);
QHashData *detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize); // ### Qt5 remove me
- QHashData *detach_helper(void (*node_duplicate)(Node *, void *), void (*node_delete)(Node *),
- int nodeSize);
+ QHashData *detach_helper2(void (*node_duplicate)(Node *, void *), void (*node_delete)(Node *),
+ int nodeSize, int nodeAlign);
void mightGrow();
bool willGrow();
void hasShrunk();
@@ -267,6 +270,14 @@ class QHash
return reinterpret_cast<Node *>(node);
}
+#ifdef Q_ALIGNOF
+ static inline int alignOfNode() { return qMax<int>(sizeof(void*), Q_ALIGNOF(Node)); }
+ static inline int alignOfDummyNode() { return qMax<int>(sizeof(void*), Q_ALIGNOF(DummyNode)); }
+#else
+ static inline int alignOfNode() { return 0; }
+ static inline int alignOfDummyNode() { return 0; }
+#endif
+
public:
inline QHash() : d(&QHashData::shared_null) { d->ref.ref(); }
inline QHash(const QHash<Key, T> &other) : d(other.d) { d->ref.ref(); if (!d->sharable) detach(); }
@@ -483,7 +494,7 @@ private:
Node **findNode(const Key &key, uint *hp = 0) const;
Node *createNode(uint h, const Key &key, const T &value, Node **nextNode);
void deleteNode(Node *node);
- static void deleteNode(QHashData::Node *node);
+ static void deleteNode2(QHashData::Node *node);
static void duplicateNode(QHashData::Node *originalNode, void *newNode);
};
@@ -492,12 +503,12 @@ private:
template <class Key, class T>
Q_INLINE_TEMPLATE void QHash<Key, T>::deleteNode(Node *node)
{
- deleteNode(reinterpret_cast<QHashData::Node*>(node));
+ deleteNode2(reinterpret_cast<QHashData::Node*>(node));
+ d->freeNode(node);
}
-
template <class Key, class T>
-Q_INLINE_TEMPLATE void QHash<Key, T>::deleteNode(QHashData::Node *node)
+Q_INLINE_TEMPLATE void QHash<Key, T>::deleteNode2(QHashData::Node *node)
{
#ifdef Q_CC_BOR
concrete(node)->~QHashNode<Key, T>();
@@ -506,7 +517,6 @@ Q_INLINE_TEMPLATE void QHash<Key, T>::deleteNode(QHashData::Node *node)
#else
concrete(node)->~Node();
#endif
- qFree(node);
}
template <class Key, class T>
@@ -527,9 +537,9 @@ QHash<Key, T>::createNode(uint ah, const Key &akey, const T &avalue, Node **anex
Node *node;
if (QTypeInfo<T>::isDummy) {
- node = reinterpret_cast<Node *>(new (d->allocateNode()) DummyNode(akey));
+ node = reinterpret_cast<Node *>(new (d->allocateNode(alignOfDummyNode())) DummyNode(akey));
} else {
- node = new (d->allocateNode()) Node(akey, avalue);
+ node = new (d->allocateNode(alignOfNode())) Node(akey, avalue);
}
node->h = ah;
@@ -554,7 +564,7 @@ Q_INLINE_TEMPLATE QHash<Key, T> &QHash<Key, T>::unite(const QHash<Key, T> &other
template <class Key, class T>
Q_OUTOFLINE_TEMPLATE void QHash<Key, T>::freeData(QHashData *x)
{
- x->free_helper(deleteNode);
+ x->free_helper(deleteNode2);
}
template <class Key, class T>
@@ -566,8 +576,9 @@ Q_INLINE_TEMPLATE void QHash<Key, T>::clear()
template <class Key, class T>
Q_OUTOFLINE_TEMPLATE void QHash<Key, T>::detach_helper()
{
- QHashData *x = d->detach_helper(duplicateNode, deleteNode,
- QTypeInfo<T>::isDummy ? sizeof(DummyNode) : sizeof(Node));
+ QHashData *x = d->detach_helper2(duplicateNode, deleteNode2,
+ QTypeInfo<T>::isDummy ? sizeof(DummyNode) : sizeof(Node),
+ QTypeInfo<T>::isDummy ? alignOfDummyNode() : alignOfNode());
if (!d->ref.deref())
freeData(d);
d = x;
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index 1385810..3b48c3f 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -53,11 +53,16 @@ QT_BEGIN_NAMESPACE
QMapData QMapData::shared_null = {
&shared_null,
{ &shared_null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, 0, false, true
+ Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, 0, false, true, false, 0
};
QMapData *QMapData::createData()
{
+ return createData(0);
+}
+
+QMapData *QMapData::createData(int alignment)
+{
QMapData *d = new QMapData;
Q_CHECK_PTR(d);
Node *e = reinterpret_cast<Node *>(d);
@@ -69,6 +74,8 @@ QMapData *QMapData::createData()
d->randomBits = 0;
d->insertInOrder = false;
d->sharable = true;
+ d->strictAlignment = alignment > 8;
+ d->reserved = 0;
return d;
}
@@ -80,11 +87,19 @@ void QMapData::continueFreeData(int offset)
while (cur != e) {
prev = cur;
cur = cur->forward[0];
- qFree(reinterpret_cast<char *>(prev) - offset);
+ if (strictAlignment)
+ qFreeAligned(reinterpret_cast<char *>(prev) - offset);
+ else
+ qFree(reinterpret_cast<char *>(prev) - offset);
}
delete this;
}
+QMapData::Node *QMapData::node_create(Node *update[], int offset)
+{
+ return node_create(update, offset, 0);
+}
+
/*!
Creates a new node inside the data structure.
@@ -94,10 +109,12 @@ void QMapData::continueFreeData(int offset)
\a offset is an amount of bytes that needs to reserved just before the
QMapData::Node structure.
+ \a alignment dictates the alignment for the data.
+
\internal
\since 4.6
*/
-QMapData::Node *QMapData::node_create(Node *update[], int offset)
+QMapData::Node *QMapData::node_create(Node *update[], int offset, int alignment)
{
int level = 0;
uint mask = (1 << Sparseness) - 1;
@@ -118,7 +135,9 @@ QMapData::Node *QMapData::node_create(Node *update[], int offset)
if (level == 3 && !insertInOrder)
randomBits = qrand();
- void *concreteNode = qMalloc(offset + sizeof(Node) + level * sizeof(Node *));
+ void *concreteNode = strictAlignment ?
+ qMallocAligned(offset + sizeof(Node) + level * sizeof(Node *), alignment) :
+ qMalloc(offset + sizeof(Node) + level * sizeof(Node *));
Q_CHECK_PTR(concreteNode);
Node *abstractNode = reinterpret_cast<Node *>(reinterpret_cast<char *>(concreteNode) + offset);
@@ -145,7 +164,10 @@ void QMapData::node_delete(Node *update[], int offset, Node *node)
update[i]->forward[i] = node->forward[i];
}
--size;
- qFree(reinterpret_cast<char *>(node) - offset);
+ if (strictAlignment)
+ qFreeAligned(reinterpret_cast<char *>(node) - offset);
+ else
+ qFree(reinterpret_cast<char *>(node) - offset);
}
#ifdef QT_QMAP_DEBUG
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 688aca6..65c3d2a 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -74,10 +74,14 @@ struct Q_CORE_EXPORT QMapData
uint randomBits;
uint insertInOrder : 1;
uint sharable : 1;
+ uint strictAlignment : 1;
+ uint reserved : 29;
- static QMapData *createData();
+ static QMapData *createData(); // ### Qt5 remove me
+ static QMapData *createData(int alignment);
void continueFreeData(int offset);
- Node *node_create(Node *update[], int offset);
+ Node *node_create(Node *update[], int offset); // ### Qt5 remove me
+ Node *node_create(Node *update[], int offset, int alignment);
void node_delete(Node *update[], int offset, Node *node);
#ifdef QT_QMAP_DEBUG
uint adjust_ptr(Node *node);
@@ -145,6 +149,13 @@ class QMap
};
static inline int payload() { return sizeof(PayloadNode) - sizeof(QMapData::Node *); }
+ static inline int alignment() {
+#ifdef Q_ALIGNOF
+ return qMax(sizeof(void*), Q_ALIGNOF(Node));
+#else
+ return 0;
+#endif
+ }
static inline Node *concrete(QMapData::Node *node) {
return reinterpret_cast<Node *>(reinterpret_cast<char *>(node) - payload());
}
@@ -414,7 +425,7 @@ template <class Key, class T>
Q_INLINE_TEMPLATE typename QMapData::Node *
QMap<Key, T>::node_create(QMapData *adt, QMapData::Node *aupdate[], const Key &akey, const T &avalue)
{
- QMapData::Node *abstractNode = adt->node_create(aupdate, payload());
+ QMapData::Node *abstractNode = adt->node_create(aupdate, payload(), alignment());
QT_TRY {
Node *concreteNode = concrete(abstractNode);
new (&concreteNode->key) Key(akey);
@@ -715,7 +726,7 @@ template <class Key, class T>
Q_OUTOFLINE_TEMPLATE void QMap<Key, T>::detach_helper()
{
union { QMapData *d; QMapData::Node *e; } x;
- x.d = QMapData::createData();
+ x.d = QMapData::createData(alignment());
if (d->size) {
x.d->insertInOrder = true;
QMapData::Node *update[QMapData::LastLevel + 1];
@@ -905,7 +916,7 @@ Q_OUTOFLINE_TEMPLATE bool QMap<Key, T>::operator==(const QMap<Key, T> &other) co
template <class Key, class T>
Q_OUTOFLINE_TEMPLATE QMap<Key, T>::QMap(const std::map<Key, T> &other)
{
- d = QMapData::createData();
+ d = QMapData::createData(alignment());
d->insertInOrder = true;
typename std::map<Key,T>::const_iterator it = other.end();
while (it != other.begin()) {
diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp
index 20f3a80..8bb1074 100644
--- a/src/corelib/tools/qvector.cpp
+++ b/src/corelib/tools/qvector.cpp
@@ -45,7 +45,14 @@
QT_BEGIN_NAMESPACE
-QVectorData QVectorData::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, true, false };
+static inline int alignmentThreshold()
+{
+ // malloc on 32-bit platforms should return pointers that are 8-byte aligned or more
+ // while on 64-bit platforms they should be 16-byte aligned or more
+ return 2 * sizeof(void*);
+}
+
+QVectorData QVectorData::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, true, false, 0 };
QVectorData *QVectorData::malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init)
{
@@ -55,6 +62,26 @@ QVectorData *QVectorData::malloc(int sizeofTypedData, int size, int sizeofT, QVe
return p;
}
+QVectorData *QVectorData::allocate(int size, int alignment)
+{
+ return static_cast<QVectorData *>(alignment > alignmentThreshold() ? qMallocAligned(size, alignment) : qMalloc(size));
+}
+
+QVectorData *QVectorData::reallocate(QVectorData *x, int newsize, int oldsize, int alignment)
+{
+ if (alignment > alignmentThreshold())
+ return static_cast<QVectorData *>(qReallocAligned(x, newsize, oldsize, alignment));
+ return static_cast<QVectorData *>(qRealloc(x, newsize));
+}
+
+void QVectorData::free(QVectorData *x, int alignment)
+{
+ if (alignment > alignmentThreshold())
+ qFreeAligned(x);
+ else
+ qFree(x);
+}
+
int QVectorData::grow(int sizeofTypedData, int size, int sizeofT, bool excessive)
{
if (excessive)
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index b77b53a..7402d77 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -72,6 +72,7 @@ struct Q_CORE_EXPORT QVectorData
#else
uint sharable : 1;
uint capacity : 1;
+ uint reserved : 30;
#endif
static QVectorData shared_null;
@@ -79,6 +80,9 @@ struct Q_CORE_EXPORT QVectorData
// some debugges when the QVector is member of a class within an unnamed namespace.
// ### Qt 5: can be removed completely. (Ralf)
static QVectorData *malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init);
+ static QVectorData *allocate(int size, int alignment);
+ static QVectorData *reallocate(QVectorData *old, int newsize, int oldsize, int alignment);
+ static void free(QVectorData *data, int alignment);
static int grow(int sizeofTypedData, int size, int sizeofT, bool excessive);
};
@@ -87,6 +91,8 @@ struct QVectorTypedData : private QVectorData
{ // private inheritance as we must not access QVectorData member thought QVectorTypedData
// as this would break strict aliasing rules. (in the case of shared_null)
T array[1];
+
+ static inline void free(QVectorTypedData *x, int alignment) { QVectorData::free(x, alignment); }
};
class QRegion;
@@ -302,6 +308,14 @@ private:
// count the padding at the end
return reinterpret_cast<const char *>(&(reinterpret_cast<const Data *>(this))->array[1]) - reinterpret_cast<const char *>(this);
}
+ inline int alignOfTypedData() const
+ {
+#ifdef Q_ALIGNOF
+ return qMax<int>(sizeof(void*), Q_ALIGNOF(Data));
+#else
+ return 0;
+#endif
+ }
};
template <typename T>
@@ -373,7 +387,7 @@ QVector<T> &QVector<T>::operator=(const QVector<T> &v)
template <typename T>
inline QVectorData *QVector<T>::malloc(int aalloc)
{
- QVectorData *vectordata = static_cast<QVectorData *>(qMalloc(sizeOfTypedData() + (aalloc - 1) * sizeof(T)));
+ QVectorData *vectordata = QVectorData::allocate(sizeOfTypedData() + (aalloc - 1) * sizeof(T), alignOfTypedData());
Q_CHECK_PTR(vectordata);
return vectordata;
}
@@ -420,7 +434,7 @@ void QVector<T>::free(Data *x)
while (i-- != b)
i->~T();
}
- qFree(x);
+ x->free(x, alignOfTypedData());
}
template <typename T>
@@ -459,7 +473,8 @@ void QVector<T>::realloc(int asize, int aalloc)
}
} else {
QT_TRY {
- QVectorData *mem = static_cast<QVectorData *>(qRealloc(p, sizeOfTypedData() + (aalloc - 1) * sizeof(T)));
+ QVectorData *mem = QVectorData::reallocate(d, sizeOfTypedData() + (aalloc - 1) * sizeof(T),
+ sizeOfTypedData() + (d->alloc - 1) * sizeof(T), alignOfTypedData());
Q_CHECK_PTR(mem);
x.d = d = mem;
x.d->size = d->size;
@@ -472,6 +487,7 @@ void QVector<T>::realloc(int asize, int aalloc)
x.d->alloc = aalloc;
x.d->sharable = true;
x.d->capacity = d->capacity;
+ x.d->reserved = 0;
}
if (QTypeInfo<T>::isComplex) {