summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp19
-rw-r--r--src/corelib/kernel/qdeadlinetimer.h4
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix_p.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp82
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h1
-rw-r--r--src/corelib/kernel/qmetatype.cpp3
-rw-r--r--src/corelib/kernel/qmetatype.h88
-rw-r--r--src/corelib/kernel/qobject.cpp78
-rw-r--r--src/corelib/kernel/qobject.h4
-rw-r--r--src/corelib/kernel/qobjectdefs.h2
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h4
-rw-r--r--src/corelib/kernel/qtimer.cpp8
-rw-r--r--src/corelib/kernel/qtimer.h6
-rw-r--r--src/corelib/kernel/qvariant.cpp39
-rw-r--r--src/corelib/kernel/qvariant.h17
-rw-r--r--src/corelib/kernel/qvariant_p.h5
17 files changed, 221 insertions, 143 deletions
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index b1f3b74cd4..a042361686 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -247,7 +247,7 @@ AppleApplication *qt_apple_sharedApplication()
qWarning() << "accessing the shared" << [AppleApplication class]
<< "is not allowed in application extensions";
- // In practice the application is actually available, but the the App
+ // In practice the application is actually available, but the App
// review process will likely catch uses of it, so we return nil just
// in case, unless we don't care about being App Store compliant.
#if QT_CONFIG(appstore_compliant)
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index e25049f821..70f0a5ad4c 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -121,7 +121,6 @@
#endif
#ifdef Q_OS_WASM
-#include <emscripten.h>
#include <emscripten/val.h>
#endif
@@ -497,13 +496,6 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
QCoreApplicationPrivate::~QCoreApplicationPrivate()
{
-#ifdef Q_OS_WASM
- EM_ASM(
- // unmount persistent directory as IDBFS
- // see also QTBUG-70002
- FS.unmount('/home/web_user');
- );
-#endif
#ifndef QT_NO_QOBJECT
cleanupThreadData();
#endif
@@ -795,17 +787,8 @@ void QCoreApplicationPrivate::init()
Q_ASSERT_X(!QCoreApplication::self, "QCoreApplication", "there should be only one application object");
QCoreApplication::self = q;
-#ifdef Q_OS_WASM
- EM_ASM(
- // mount and sync persistent filesystem to sandbox
- FS.mount(IDBFS, {}, '/home/web_user');
- FS.syncfs(true, function(err) {
- if (err)
- Module.print(err);
- });
- );
-
#if QT_CONFIG(thread)
+#ifdef Q_OS_WASM
QThreadPrivate::idealThreadCount = emscripten::val::global("navigator")["hardwareConcurrency"].as<int>();
#endif
#endif
diff --git a/src/corelib/kernel/qdeadlinetimer.h b/src/corelib/kernel/qdeadlinetimer.h
index 9dd92481d2..99e09eb31f 100644
--- a/src/corelib/kernel/qdeadlinetimer.h
+++ b/src/corelib/kernel/qdeadlinetimer.h
@@ -52,7 +52,7 @@
#include <limits>
-#if QT_HAS_INCLUDE(<chrono>)
+#if __has_include(<chrono>)
# include <chrono>
#endif
@@ -120,7 +120,7 @@ public:
QDeadlineTimer &operator-=(qint64 msecs)
{ *this = *this + (-msecs); return *this; }
-#if QT_HAS_INCLUDE(<chrono>) || defined(Q_CLANG_QDOC)
+#if __has_include(<chrono>) || defined(Q_CLANG_QDOC)
template <class Clock, class Duration>
QDeadlineTimer(std::chrono::time_point<Clock, Duration> deadline_,
Qt::TimerType type_ = Qt::CoarseTimer) : t2(0)
diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h
index f37edfc967..581df9242c 100644
--- a/src/corelib/kernel/qeventdispatcher_unix_p.h
+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h
@@ -118,7 +118,7 @@ public:
int remainingTime(int timerId) final;
- void wakeUp() final;
+ void wakeUp() override;
void interrupt() final;
void flush() override;
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 87623f304a..56b60e67e0 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -84,10 +84,8 @@ enum {
WM_QT_ACTIVATENOTIFIERS = WM_USER + 2
};
-// WM_QT_SENDPOSTEDEVENTS message parameter
enum {
- WMWP_QT_TOFOREIGNLOOP = 0,
- WMWP_QT_FROMWAKEUP
+ SendPostedEventsTimerId = ~1u
};
class QEventDispatcherWin32Private;
@@ -100,8 +98,8 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
: threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0),
- getMessageHook(0), wakeUps(0), activateNotifiersPosted(false),
- winEventNotifierActivatedEvent(NULL)
+ getMessageHook(0), sendPostedEventsTimerId(0), wakeUps(0),
+ activateNotifiersPosted(false), winEventNotifierActivatedEvent(NULL)
{
}
@@ -129,6 +127,18 @@ void WINAPI QT_WIN_CALLBACK qt_fast_timer_proc(uint timerId, uint /*reserved*/,
QCoreApplication::postEvent(t->dispatcher, new QTimerEvent(t->timerId));
}
+static inline UINT inputQueueMask()
+{
+ UINT result = QS_ALLEVENTS;
+ // QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of
+ // QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8.
+#if WINVER > 0x0601
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8)
+ result &= ~(QS_TOUCH | QS_POINTER);
+#endif // WINVER > 0x0601
+ return result;
+}
+
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
{
if (message == WM_NCCREATE)
@@ -240,47 +250,39 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
case WM_TIMER:
Q_ASSERT(d != 0);
- d->sendTimerEvent(wp);
+ if (wp == d->sendPostedEventsTimerId)
+ q->sendPostedEvents();
+ else
+ d->sendTimerEvent(wp);
return 0;
case WM_QT_SENDPOSTEDEVENTS:
Q_ASSERT(d != 0);
// We send posted events manually, if the window procedure was invoked
// by the foreign event loop (e.g. from the native modal dialog).
- q->sendPostedEvents();
+ // Skip sending, if the message queue is not empty.
+ // sendPostedEventsTimer will deliver posted events later.
+ static const UINT mask = inputQueueMask();
+ if (HIWORD(GetQueueStatus(mask)) == 0)
+ q->sendPostedEvents();
return 0;
} // switch (message)
return DefWindowProc(hwnd, message, wp, lp);
}
-static inline UINT inputQueueMask()
-{
- UINT result = QS_ALLEVENTS;
- // QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of
- // QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8.
-#if WINVER > 0x0601
- if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8)
- result &= ~(QS_TOUCH | QS_POINTER);
-#endif // WINVER > 0x0601
- return result;
-}
-
LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
{
QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance());
Q_ASSERT(q != 0);
QEventDispatcherWin32Private *d = q->d_func();
MSG *msg = reinterpret_cast<MSG *>(lp);
- static const UINT mask = inputQueueMask();
-
- if (HIWORD(GetQueueStatus(mask)) == 0 && wp == PM_REMOVE) {
- // Allow posting WM_QT_SENDPOSTEDEVENTS message.
- d->wakeUps.storeRelaxed(0);
- if (!(msg->hwnd == d->internalHwnd && msg->message == WM_QT_SENDPOSTEDEVENTS)) {
- PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS,
- WMWP_QT_TOFOREIGNLOOP, 0);
- }
+
+ if (msg->hwnd == d->internalHwnd && msg->message == WM_QT_SENDPOSTEDEVENTS
+ && wp == PM_REMOVE && d->sendPostedEventsTimerId == 0) {
+ // Start a timer to deliver posted events when the message queue is emptied.
+ d->sendPostedEventsTimerId = SetTimer(d->internalHwnd, SendPostedEventsTimerId,
+ USER_TIMER_MINIMUM, NULL);
}
return d->getMessageHook ? CallNextHookEx(0, code, wp, lp) : 0;
}
@@ -571,12 +573,15 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
}
if (haveMessage) {
if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {
- // Set result to 'true', if the message was sent by wakeUp().
- if (msg.wParam == WMWP_QT_FROMWAKEUP)
- retVal = true;
+ // Set result to 'true' because the message was sent by wakeUp().
+ retVal = true;
continue;
}
if (msg.message == WM_TIMER) {
+ // Skip timer event intended for use inside foreign loop.
+ if (d->internalHwnd == msg.hwnd && msg.wParam == d->sendPostedEventsTimerId)
+ continue;
+
// avoid live-lock by keeping track of the timers we've already sent
bool found = false;
for (int i = 0; !found && i < processedTimers.count(); ++i) {
@@ -964,8 +969,7 @@ void QEventDispatcherWin32::wakeUp()
Q_D(QEventDispatcherWin32);
if (d->internalHwnd && d->wakeUps.testAndSetAcquire(0, 1)) {
// post a WM_QT_SENDPOSTEDEVENTS to this thread if there isn't one already pending
- if (!PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS,
- WMWP_QT_FROMWAKEUP, 0))
+ if (!PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0))
qErrnoWarning("QEventDispatcherWin32::wakeUp: Failed to post a message");
}
}
@@ -1007,6 +1011,10 @@ void QEventDispatcherWin32::closingDown()
if (d->getMessageHook)
UnhookWindowsHookEx(d->getMessageHook);
d->getMessageHook = 0;
+
+ if (d->sendPostedEventsTimerId != 0)
+ KillTimer(d->internalHwnd, d->sendPostedEventsTimerId);
+ d->sendPostedEventsTimerId = 0;
}
bool QEventDispatcherWin32::event(QEvent *e)
@@ -1048,6 +1056,14 @@ bool QEventDispatcherWin32::event(QEvent *e)
void QEventDispatcherWin32::sendPostedEvents()
{
Q_D(QEventDispatcherWin32);
+
+ if (d->sendPostedEventsTimerId != 0)
+ KillTimer(d->internalHwnd, d->sendPostedEventsTimerId);
+ d->sendPostedEventsTimerId = 0;
+
+ // Allow posting WM_QT_SENDPOSTEDEVENTS message.
+ d->wakeUps.storeRelaxed(0);
+
QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
}
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index e6620178d8..8f6f05e0a7 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -170,6 +170,7 @@ public:
HHOOK getMessageHook;
// for controlling when to send posted events
+ UINT_PTR sendPostedEventsTimerId;
QAtomicInt wakeUps;
// timers
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 356a675517..9fc0659cf2 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -589,7 +589,8 @@ QMetaTypeComparatorRegistry;
typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractDebugStreamFunction,int>
QMetaTypeDebugStreamRegistry;
-Q_STATIC_ASSERT(std::is_pod<QMetaTypeInterface>::value);
+Q_STATIC_ASSERT(std::is_trivial<QMetaTypeInterface>::value);
+Q_STATIC_ASSERT(std::is_standard_layout<QMetaTypeInterface>::value);
Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index d41f7ee80e..d13fdeb642 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -977,6 +977,30 @@ enum IteratorCapability
RandomAccessCapability = 4
};
+enum ContainerCapability
+{
+ ContainerIsAppendable = 1
+};
+
+template<typename Container, typename T = void>
+struct ContainerCapabilitiesImpl
+{
+ enum {ContainerCapabilities = 0};
+ using appendFunction = void(*)(const void *container, const void *newElement);
+ static constexpr const appendFunction appendImpl = nullptr;
+};
+
+template<typename Container>
+struct ContainerCapabilitiesImpl<Container, decltype(std::declval<Container>().push_back(std::declval<typename Container::value_type>()))>
+{
+ enum {ContainerCapabilities = ContainerIsAppendable};
+
+ // The code below invokes undefined behavior if and only if the pointer passed into QSequentialIterableImpl
+ // pointed to a const object to begin with
+ static void appendImpl(const void *container, const void *value)
+ { static_cast<Container *>(const_cast<void *>(container))->push_back(*static_cast<const typename Container::value_type *>(value)); }
+};
+
template<typename T, typename Category = typename std::iterator_traits<typename T::const_iterator>::iterator_category>
struct CapabilitiesImpl;
@@ -1012,6 +1036,12 @@ template<typename T>
struct ContainerAPI<std::list<T> > : CapabilitiesImpl<std::list<T> >
{ static int size(const std::list<T> *t) { return int(t->size()); } };
+/*
+ revision 0: _iteratorCapabilities is simply a uint, where the bits at _revision were never set
+ revision 1: _iteratorCapabilties is treated as a bitfield, the remaining bits are used to introduce
+ _revision, _containerCapabilities and _unused. The latter contains 21 bits that are
+ not used yet
+*/
class QSequentialIterableImpl
{
public:
@@ -1020,19 +1050,37 @@ public:
int _metaType_id;
uint _metaType_flags;
uint _iteratorCapabilities;
+ // Iterator capabilities looks actually like
+ // uint _iteratorCapabilities:4;
+ // uint _revision:3;
+ // uint _containerCapabilities:4;
+ // uint _unused:21;*/
typedef int(*sizeFunc)(const void *p);
typedef const void * (*atFunc)(const void *p, int);
typedef void (*moveIteratorFunc)(const void *p, void **);
+ enum Position { ToBegin, ToEnd };
+ typedef void (*moveIteratorFunc2)(const void *p, void **, Position position);
typedef void (*advanceFunc)(void **p, int);
typedef VariantData (*getFunc)( void * const *p, int metaTypeId, uint flags);
typedef void (*destroyIterFunc)(void **p);
typedef bool (*equalIterFunc)(void * const *p, void * const *other);
typedef void (*copyIterFunc)(void **, void * const *);
+ typedef void(*appendFunction)(const void *container, const void *newElement);
+
+ IteratorCapability iteratorCapabilities() {return static_cast<IteratorCapability>(_iteratorCapabilities & 0xF);}
+ uint revision() {return _iteratorCapabilities >> 4 & 0x7;}
+ uint containerCapabilities() {return _iteratorCapabilities >> 7 & 0xF;}
sizeFunc _size;
atFunc _at;
- moveIteratorFunc _moveToBegin;
- moveIteratorFunc _moveToEnd;
+ union {
+ moveIteratorFunc _moveToBegin;
+ moveIteratorFunc2 _moveTo;
+ };
+ union {
+ moveIteratorFunc _moveToEnd;
+ appendFunction _append;
+ };
advanceFunc _advance;
getFunc _get;
destroyIterFunc _destroyIter;
@@ -1059,6 +1107,15 @@ public:
static void moveToEndImpl(const void *container, void **iterator)
{ IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
+ template<class Container>
+ static void moveToImpl(const void *container, void **iterator, Position position)
+ {
+ if (position == ToBegin)
+ moveToBeginImpl<Container>(container, iterator);
+ else
+ moveToEndImpl<Container>(container, iterator);
+ }
+
template<class T>
static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, IteratorOwner<typename T::const_iterator>::getData(iterator), flags); }
@@ -1069,11 +1126,11 @@ public:
, _iterator(nullptr)
, _metaType_id(qMetaTypeId<typename T::value_type>())
, _metaType_flags(QTypeInfo<typename T::value_type>::isPointer)
- , _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities)
+ , _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities | (1 << 4) | (ContainerCapabilitiesImpl<T>::ContainerCapabilities << (4+3)))
, _size(sizeImpl<T>)
, _at(atImpl<T>)
- , _moveToBegin(moveToBeginImpl<T>)
- , _moveToEnd(moveToEndImpl<T>)
+ , _moveTo(moveToImpl<T>)
+ , _append(ContainerCapabilitiesImpl<T>::appendImpl)
, _advance(IteratorOwner<typename T::const_iterator>::advance)
, _get(getImpl<T>)
, _destroyIter(IteratorOwner<typename T::const_iterator>::destroy)
@@ -1087,7 +1144,7 @@ public:
, _iterator(nullptr)
, _metaType_id(QMetaType::UnknownType)
, _metaType_flags(0)
- , _iteratorCapabilities(0)
+ , _iteratorCapabilities(0 | (1 << 4) ) // no iterator capabilities, revision 1
, _size(nullptr)
, _at(nullptr)
, _moveToBegin(nullptr)
@@ -1100,8 +1157,18 @@ public:
{
}
- inline void moveToBegin() { _moveToBegin(_iterable, &_iterator); }
- inline void moveToEnd() { _moveToEnd(_iterable, &_iterator); }
+ inline void moveToBegin() {
+ if (revision() == 0)
+ _moveToBegin(_iterable, &_iterator);
+ else
+ _moveTo(_iterable, &_iterator, ToBegin);
+ }
+ inline void moveToEnd() {
+ if (revision() == 0)
+ _moveToEnd(_iterable, &_iterator);
+ else
+ _moveTo(_iterable, &_iterator, ToEnd);
+ }
inline bool equal(const QSequentialIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); }
inline QSequentialIterableImpl &advance(int i) {
Q_ASSERT(i > 0 || _iteratorCapabilities & BiDirectionalCapability);
@@ -1109,6 +1176,11 @@ public:
return *this;
}
+ inline void append(const void *newElement) {
+ if (containerCapabilities() & ContainerIsAppendable)
+ _append(_iterable, newElement);
+ }
+
inline VariantData getCurrent() const { return _get(&_iterator, _metaType_id, _metaType_flags); }
VariantData at(int idx) const
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index cf107498dd..e2e133ac28 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -1185,8 +1185,8 @@ QObjectPrivate::Connection::~Connection()
\relates QObject
Returns the given \a object cast to type T if the object is of type
- T (or of a subclass); otherwise returns 0. If \a object is 0 then
- it will also return 0.
+ T (or of a subclass); otherwise returns \nullptr. If \a object is
+ \nullptr then it will also return \nullptr.
The class T must inherit (directly or indirectly) QObject and be
declared with the \l Q_OBJECT macro.
@@ -1538,7 +1538,7 @@ QThread *QObject::thread() const
the thread affinity is changed. You can handle this event to
perform any special processing. Note that any new events that are
posted to this object will be handled in the \a targetThread,
- provided it is non-null: when it is \nullptr, no event processing
+ provided it is not \nullptr: when it is \nullptr, no event processing
for this object or its children can happen, as they are no longer
associated with any thread.
@@ -2335,7 +2335,7 @@ void QObject::deleteLater()
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
+ \a disambiguation (\nullptr by default). In Qt 4.4 and earlier, this was
the preferred way to pass comments to translators.
Example:
@@ -2521,7 +2521,7 @@ QObject *QObject::sender() const
For signals with default parameters, this function will always return
the index with all parameters, regardless of which was used with
- connect(). For example, the signal \c {destroyed(QObject *obj = 0)}
+ connect(). For example, the signal \c {destroyed(QObject *obj = \nullptr)}
will have two different indexes (with and without the parameter), but
this function will always return the index with a parameter. This does
not apply when overloading signals with different parameters.
@@ -2662,7 +2662,7 @@ bool QObject::isSignalConnected(const QMetaMethod &signal) const
member in the specified class.
\list
- \li If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
+ \li If member.mobj is \nullptr then both signalIndex and methodIndex are set to -1.
\li If specified member is not a member of obj instance class (or one of
its parent classes) then both signalIndex and methodIndex are set to -1.
@@ -2799,12 +2799,12 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
const QObject *receiver, const char *method,
Qt::ConnectionType type)
{
- if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {
+ if (sender == nullptr || receiver == nullptr || signal == nullptr || method == nullptr) {
qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
- sender ? sender->metaObject()->className() : "(null)",
- (signal && *signal) ? signal+1 : "(null)",
- receiver ? receiver->metaObject()->className() : "(null)",
- (method && *method) ? method+1 : "(null)");
+ sender ? sender->metaObject()->className() : "(nullptr)",
+ (signal && *signal) ? signal+1 : "(nullptr)",
+ receiver ? receiver->metaObject()->className() : "(nullptr)",
+ (method && *method) ? method+1 : "(nullptr)");
return QMetaObject::Connection(0);
}
QByteArray tmp_signal_name;
@@ -2937,14 +2937,14 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
const QObject *receiver, const QMetaMethod &method,
Qt::ConnectionType type)
{
- if (sender == 0
- || receiver == 0
+ if (sender == nullptr
+ || receiver == nullptr
|| signal.methodType() != QMetaMethod::Signal
|| method.methodType() == QMetaMethod::Constructor) {
qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
- sender ? sender->metaObject()->className() : "(null)",
+ sender ? sender->metaObject()->className() : "(nullptr)",
signal.methodSignature().constData(),
- receiver ? receiver->metaObject()->className() : "(null)",
+ receiver ? receiver->metaObject()->className() : "(nullptr)",
method.methodSignature().constData() );
return QMetaObject::Connection(0);
}
@@ -3046,20 +3046,20 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
\endlist
- 0 may be used as a wildcard, meaning "any signal", "any receiving
+ \nullptr may be used as a wildcard, meaning "any signal", "any receiving
object", or "any slot in the receiving object", respectively.
The \a sender may never be \nullptr. (You cannot disconnect signals
from more than one object in a single call.)
- If \a signal is 0, it disconnects \a receiver and \a method from
+ If \a signal is \nullptr, it disconnects \a receiver and \a method from
any signal. If not, only the specified signal is disconnected.
- If \a receiver is 0, it disconnects anything connected to \a
+ If \a receiver is \nullptr, it disconnects anything connected to \a
signal. If not, slots in objects other than \a receiver are not
disconnected.
- If \a method is 0, it disconnects anything that is connected to \a
+ If \a method is \nullptr, it disconnects anything that is connected to \a
receiver. If not, only slots named \a method will be disconnected,
and all other slots are left alone. The \a method must be \nullptr
if \a receiver is left out, so you cannot disconnect a
@@ -3070,8 +3070,8 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
bool QObject::disconnect(const QObject *sender, const char *signal,
const QObject *receiver, const char *method)
{
- if (sender == 0 || (receiver == 0 && method != 0)) {
- qWarning("QObject::disconnect: Unexpected null parameter");
+ if (sender == nullptr || (receiver == nullptr && method != nullptr)) {
+ qWarning("QObject::disconnect: Unexpected nullptr parameter");
return false;
}
@@ -3197,16 +3197,16 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
\endlist
QMetaMethod() may be used as wildcard in the meaning "any signal" or "any slot in receiving object".
- In the same way 0 can be used for \a receiver in the meaning "any receiving object". In this case
- method should also be QMetaMethod(). \a sender parameter should be never 0.
+ In the same way \nullptr can be used for \a receiver in the meaning "any receiving object".
+ In this case method should also be QMetaMethod(). \a sender parameter should be never \nullptr.
\sa disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
*/
bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
const QObject *receiver, const QMetaMethod &method)
{
- if (sender == 0 || (receiver == 0 && method.mobj != 0)) {
- qWarning("QObject::disconnect: Unexpected null parameter");
+ if (sender == nullptr || (receiver == nullptr && method.mobj != nullptr)) {
+ qWarning("QObject::disconnect: Unexpected nullptr parameter");
return false;
}
if (signal.mobj) {
@@ -3240,7 +3240,7 @@ bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
}
- // If we are here sender is not null. If signal is not null while signal_index
+ // If we are here sender is not nullptr. If signal is not nullptr while signal_index
// is -1 then this signal is not a member of sender.
if (signal.mobj && signal_index == -1) {
qWarning("QObject::disconect: signal %s not found on class %s",
@@ -3329,7 +3329,7 @@ void QObject::connectNotify(const QMetaMethod &signal)
\a signal with a specific signal.
If all signals were disconnected from this object (e.g., the
- signal argument to disconnect() was 0), disconnectNotify()
+ signal argument to disconnect() was \nullptr), disconnectNotify()
is only called once, and the \a signal will be an invalid
QMetaMethod (QMetaMethod::isValid() returns \c false).
@@ -4612,7 +4612,7 @@ QDebug operator<<(QDebug dbg, const QObject *o)
It works exactly like the Q_NAMESPACE macro. However, the external
\c{staticMetaObject} variable that gets defined in the namespace
- is declared with the supplied \c{EXPORT_MACRO} qualifier. This is
+ is declared with the supplied \a EXPORT_MACRO qualifier. This is
useful if the object needs to be exported from a dynamic library.
\sa Q_NAMESPACE, {Creating Shared Libraries}
@@ -4929,7 +4929,7 @@ void qDeleteInEventHandler(QObject *o)
\a sender is the sender object
\a signal is a pointer to a pointer to a member signal of the sender
- \a receiver is the receiver object, may not be null, will be equal to sender when
+ \a receiver is the receiver object, may not be \nullptr, will be equal to sender when
connecting to a static function or a functor
\a slot a pointer only used when using Qt::UniqueConnection
\a type the Qt::ConnctionType passed as argument to connect
@@ -4937,7 +4937,7 @@ void qDeleteInEventHandler(QObject *o)
to be used with queued connection
must stay valid at least for the whole time of the connection, this function
do not take ownership. typically static data.
- If null, then the types will be computed when the signal is emit in a queued
+ If \nullptr, then the types will be computed when the signal is emit in a queued
connection from the types from the signature.
\a senderMetaObject is the metaobject used to lookup the signal, the signal must be in
this metaobject
@@ -4948,7 +4948,7 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa
const int *types, const QMetaObject *senderMetaObject)
{
if (!signal) {
- qWarning("QObject::connect: invalid null parameter");
+ qWarning("QObject::connect: invalid nullptr parameter");
if (slotObj)
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
@@ -4988,7 +4988,7 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
: "Unknown";
const char *receiverString = receiver ? receiver->metaObject()->className()
: "Unknown";
- qWarning("QObject::connect(%s, %s): invalid null parameter", senderString, receiverString);
+ qWarning("QObject::connect(%s, %s): invalid nullptr parameter", senderString, receiverString);
if (slotObj)
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
@@ -5121,20 +5121,20 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
\endlist
- 0 may be used as a wildcard, meaning "any signal", "any receiving
+ \nullptr may be used as a wildcard, meaning "any signal", "any receiving
object", or "any slot in the receiving object", respectively.
The \a sender may never be \nullptr. (You cannot disconnect signals
from more than one object in a single call.)
- If \a signal is 0, it disconnects \a receiver and \a method from
+ If \a signal is \nullptr, it disconnects \a receiver and \a method from
any signal. If not, only the specified signal is disconnected.
- If \a receiver is 0, it disconnects anything connected to \a
+ If \a receiver is \nullptr, it disconnects anything connected to \a
signal. If not, slots in objects other than \a receiver are not
disconnected.
- If \a method is 0, it disconnects anything that is connected to \a
+ If \a method is \nullptr, it disconnects anything that is connected to \a
receiver. If not, only slots named \a method will be disconnected,
and all other slots are left alone. The \a method must be \nullptr
if \a receiver is left out, so you cannot disconnect a
@@ -5150,8 +5150,8 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
bool QObject::disconnectImpl(const QObject *sender, void **signal, const QObject *receiver, void **slot, const QMetaObject *senderMetaObject)
{
- if (sender == 0 || (receiver == 0 && slot != 0)) {
- qWarning("QObject::disconnect: Unexpected null parameter");
+ if (sender == nullptr || (receiver == nullptr && slot != nullptr)) {
+ qWarning("QObject::disconnect: Unexpected nullptr parameter");
return false;
}
@@ -5182,7 +5182,7 @@ bool QObject::disconnectImpl(const QObject *sender, void **signal, const QObject
QMetaObject::Connection QObjectPrivate::connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type)
{
if (!sender) {
- qWarning("QObject::connect: invalid null parameter");
+ qWarning("QObject::connect: invalid nullptr parameter");
if (slotObj)
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 540b8b32c1..f5d7c22e3a 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -55,7 +55,7 @@
#include <QtCore/qobject_impl.h>
-#if QT_HAS_INCLUDE(<chrono>)
+#if __has_include(<chrono>)
# include <chrono>
#endif
@@ -160,7 +160,7 @@ public:
void moveToThread(QThread *thread);
int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);
-#if QT_HAS_INCLUDE(<chrono>)
+#if __has_include(<chrono>)
Q_ALWAYS_INLINE
int startTimer(std::chrono::milliseconds time, Qt::TimerType timerType = Qt::CoarseTimer)
{
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index dc2d832fe5..becbb90a61 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -532,7 +532,7 @@ struct Q_CORE_EXPORT QMetaObject
static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
&& QtPrivate::FunctionPointer<Func>::ArgumentCount == -1
&& !std::is_convertible<Func, const char*>::value, bool>::type
- invokeMethod(QObject *context, Func function, typename std::result_of<Func()>::type *ret)
+ invokeMethod(QObject *context, Func function, decltype(function()) *ret)
{
return invokeMethodImpl(context,
new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index 31ecc8b20d..aed50d6c5a 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -285,11 +285,15 @@ namespace QtPrivate {
{
};
+ template <typename T>
+ using is_bool = std::is_same<bool, typename std::decay<T>::type>;
+
template<typename From, typename To>
struct AreArgumentsNarrowedBase<From, To, typename std::enable_if<sizeof(From) && sizeof(To)>::type>
: std::integral_constant<bool,
(std::is_floating_point<From>::value && std::is_integral<To>::value) ||
(std::is_floating_point<From>::value && std::is_floating_point<To>::value && sizeof(From) > sizeof(To)) ||
+ ((std::is_pointer<From>::value || std::is_member_pointer<From>::value) && QtPrivate::is_bool<To>::value) ||
((std::is_integral<From>::value || std::is_enum<From>::value) && std::is_floating_point<To>::value) ||
(std::is_integral<From>::value && std::is_integral<To>::value
&& (sizeof(From) > sizeof(To)
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index 948f697dc5..4d8778ecf5 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -84,10 +84,10 @@ QT_BEGIN_NAMESPACE
must start and stop the timer in its thread; it is not possible to
start a timer from another thread.
- As a special case, a QTimer with a timeout of 0 will time out as
- soon as all the events in the window system's event queue have
- been processed. This can be used to do heavy work while providing
- a snappy user interface:
+ As a special case, a QTimer with a timeout of 0 will time out as soon as
+ possible, though the ordering between zero timers and other sources of
+ events is unspecified. Zero timers can be used to do some work while still
+ providing a snappy user interface:
\snippet timers/timers.cpp 4
\snippet timers/timers.cpp 5
diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h
index eb7185c12d..6bbfd741d9 100644
--- a/src/corelib/kernel/qtimer.h
+++ b/src/corelib/kernel/qtimer.h
@@ -47,7 +47,7 @@
#include <QtCore/qbasictimer.h> // conceptual inheritance
#include <QtCore/qobject.h>
-#if QT_HAS_INCLUDE(<chrono>)
+#if __has_include(<chrono>)
# include <chrono>
#endif
@@ -177,7 +177,7 @@ Q_SIGNALS:
void timeout(QPrivateSignal);
public:
-#if QT_HAS_INCLUDE(<chrono>) || defined(Q_QDOC)
+#if __has_include(<chrono>) || defined(Q_QDOC)
void setInterval(std::chrono::milliseconds value)
{
setInterval(int(value.count()));
@@ -223,7 +223,7 @@ private:
static void singleShotImpl(int msec, Qt::TimerType timerType,
const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj);
-#if QT_HAS_INCLUDE(<chrono>)
+#if __has_include(<chrono>)
static Qt::TimerType defaultTypeFor(std::chrono::milliseconds interval)
{ return defaultTypeFor(int(interval.count())); }
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 43a3fb1db0..a1e1c71d12 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -2577,8 +2577,8 @@ void QVariant::save(QDataStream &s) const
} else if (typeId >= QMetaType::QKeySequence && typeId <= QMetaType::QQuaternion) {
// and as a result these types received lower ids too
typeId +=1;
- } else if (typeId == QMetaType::QPolygonF) {
- // This existed in Qt 4 only as a custom type
+ } else if (typeId == QMetaType::QPolygonF || typeId == QMetaType::QUuid) {
+ // These existed in Qt 4 only as a custom type
typeId = 127;
fakeUserType = true;
}
@@ -4520,15 +4520,24 @@ QSequentialIterable::const_iterator QSequentialIterable::end() const
return it;
}
+static const QVariant variantFromVariantDataHelper(const QtMetaTypePrivate::VariantData &d) {
+ QVariant v;
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ v = *reinterpret_cast<const QVariant*>(d.data);
+ else
+ v = QVariant(d.metaTypeId, d.data, d.flags & ~QVariantConstructionFlags::ShouldDeleteVariantData);
+ if (d.flags & QVariantConstructionFlags::ShouldDeleteVariantData)
+ QMetaType::destroy(d.metaTypeId, const_cast<void *>(d.data));
+ return v;
+}
+
/*!
Returns the element at position \a idx in the container.
*/
QVariant QSequentialIterable::at(int idx) const
{
const QtMetaTypePrivate::VariantData d = m_impl.at(idx);
- if (d.metaTypeId == qMetaTypeId<QVariant>())
- return *reinterpret_cast<const QVariant*>(d.data);
- return QVariant(d.metaTypeId, d.data, d.flags);
+ return variantFromVariantDataHelper(d);
}
/*!
@@ -4605,9 +4614,7 @@ QSequentialIterable::const_iterator::operator=(const const_iterator &other)
const QVariant QSequentialIterable::const_iterator::operator*() const
{
const QtMetaTypePrivate::VariantData d = m_impl.getCurrent();
- if (d.metaTypeId == qMetaTypeId<QVariant>())
- return *reinterpret_cast<const QVariant*>(d.data);
- return QVariant(d.metaTypeId, d.data, d.flags);
+ return variantFromVariantDataHelper(d);
}
/*!
@@ -4939,10 +4946,7 @@ QAssociativeIterable::const_iterator::operator=(const const_iterator &other)
const QVariant QAssociativeIterable::const_iterator::operator*() const
{
const QtMetaTypePrivate::VariantData d = m_impl.getCurrentValue();
- QVariant v(d.metaTypeId, d.data, d.flags);
- if (d.metaTypeId == qMetaTypeId<QVariant>())
- return *reinterpret_cast<const QVariant*>(d.data);
- return v;
+ return variantFromVariantDataHelper(d);
}
/*!
@@ -4951,10 +4955,7 @@ const QVariant QAssociativeIterable::const_iterator::operator*() const
const QVariant QAssociativeIterable::const_iterator::key() const
{
const QtMetaTypePrivate::VariantData d = m_impl.getCurrentKey();
- QVariant v(d.metaTypeId, d.data, d.flags);
- if (d.metaTypeId == qMetaTypeId<QVariant>())
- return *reinterpret_cast<const QVariant*>(d.data);
- return v;
+ return variantFromVariantDataHelper(d);
}
/*!
@@ -4962,11 +4963,7 @@ const QVariant QAssociativeIterable::const_iterator::key() const
*/
const QVariant QAssociativeIterable::const_iterator::value() const
{
- const QtMetaTypePrivate::VariantData d = m_impl.getCurrentValue();
- QVariant v(d.metaTypeId, d.data, d.flags);
- if (d.metaTypeId == qMetaTypeId<QVariant>())
- return *reinterpret_cast<const QVariant*>(d.data);
- return v;
+ return operator*();
}
/*!
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index e7d3d9c835..c95882d48f 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -53,7 +53,7 @@
#include <QtCore/qbytearraylist.h>
#endif
-#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
+#if __has_include(<variant>) && __cplusplus >= 201703L
#include <variant>
#elif defined(Q_CLANG_QDOC)
namespace std { template<typename...> struct variant; }
@@ -370,7 +370,7 @@ class Q_CORE_EXPORT QVariant
static inline QVariant fromValue(const T &value)
{ return QVariant(qMetaTypeId<T>(), &value, QTypeInfo<T>::isPointer); }
-#if (QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L) || defined(Q_CLANG_QDOC)
+#if (__has_include(<variant>) && __cplusplus >= 201703L) || defined(Q_CLANG_QDOC)
template<typename... Types>
static inline QVariant fromStdVariant(const std::variant<Types...> &value)
{
@@ -544,7 +544,7 @@ inline QVariant QVariant::fromValue(const QVariant &value)
return value;
}
-#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
+#if __has_include(<variant>) && __cplusplus >= 201703L
template<>
inline QVariant QVariant::fromValue(const std::monostate &)
{
@@ -801,7 +801,8 @@ namespace QtPrivate {
static QVariantList invoke(const QVariant &v)
{
const int typeId = v.userType();
- if (typeId == qMetaTypeId<QStringList>() || typeId == qMetaTypeId<QByteArrayList>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) {
+ if (typeId == qMetaTypeId<QStringList>() || typeId == qMetaTypeId<QByteArrayList>() ||
+ (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>()) && !QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QVariantList>()))) {
QSequentialIterable iter = QVariantValueHelperInterface<QSequentialIterable>::invoke(v);
QVariantList l;
l.reserve(iter.size());
@@ -818,7 +819,7 @@ namespace QtPrivate {
static QVariantHash invoke(const QVariant &v)
{
const int typeId = v.userType();
- if (typeId == qMetaTypeId<QVariantMap>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ if (typeId == qMetaTypeId<QVariantMap>() || ((QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) && !QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QVariantHash>()))) {
QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
QVariantHash l;
l.reserve(iter.size());
@@ -835,7 +836,7 @@ namespace QtPrivate {
static QVariantMap invoke(const QVariant &v)
{
const int typeId = v.userType();
- if (typeId == qMetaTypeId<QVariantHash>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ if (typeId == qMetaTypeId<QVariantHash>() || (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>()) && !QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QVariantMap>()))) {
QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
QVariantMap l;
for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
@@ -851,10 +852,8 @@ namespace QtPrivate {
static QPair<QVariant, QVariant> invoke(const QVariant &v)
{
const int typeId = v.userType();
- if (typeId == qMetaTypeId<QPair<QVariant, QVariant> >())
- return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
- if (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
+ if (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>()) && !(typeId == qMetaTypeId<QPair<QVariant, QVariant> >())) {
QtMetaTypePrivate::QPairVariantInterfaceImpl pi = v.value<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
const QtMetaTypePrivate::VariantData d1 = pi.first();
diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h
index 3d87beac83..b8b63b5e6f 100644
--- a/src/corelib/kernel/qvariant_p.h
+++ b/src/corelib/kernel/qvariant_p.h
@@ -105,6 +105,11 @@ inline T *v_cast(QVariant::Private *d, T * = nullptr)
#endif
+enum QVariantConstructionFlags : uint {
+ Default = 0x0,
+ PointerType = 0x1,
+ ShouldDeleteVariantData = 0x2 // only used in Q*Iterable
+};
//a simple template that avoids to allocate 2 memory chunks when creating a QVariant
template <class T> class QVariantPrivateSharedEx : public QVariant::PrivateShared