summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/global/qcompilerdetection.h2
-rw-r--r--src/corelib/global/qnamespace.h43
-rw-r--r--src/corelib/io/qdir.cpp4
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp2
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.mm2
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp13
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm15
-rw-r--r--src/corelib/kernel/qcore_mac_p.h130
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp2
-rw-r--r--src/corelib/kernel/qdeadlinetimer.cpp1
-rw-r--r--src/corelib/kernel/qdeadlinetimer.h5
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf.mm53
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp22
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt_p.h1
-rw-r--r--src/corelib/kernel/qmetatype.cpp2
-rw-r--r--src/corelib/kernel/qobject.cpp7
-rw-r--r--src/corelib/kernel/qtimer.cpp42
-rw-r--r--src/corelib/kernel/qtimer.h13
-rw-r--r--src/corelib/kernel/qvariant.cpp13
-rw-r--r--src/corelib/kernel/qvariant.h2
-rw-r--r--src/corelib/kernel/qwineventnotifier.cpp7
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp31
-rw-r--r--src/corelib/plugin/qplugin.h12
-rw-r--r--src/corelib/serialization/qdatastream.cpp1
-rw-r--r--src/corelib/serialization/qdatastream.h5
-rw-r--r--src/corelib/thread/qfuture.h1
-rw-r--r--src/corelib/thread/qmutex_p.h3
-rw-r--r--src/corelib/thread/qmutex_unix.cpp2
-rw-r--r--src/corelib/thread/qsemaphore.cpp6
-rw-r--r--src/corelib/thread/qwaitcondition.h4
-rw-r--r--src/corelib/thread/qwaitcondition_unix.cpp53
-rw-r--r--src/corelib/thread/qwaitcondition_win.cpp11
-rw-r--r--src/corelib/tools/qarraydata.h2
-rw-r--r--src/corelib/tools/qbytearray.cpp78
-rw-r--r--src/corelib/tools/qbytearray.h3
-rw-r--r--src/corelib/tools/qcryptographichash.cpp40
-rw-r--r--src/corelib/tools/qcryptographichash.h1
-rw-r--r--src/corelib/tools/qhash.h2
-rw-r--r--src/corelib/tools/qlinkedlist.h2
-rw-r--r--src/corelib/tools/qlist.h2
-rw-r--r--src/corelib/tools/qlocale.cpp31
-rw-r--r--src/corelib/tools/qmap.h2
-rw-r--r--src/corelib/tools/qregexp.cpp20
-rw-r--r--src/corelib/tools/qregularexpression.cpp118
-rw-r--r--src/corelib/tools/qregularexpression.h1
-rw-r--r--src/corelib/tools/qregularexpression_p.h70
-rw-r--r--src/corelib/tools/qringbuffer.cpp8
-rw-r--r--src/corelib/tools/qset.h2
-rw-r--r--src/corelib/tools/qshareddata.h24
-rw-r--r--src/corelib/tools/qstring.cpp44
-rw-r--r--src/corelib/tools/qstring.h3
-rw-r--r--src/corelib/tools/qtimezone.cpp14
-rw-r--r--src/corelib/tools/qtimezoneprivate.cpp18
-rw-r--r--src/corelib/tools/qtimezoneprivate_p.h3
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp5
-rw-r--r--src/corelib/tools/qtimezoneprivate_win.cpp1
-rw-r--r--src/corelib/tools/tools.pri18
57 files changed, 880 insertions, 142 deletions
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index f3f3139d1a..e5e47082d8 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -898,7 +898,7 @@
/* C11 features supported in GCC 4.7: */
# define Q_COMPILER_STATIC_ASSERT
# endif
-# if Q_CC_GNU >= 409
+# if Q_CC_GNU >= 409 && defined(__has_include)
/* C11 features supported in GCC 4.9: */
# if __has_include(<threads.h>)
# define Q_COMPILER_THREAD_LOCAL
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 31b1823690..982eb75650 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -107,6 +107,7 @@ public:
KeyboardModifierMask = 0xfe000000
};
Q_DECLARE_FLAGS(KeyboardModifiers, KeyboardModifier)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardModifiers)
//shorter names for shortcuts
// The use of all-caps identifiers has the potential for clashing with
@@ -163,6 +164,7 @@ public:
MouseButtonMask = 0xffffffff
};
Q_DECLARE_FLAGS(MouseButtons, MouseButton)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(MouseButtons)
enum Orientation {
Horizontal = 0x1,
@@ -170,6 +172,7 @@ public:
};
Q_DECLARE_FLAGS(Orientations, Orientation)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(Orientations)
enum FocusPolicy {
NoFocus = 0,
@@ -225,6 +228,7 @@ public:
};
Q_DECLARE_FLAGS(Alignment, AlignmentFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(Alignment)
enum TextFlag {
TextSingleLine = 0x0100,
@@ -308,6 +312,7 @@ public:
};
Q_DECLARE_FLAGS(WindowFlags, WindowType)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(WindowFlags)
enum WindowState {
WindowNoState = 0x00000000,
@@ -318,6 +323,7 @@ public:
};
Q_DECLARE_FLAGS(WindowStates, WindowState)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(WindowStates)
enum ApplicationState {
ApplicationSuspended = 0x00000000,
@@ -337,6 +343,7 @@ public:
};
Q_DECLARE_FLAGS(ScreenOrientations, ScreenOrientation)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(ScreenOrientations)
enum WidgetAttribute {
WA_Disabled = 0,
@@ -553,6 +560,7 @@ public:
NoFormatConversion = 0x00000200
};
Q_DECLARE_FLAGS(ImageConversionFlags, ImageConversionFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(ImageConversionFlags)
enum BGMode {
TransparentMode,
@@ -1210,6 +1218,7 @@ public:
};
Q_DECLARE_FLAGS(DockWidgetAreas, DockWidgetArea)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(DockWidgetAreas)
enum ToolBarArea {
LeftToolBarArea = 0x1,
@@ -1227,6 +1236,7 @@ public:
};
Q_DECLARE_FLAGS(ToolBarAreas, ToolBarArea)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(ToolBarAreas)
enum DateFormat {
TextDate, // default Qt
@@ -1285,6 +1295,7 @@ public:
};
Q_DECLARE_FLAGS(Edges, Edge)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(Edges)
enum ConnectionType {
AutoConnection,
@@ -1387,6 +1398,7 @@ public:
ImQueryAll = 0xffffffff
};
Q_DECLARE_FLAGS(InputMethodQueries, InputMethodQuery)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(InputMethodQueries)
enum InputMethodHint {
ImhNone = 0x0,
@@ -1421,6 +1433,7 @@ public:
ImhExclusiveInputMask = 0xffff0000
};
Q_DECLARE_FLAGS(InputMethodHints, InputMethodHint)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(InputMethodHints)
enum EnterKeyType {
EnterKeyDefault,
@@ -1471,6 +1484,7 @@ public:
IgnoreAction = 0x0
};
Q_DECLARE_FLAGS(DropActions, DropAction)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(DropActions)
enum CheckState {
Unchecked,
@@ -1525,6 +1539,7 @@ public:
ItemIsUserTristate = 256
};
Q_DECLARE_FLAGS(ItemFlags, ItemFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(ItemFlags)
enum MatchFlag {
MatchExactly = 0,
@@ -1539,6 +1554,7 @@ public:
MatchRecursive = 64
};
Q_DECLARE_FLAGS(MatchFlags, MatchFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(MatchFlags)
typedef void * HANDLE;
#if QT_DEPRECATED_SINCE(5, 0)
@@ -1563,6 +1579,7 @@ public:
TextBrowserInteraction = TextSelectableByMouse | LinksAccessibleByMouse | LinksAccessibleByKeyboard
};
Q_DECLARE_FLAGS(TextInteractionFlags, TextInteractionFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(TextInteractionFlags)
enum EventPriority {
HighEventPriority = 1,
@@ -1614,6 +1631,7 @@ public:
TouchPointReleased = 0x08
};
Q_DECLARE_FLAGS(TouchPointStates, TouchPointState)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(TouchPointStates)
#ifndef QT_NO_GESTURES
enum GestureState
@@ -1645,6 +1663,7 @@ public:
IgnoredGesturesPropagateToParent = 0x04
};
Q_DECLARE_FLAGS(GestureFlags, GestureFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(GestureFlags)
enum NativeGestureType
{
@@ -1698,6 +1717,7 @@ public:
MouseEventFlagMask = 0xFF
};
Q_DECLARE_FLAGS(MouseEventFlags, MouseEventFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(MouseEventFlags)
enum ChecksumType {
ChecksumIso3309,
@@ -1800,29 +1820,6 @@ public:
#undef QT_Q_ENUM
#undef QT_Q_FLAG
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MouseButtons)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Orientations)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::KeyboardModifiers)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::WindowFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Alignment)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Edges)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ImageConversionFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::DockWidgetAreas)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ToolBarAreas)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::WindowStates)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ScreenOrientations)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::DropActions)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ItemFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MatchFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TextInteractionFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodQueries)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodHints)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TouchPointStates)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MouseEventFlags)
-#ifndef QT_NO_GESTURES
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::GestureFlags)
-#endif
-
typedef bool (*qInternalCallback)(void **);
class Q_CORE_EXPORT QInternal {
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index e4d384e4ca..06eacf5455 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -2035,7 +2035,7 @@ QString QDir::homePath()
Returns the system's temporary directory.
- The directory is constructed using the absolute path of the temporary directory,
+ The directory is constructed using the absolute canonical path of the temporary directory,
ensuring that its path() will be the same as its absolutePath().
See tempPath() for details.
@@ -2044,7 +2044,7 @@ QString QDir::homePath()
*/
/*!
- Returns the absolute path of the system's temporary directory.
+ Returns the absolute canonical path of the system's temporary directory.
On Unix/Linux systems this is the path in the \c TMPDIR environment
variable or \c{/tmp} if \c TMPDIR is not defined. On Windows this is
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index b8cf42a2e9..5cc3a5937e 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -1532,7 +1532,7 @@ QString QFileSystemEngine::tempPath()
temp = QLatin1String(_PATH_TMP);
}
}
- return QDir::cleanPath(temp);
+ return QDir(QDir::cleanPath(temp)).canonicalPath();
#endif
}
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm
index 792ea387ac..844aa9daa7 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.mm
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm
@@ -499,7 +499,7 @@ bool QFseventsFileSystemWatcherEngine::startStream()
DEBUG() << "Starting stream with paths" << watchingState.watchedPaths.keys();
- NSMutableArray *pathsToWatch = [NSMutableArray arrayWithCapacity:watchingState.watchedPaths.size()];
+ NSMutableArray<NSString *> *pathsToWatch = [NSMutableArray<NSString *> arrayWithCapacity:watchingState.watchedPaths.size()];
for (PathRefCounts::const_iterator i = watchingState.watchedPaths.begin(), ei = watchingState.watchedPaths.end(); i != ei; ++i)
[pathsToWatch addObject:i.key().toNSString()];
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index 78093727b8..0025c60c3b 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -574,6 +574,19 @@ QVector<QPair<int, int > > QSortFilterProxyModelPrivate::proxy_intervals_for_sou
proxy_intervals.append(QPair<int, int>(first_proxy_item, last_proxy_item));
}
std::stable_sort(proxy_intervals.begin(), proxy_intervals.end());
+ // Consolidate adjacent intervals
+ for (int i = proxy_intervals.size()-1; i > 0; --i) {
+ QPair<int, int> &interval = proxy_intervals[i];
+ QPair<int, int> &preceeding_interval = proxy_intervals[i - 1];
+ if (interval.first == preceeding_interval.second + 1) {
+ preceeding_interval.second = interval.second;
+ interval.first = interval.second = -1;
+ }
+ }
+ proxy_intervals.erase(
+ std::remove_if(proxy_intervals.begin(), proxy_intervals.end(),
+ [](QPair<int, int> &interval) { return interval.first < 0; }),
+ proxy_intervals.end());
return proxy_intervals;
}
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index 5ecd86a30e..c1062e98b8 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -87,19 +87,20 @@ QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_DECLARE_WEAK_QDEBUG_OPERATOR_FOR_CF_TY
QT_END_NAMESPACE
QT_USE_NAMESPACE
@interface QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) : NSObject
-{
+@end
+
+@implementation QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) {
NSAutoreleasePool **m_pool;
}
--(id)initWithPool:(NSAutoreleasePool**)pool;
-@end
-@implementation QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker)
--(id)initWithPool:(NSAutoreleasePool**)pool
+
+- (instancetype)initWithPool:(NSAutoreleasePool **)pool
{
- if (self = [super init])
+ if ((self = [self init]))
m_pool = pool;
return self;
}
--(void)dealloc
+
+- (void)dealloc
{
if (*m_pool) {
// The pool is still valid, which means we're not being drained from
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index 9c6cef68b2..e8aa24b944 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -51,18 +51,50 @@
// We mean it.
//
+#include "private/qglobal_p.h"
+
#ifndef __IMAGECAPTURE__
# define __IMAGECAPTURE__
#endif
+// --------------------------------------------------------------------------
+
+#if !defined(QT_BOOTSTRAPPED) && (QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_12) || !defined(Q_OS_MACOS))
+#define QT_USE_APPLE_ACTIVITIES
+
+#if defined(OS_ACTIVITY_OBJECT_API)
+#error The file <os/activity.h> has already been included
+#endif
+
+// We runtime-check all use of the activity APIs, so we can safely build
+// with them included, even if the deployment target is macOS 10.11
+#if QT_MACOS_DEPLOYMENT_TARGET_BELOW(__MAC_10_12)
+#undef __MAC_OS_X_VERSION_MIN_REQUIRED
+#define __MAC_OS_X_VERSION_MIN_REQUIRED __MAC_10_12
+#define DID_OVERRIDE_DEPLOYMENT_TARGET
+#endif
+
+#include <os/activity.h>
+#if !OS_ACTIVITY_OBJECT_API
+#error "Expected activity API to be available"
+#endif
+
+#if defined(DID_OVERRIDE_DEPLOYMENT_TARGET)
+#undef __MAC_OS_X_VERSION_MIN_REQUIRED
+#define __MAC_OS_X_VERSION_MIN_REQUIRED __MAC_10_11
+#undef DID_OVERRIDE_DEPLOYMENT_TARGET
+#endif
+
+#endif
+
+// --------------------------------------------------------------------------
+
#if defined(QT_BOOTSTRAPPED)
#include <ApplicationServices/ApplicationServices.h>
#else
#include <CoreFoundation/CoreFoundation.h>
#endif
-#include "private/qglobal_p.h"
-
#ifdef __OBJC__
#include <Foundation/Foundation.h>
#endif
@@ -190,6 +222,100 @@ private:
// --------------------------------------------------------------------------
+#if defined(QT_USE_APPLE_ACTIVITIES)
+
+QT_END_NAMESPACE
+#include <os/availability.h>
+#define OS_ACTIVITY_AVAILABILITY API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
+#define OS_ACTIVITY_AVAILABILITY_CHECK __builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *)
+QT_BEGIN_NAMESPACE
+
+template <typename T> using QAppleOsType = QAppleRefCounted<T, void *, os_retain, os_release>;
+
+class Q_CORE_EXPORT QAppleLogActivity
+{
+public:
+ QAppleLogActivity() : activity(nullptr) {}
+ QAppleLogActivity(os_activity_t activity) OS_ACTIVITY_AVAILABILITY : activity(activity) {}
+ ~QAppleLogActivity() { if (activity) leave(); }
+
+ QAppleLogActivity(const QAppleLogActivity &) = delete;
+ QAppleLogActivity& operator=(const QAppleLogActivity &) = delete;
+
+ QAppleLogActivity(QAppleLogActivity&& other)
+ : activity(other.activity), state(other.state) { other.activity = nullptr; }
+
+ QAppleLogActivity& operator=(QAppleLogActivity &&other)
+ {
+ if (this != &other) {
+ activity = other.activity;
+ state = other.state;
+ other.activity = nullptr;
+ }
+ return *this;
+ }
+
+ QAppleLogActivity&& enter()
+ {
+ if (activity) {
+ if (OS_ACTIVITY_AVAILABILITY_CHECK)
+ os_activity_scope_enter(static_cast<os_activity_t>(*this), &state);
+ }
+ return std::move(*this);
+ }
+
+ void leave() {
+ if (activity) {
+ if (OS_ACTIVITY_AVAILABILITY_CHECK)
+ os_activity_scope_leave(&state);
+ }
+ }
+
+ operator os_activity_t() OS_ACTIVITY_AVAILABILITY
+ {
+ return reinterpret_cast<os_activity_t>(static_cast<void *>(activity));
+ }
+
+private:
+ // Work around API_AVAILABLE not working for templates by using void*
+ QAppleOsType<void *> activity;
+ os_activity_scope_state_s state;
+};
+
+#define QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent) []() { \
+ if (!(condition)) \
+ return QAppleLogActivity(); \
+ if (OS_ACTIVITY_AVAILABILITY_CHECK) \
+ return QAppleLogActivity(os_activity_create(description, parent, OS_ACTIVITY_FLAG_DEFAULT)); \
+ return QAppleLogActivity(); \
+ }()
+
+#define QT_VA_ARGS_CHOOSE(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
+#define QT_VA_ARGS_COUNT(...) QT_VA_ARGS_CHOOSE(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1)
+
+#define QT_OVERLOADED_MACRO(MACRO, ...) _QT_OVERLOADED_MACRO(MACRO, QT_VA_ARGS_COUNT(__VA_ARGS__))(__VA_ARGS__)
+#define _QT_OVERLOADED_MACRO(MACRO, ARGC) _QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC)
+#define _QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC) MACRO##ARGC
+
+#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT3(condition, description, parent) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent)
+#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT2(description, parent) QT_APPLE_LOG_ACTIVITY_WITH_PARENT3(true, description, parent)
+#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY_WITH_PARENT, __VA_ARGS__)
+
+#define QT_APPLE_LOG_ACTIVITY2(condition, description) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, OS_ACTIVITY_CURRENT)
+#define QT_APPLE_LOG_ACTIVITY1(description) QT_APPLE_LOG_ACTIVITY2(true, description)
+#define QT_APPLE_LOG_ACTIVITY(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY, __VA_ARGS__)
+
+#define QT_APPLE_SCOPED_LOG_ACTIVITY(...) QAppleLogActivity scopedLogActivity = QT_APPLE_LOG_ACTIVITY(__VA_ARGS__).enter();
+
+#else
+// No-ops for macOS 10.11. We don't need to provide QT_APPLE_SCOPED_LOG_ACTIVITY,
+// as all the call sites for that are in code that's only built on 10.12 and above.
+#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT(...)
+#define QT_APPLE_LOG_ACTIVITY(...)
+#endif // QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE
+
+// -------------------------------------------------------------------------
+
QT_END_NAMESPACE
#endif // QCORE_MAC_P_H
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 4e32f90964..e0ae350f32 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -1889,7 +1889,7 @@ bool QCoreApplication::event(QEvent *e)
\value UnicodeUTF8 UTF-8.
\omitvalue Latin1
- \omitvalue DefaultCodec UTF-8.
+ \omitvalue DefaultCodec \omit UTF-8. \endomit
\omitvalue CodecForTr
\sa QObject::tr(), QString::fromUtf8()
diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp
index d8a670310b..97b98a1376 100644
--- a/src/corelib/kernel/qdeadlinetimer.cpp
+++ b/src/corelib/kernel/qdeadlinetimer.cpp
@@ -39,7 +39,6 @@
#include "qdeadlinetimer.h"
#include "qdeadlinetimer_p.h"
-#include <qpair.h>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/kernel/qdeadlinetimer.h b/src/corelib/kernel/qdeadlinetimer.h
index 6c10e1025e..1a4ee04a96 100644
--- a/src/corelib/kernel/qdeadlinetimer.h
+++ b/src/corelib/kernel/qdeadlinetimer.h
@@ -43,6 +43,7 @@
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qmetatype.h>
#include <QtCore/qnamespace.h>
+#include <QtCore/qpair.h>
#ifdef max
// un-pollute the namespace. We need std::numeric_limits::max() and std::chrono::duration::max()
@@ -186,6 +187,10 @@ private:
unsigned type;
qint64 rawRemainingTimeNSecs() const Q_DECL_NOTHROW;
+
+public:
+ // This is not a public function, it's here only for Qt's internal convenience...
+ QPair<qint64, unsigned> _q_data() const { return qMakePair(t1, t2); }
};
Q_DECLARE_SHARED(QDeadlineTimer)
diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm
index 8499b3fd57..a6c5ccd7a8 100644
--- a/src/corelib/kernel/qeventdispatcher_cf.mm
+++ b/src/corelib/kernel/qeventdispatcher_cf.mm
@@ -58,18 +58,36 @@
QT_USE_NAMESPACE
-@interface QT_MANGLE_NAMESPACE(RunLoopModeTracker) : NSObject {
- QStack<CFStringRef> m_runLoopModes;
-}
+/*!
+ During scroll view panning, and possibly other gestures, UIKit will
+ request a switch to UITrackingRunLoopMode via GSEventPushRunLoopMode,
+ which records the new runloop mode and stops the current runloop.
+
+ Unfortunately the runloop mode is just stored on an internal stack, used
+ when UIKit itself is running the runloop, and is not available through e.g.
+ CFRunLoopCopyCurrentMode, which only knows about the current running
+ runloop mode, not the requested future runloop mode.
+
+ To ensure that we pick up this new runloop mode and use it when calling
+ CFRunLoopRunInMode from processEvents, we listen for the notification
+ emitted by [UIApplication pushRunLoopMode:requester:].
+
+ Without this workaround we end up always running in the default runloop
+ mode, resulting in missing momentum-phases in UIScrollViews such as the
+ emoji keyboard.
+*/
+@interface QT_MANGLE_NAMESPACE(RunLoopModeTracker) : NSObject
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(RunLoopModeTracker);
-@implementation RunLoopModeTracker
+@implementation RunLoopModeTracker {
+ QStack<CFStringRef> m_runLoopModes;
+}
-- (id) init
+- (instancetype)init
{
- if (self = [super init]) {
+ if ((self = [super init])) {
m_runLoopModes.push(kCFRunLoopDefaultMode);
[[NSNotificationCenter defaultCenter]
@@ -77,21 +95,21 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(RunLoopModeTracker);
selector:@selector(receivedNotification:)
name:nil
#ifdef Q_OS_OSX
- object:[NSApplication sharedApplication]];
+ object:NSApplication.sharedApplication];
#elif defined(Q_OS_WATCHOS)
- object:[WKExtension sharedExtension]];
+ object:WKExtension.sharedExtension];
#else
// Use performSelector so this can work in an App Extension
- object:[[UIApplication class] performSelector:@selector(sharedApplication)]];
+ object:[UIApplication.class performSelector:@selector(sharedApplication)]];
#endif
}
return self;
}
-- (void) dealloc
+- (void)dealloc
{
- [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [NSNotificationCenter.defaultCenter removeObserver:self];
[super dealloc];
}
@@ -100,13 +118,13 @@ static CFStringRef runLoopMode(NSDictionary *dictionary)
{
for (NSString *key in dictionary) {
if (CFStringHasSuffix((CFStringRef)key, CFSTR("RunLoopMode")))
- return (CFStringRef)[dictionary objectForKey: key];
+ return (CFStringRef)dictionary[key];
}
return nil;
}
-- (void) receivedNotification:(NSNotification *) notification
+- (void)receivedNotification:(NSNotification *)notification
{
if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePushNotification"))) {
if (CFStringRef mode = runLoopMode(notification.userInfo))
@@ -116,7 +134,7 @@ static CFStringRef runLoopMode(NSDictionary *dictionary)
} else if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePopNotification"))) {
CFStringRef mode = runLoopMode(notification.userInfo);
- if (CFStringCompare(mode, [self currentMode], 0) == kCFCompareEqualTo)
+ if (CFStringCompare(mode, self.currentMode, 0) == kCFCompareEqualTo)
m_runLoopModes.pop();
else
qCWarning(lcEventDispatcher) << "Tried to pop run loop mode"
@@ -126,7 +144,7 @@ static CFStringRef runLoopMode(NSDictionary *dictionary)
}
}
-- (CFStringRef) currentMode
+- (CFStringRef)currentMode
{
return m_runLoopModes.top();
}
@@ -238,6 +256,7 @@ QEventLoop *QEventDispatcherCoreFoundation::currentEventLoop() const
*/
bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlags flags)
{
+ QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processEvents");
bool eventsProcessed = false;
if (flags & (QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers))
@@ -390,6 +409,8 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
bool QEventDispatcherCoreFoundation::processPostedEvents()
{
+ QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processPostedEvents");
+
if (m_processEvents.processedPostedEvents && !(m_processEvents.flags & QEventLoop::EventLoopExec)) {
qCDebug(lcEventDispatcher) << "Already processed events this pass";
return false;
@@ -405,6 +426,8 @@ bool QEventDispatcherCoreFoundation::processPostedEvents()
void QEventDispatcherCoreFoundation::processTimers(CFRunLoopTimerRef timer)
{
+ QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processTimers");
+
if (m_processEvents.processedTimers && !(m_processEvents.flags & QEventLoop::EventLoopExec)) {
qCDebug(lcEventDispatcher) << "Already processed timers this pass";
m_processEvents.deferredUpdateTimers = true;
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
index 33753ed507..600c6c38fd 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt.cpp
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -43,6 +43,8 @@
#include <QtCore/QThread>
#include <QtCore/QHash>
#include <QtCore/QMutex>
+#include <QtCore/QSemaphore>
+#include <QtCore/QSharedPointer>
#include <QtCore/qfunctions_winrt.h>
#include <private/qabstracteventdispatcher_p.h>
#include <private/qcoreapplication_p.h>
@@ -293,6 +295,26 @@ HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function<HRESULT ()> &
return QWinRTFunctions::await(op);
}
+HRESULT QEventDispatcherWinRT::runOnMainThread(const std::function<HRESULT()> &delegate, int timeout)
+{
+ if (QThread::currentThread() == QCoreApplication::instance()->thread())
+ return delegate();
+
+ auto semaphore = QSharedPointer<QSemaphore>(new QSemaphore);
+ auto ptrSemaphore = new QSharedPointer<QSemaphore>(semaphore);
+ auto result = QSharedPointer<HRESULT>(new HRESULT);
+ auto ptrResult = new QSharedPointer<HRESULT>(result);
+
+ QMetaObject::invokeMethod(QCoreApplication::instance(), [delegate, ptrSemaphore, ptrResult]() {
+ **ptrResult = delegate();
+ delete ptrResult;
+ (*ptrSemaphore)->release();
+ delete ptrSemaphore;
+ }, nullptr);
+
+ return semaphore->tryAcquire(1, timeout) ? *result : E_FAIL;
+}
+
bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
{
Q_D(QEventDispatcherWinRT);
diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h
index f69bb9cf3f..8b998a7958 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt_p.h
+++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h
@@ -75,6 +75,7 @@ public:
~QEventDispatcherWinRT();
static HRESULT runOnXamlThread(const std::function<HRESULT()> &delegate, bool waitForRun = true);
+ static HRESULT runOnMainThread(const std::function<HRESULT()> &delegate, int timeout = 100);
bool processEvents(QEventLoop::ProcessEventsFlags flags);
bool hasPendingEvents();
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index fc40668c9a..0e57cb8cba 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -316,7 +316,7 @@ struct DefinedTypesFilter {
\omitvalue WeakPointerToQObject
\omitvalue TrackingPointerToQObject
\omitvalue WasDeclaredAsMetaType
- \omitvalue IsGadget This type is a Q_GADGET and it's corresponding QMetaObject can be accessed with QMetaType::metaObject Since 5.5.
+ \omitvalue IsGadget \omit This type is a Q_GADGET and it's corresponding QMetaObject can be accessed with QMetaType::metaObject Since 5.5. \endomit
\omitvalue PointerToGadget
*/
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index dcc1bb5814..25d17ecd6b 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4802,7 +4802,12 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
const int *types, const QMetaObject *senderMetaObject)
{
if (!sender || !receiver || !slotObj || !senderMetaObject) {
- qWarning("QObject::connect: invalid null parameter");
+ const char *senderString = sender ? sender->metaObject()->className()
+ : senderMetaObject ? senderMetaObject->className()
+ : "Unknown";
+ const char *receiverString = receiver ? receiver->metaObject()->className()
+ : "Unknown";
+ qWarning("QObject::connect(%s, %s): invalid null parameter", senderString, receiverString);
if (slotObj)
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index c3504943c4..802c8d72f6 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -571,6 +571,48 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv
*/
/*!
+ \fn template<typename Functor> QMetaObject::Connection connectTo(Functor functor, Qt::ConnectionType connectionType = Qt::AutoConnection)
+ \since 5.12
+ \overload
+
+ Creates a connection from the timeout() signal to \a functor, and returns a
+ handle to the connection.
+
+ This method is provided for convenience.
+ It's equivalent to calling \c {QObject::connect(timer, &QTimer::timeout, timer, functor, connectionType)}.
+
+ \sa QObject::connect(), timeout()
+*/
+
+/*!
+ \fn template<typename Functor> QMetaObject::Connection connectTo(QObject *context, Functor functor, Qt::ConnectionType connectionType = Qt::AutoConnection)
+ \since 5.12
+ \overload connectTo()
+
+ Creates a connection from the timeout() signal to \a functor to be placed in a specific
+ event loop of \a context, and returns a handle to the connection.
+
+ This method is provided for convenience. It's equivalent to calling
+ \c {QObject::connect(timer, &QTimer::timeout, context, functor, connectionType)}.
+
+ \sa QObject::connect(), timeout()
+*/
+
+/*!
+ \fn template<typename PointerToMemberFunction> QMetaObject::Connection connectTo(QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType connectionType = Qt::AutoConnection)
+ \since 5.12
+ \overload connectTo()
+
+ Creates a connection from the timeout() signal to the \a method in the \a receiver object. Returns
+ a handle to the connection.
+
+ This method is provided for convenience. It's equivalent to calling
+ \c {QObject::connect(timer, &QTimer::timeout, receiver, method, connectionType)}.
+
+ \sa QObject::connect(), timeout()
+*/
+
+/*!
\fn void QTimer::start(std::chrono::milliseconds msec)
\since 5.8
\overload
diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h
index e6db586aa0..7825bb0798 100644
--- a/src/corelib/kernel/qtimer.h
+++ b/src/corelib/kernel/qtimer.h
@@ -96,6 +96,12 @@ public:
static void singleShot(int msec, const QObject *context, Functor functor);
template<typename Functor, int>
static void singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor);
+ template <typename Functor>
+ QMetaObject::Connection connectTo(Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
+ template <typename Functor>
+ QMetaObject::Connection connectTo(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
+ template <typename PointerToMemberFunction>
+ QMetaObject::Connection connectTo(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
#else
// singleShot to a QObject slot
template <typename Duration, typename Func1>
@@ -152,6 +158,13 @@ public:
new QtPrivate::QFunctorSlotObject<Func1, 0,
typename QtPrivate::List_Left<void, 0>::Value, void>(std::move(slot)));
}
+
+ template <typename ... Args>
+ QMetaObject::Connection connectTo(Args && ...args)
+ {
+ return QObject::connect(this, &QTimer::timeout, std::forward<Args>(args)... );
+ }
+
#endif
public Q_SLOTS:
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 6192b66487..b41a883e80 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1175,9 +1175,16 @@ static void customConstruct(QVariant::Private *d, const void *copy)
type.construct(&d->data.ptr, copy);
d->is_shared = false;
} else {
- void *ptr = type.create(copy);
+ // Private::Data contains long long, and long double is the biggest standard type.
+ const size_t maxAlignment =
+ qMax(Q_ALIGNOF(QVariant::Private::Data), Q_ALIGNOF(long double));
+ const size_t s = sizeof(QVariant::PrivateShared);
+ const size_t offset = s + ((s * maxAlignment - s) % maxAlignment);
+ void *data = operator new(offset + size);
+ void *ptr = static_cast<char *>(data) + offset;
+ type.construct(ptr, copy);
d->is_shared = true;
- d->data.shared = new QVariant::PrivateShared(ptr);
+ d->data.shared = new (data) QVariant::PrivateShared(ptr);
}
}
@@ -1186,7 +1193,7 @@ static void customClear(QVariant::Private *d)
if (!d->is_shared) {
QMetaType::destruct(d->type, &d->data.ptr);
} else {
- QMetaType::destroy(d->type, d->data.shared->ptr);
+ QMetaType::destruct(d->type, d->data.shared->ptr);
delete d->data.shared;
}
}
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 9a5fc63d03..ff73c27b6e 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -633,6 +633,7 @@ public:
const_iterator &operator-=(int j);
const_iterator operator+(int j) const;
const_iterator operator-(int j) const;
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
};
friend struct const_iterator;
@@ -690,6 +691,7 @@ public:
const_iterator &operator-=(int j);
const_iterator operator+(int j) const;
const_iterator operator-(int j) const;
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
};
friend struct const_iterator;
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp
index 24de491326..85d4ad4fa9 100644
--- a/src/corelib/kernel/qwineventnotifier.cpp
+++ b/src/corelib/kernel/qwineventnotifier.cpp
@@ -157,7 +157,6 @@ void QWinEventNotifier::setHandle(HANDLE hEvent)
Q_D(QWinEventNotifier);
setEnabled(false);
d->handleToEvent = hEvent;
- d->signaledCount = 0;
}
/*!
@@ -209,10 +208,12 @@ void QWinEventNotifier::setEnabled(bool enable)
return;
}
- if (enable)
+ if (enable) {
+ d->signaledCount = 0;
eventDispatcher->registerEventNotifier(this);
- else
+ } else {
eventDispatcher->unregisterEventNotifier(this);
+ }
}
/*!
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index a4be18a67f..deea7a7d17 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -117,29 +117,22 @@ void QFactoryLoader::update()
QDir::Files);
QLibraryPrivate *library = 0;
-#ifdef Q_OS_MAC
- // Loading both the debug and release version of the cocoa plugins causes the objective-c runtime
- // to print "duplicate class definitions" warnings. Detect if QFactoryLoader is about to load both,
- // skip one of them (below).
- //
- // ### FIXME find a proper solution
- //
- const bool isLoadingDebugAndReleaseCocoa = plugins.contains(QLatin1String("libqcocoa_debug.dylib"))
- && plugins.contains(QLatin1String("libqcocoa.dylib"));
-#endif
for (int j = 0; j < plugins.count(); ++j) {
QString fileName = QDir::cleanPath(path + QLatin1Char('/') + plugins.at(j));
#ifdef Q_OS_MAC
- if (isLoadingDebugAndReleaseCocoa) {
-#ifdef QT_DEBUG
- if (fileName.contains(QLatin1String("libqcocoa.dylib")))
- continue; // Skip release plugin in debug mode
-#else
- if (fileName.contains(QLatin1String("libqcocoa_debug.dylib")))
- continue; // Skip debug plugin in release mode
-#endif
- }
+ const bool isDebugPlugin = fileName.endsWith(QLatin1String("_debug.dylib"));
+ const bool isDebugLibrary =
+ #ifdef QT_DEBUG
+ true;
+ #else
+ false;
+ #endif
+
+ // Skip mismatching plugins so that we don't end up loading both debug and release
+ // versions of the same Qt libraries (due to the plugin's dependencies).
+ if (isDebugPlugin != isDebugLibrary)
+ continue;
#endif
if (qt_debug_component()) {
qDebug() << "QFactoryLoader::QFactoryLoader() looking at" << fileName;
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index b644d47856..07edc616df 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -105,11 +105,21 @@ void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
}; \
static Static##PLUGIN##PluginInstance static##PLUGIN##Instance;
+#if defined(QT_PLUGIN_RESOURCE_INIT_FUNCTION)
+# define QT_PLUGIN_RESOURCE_INIT \
+ extern void QT_PLUGIN_RESOURCE_INIT_FUNCTION(); \
+ QT_PLUGIN_RESOURCE_INIT_FUNCTION();
+#else
+# define QT_PLUGIN_RESOURCE_INIT
+#endif
+
#define Q_PLUGIN_INSTANCE(IMPLEMENTATION) \
{ \
static QT_PREPEND_NAMESPACE(QPointer)<QT_PREPEND_NAMESPACE(QObject)> _instance; \
- if (!_instance) \
+ if (!_instance) { \
+ QT_PLUGIN_RESOURCE_INIT \
_instance = new IMPLEMENTATION; \
+ } \
return _instance; \
}
diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp
index 8f419a4a46..54d1ae816b 100644
--- a/src/corelib/serialization/qdatastream.cpp
+++ b/src/corelib/serialization/qdatastream.cpp
@@ -564,6 +564,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_9 Same as Qt_5_6
\value Qt_5_10 Same as Qt_5_6
\value Qt_5_11 Same as Qt_5_6
+ \value Qt_5_12 Same as Qt_5_6
\omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version()
diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h
index 1f1b13686c..85a2177652 100644
--- a/src/corelib/serialization/qdatastream.h
+++ b/src/corelib/serialization/qdatastream.h
@@ -98,10 +98,11 @@ public:
Qt_5_9 = Qt_5_8,
Qt_5_10 = Qt_5_9,
Qt_5_11 = Qt_5_10,
-#if QT_VERSION >= 0x050c00
+ Qt_5_12 = Qt_5_11,
+#if QT_VERSION >= 0x050d00
#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
#endif
- Qt_DefaultCompiledVersion = Qt_5_11
+ Qt_DefaultCompiledVersion = Qt_5_12
};
enum ByteOrder {
diff --git a/src/corelib/thread/qfuture.h b/src/corelib/thread/qfuture.h
index af599c26db..a456dd9139 100644
--- a/src/corelib/thread/qfuture.h
+++ b/src/corelib/thread/qfuture.h
@@ -136,6 +136,7 @@ public:
inline const_iterator operator-(int j) const { return const_iterator(future, index - j); }
inline const_iterator &operator+=(int j) { index += j; return *this; }
inline const_iterator &operator-=(int j) { index -= j; return *this; }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
private:
QFuture const * future;
int index;
diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h
index 4e6f522a37..ec9bfc1152 100644
--- a/src/corelib/thread/qmutex_p.h
+++ b/src/corelib/thread/qmutex_p.h
@@ -58,6 +58,7 @@
#include <QtCore/qnamespace.h>
#include <QtCore/qmutex.h>
#include <QtCore/qatomic.h>
+#include <QtCore/qdeadlinetimer.h>
#if defined(Q_OS_MAC)
# include <mach/semaphore.h>
@@ -146,7 +147,7 @@ public:
// helper functions for qmutex_unix.cpp and qwaitcondition_unix.cpp
// they are in qwaitcondition_unix.cpp actually
void qt_initialize_pthread_cond(pthread_cond_t *cond, const char *where);
-void qt_abstime_for_timeout(struct timespec *ts, int timeout);
+void qt_abstime_for_timeout(struct timespec *ts, QDeadlineTimer deadline);
#endif
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp
index 3e1e531be4..91f02ba3ec 100644
--- a/src/corelib/thread/qmutex_unix.cpp
+++ b/src/corelib/thread/qmutex_unix.cpp
@@ -130,7 +130,7 @@ bool QMutexPrivate::wait(int timeout)
errorCode = pthread_cond_wait(&cond, &mutex);
} else {
timespec ti;
- qt_abstime_for_timeout(&ti, timeout);
+ qt_abstime_for_timeout(&ti, QDeadlineTimer(timeout));
errorCode = pthread_cond_timedwait(&cond, &mutex, &ti);
}
if (errorCode) {
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index e91e859975..f418ac1205 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -487,11 +487,9 @@ bool QSemaphore::tryAcquire(int n, int timeout)
QDeadlineTimer timer(timeout);
QMutexLocker locker(&d->mutex);
- qint64 remainingTime = timer.remainingTime();
- while (n > d->avail && remainingTime != 0) {
- if (!d->cond.wait(locker.mutex(), remainingTime))
+ while (n > d->avail && !timer.hasExpired()) {
+ if (!d->cond.wait(locker.mutex(), timer))
return false;
- remainingTime = timer.remainingTime();
}
if (n > d->avail)
return false;
diff --git a/src/corelib/thread/qwaitcondition.h b/src/corelib/thread/qwaitcondition.h
index a0c6766833..e42efbdfca 100644
--- a/src/corelib/thread/qwaitcondition.h
+++ b/src/corelib/thread/qwaitcondition.h
@@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_THREAD
+class QDeadlineTimer;
class QWaitConditionPrivate;
class QMutex;
class QReadWriteLock;
@@ -59,8 +60,11 @@ public:
QWaitCondition();
~QWaitCondition();
+ // ### Qt 6: remove unsigned long overloads
bool wait(QMutex *lockedMutex, unsigned long time = ULONG_MAX);
+ bool wait(QMutex *lockedMutex, QDeadlineTimer deadline);
bool wait(QReadWriteLock *lockedReadWriteLock, unsigned long time = ULONG_MAX);
+ bool wait(QReadWriteLock *lockedReadWriteLock, QDeadlineTimer deadline);
void wakeOne();
void wakeAll();
diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp
index 6adee5412e..1628ede3a2 100644
--- a/src/corelib/thread/qwaitcondition_unix.cpp
+++ b/src/corelib/thread/qwaitcondition_unix.cpp
@@ -44,6 +44,8 @@
#include "qreadwritelock.h"
#include "qatomic.h"
#include "qstring.h"
+#include "qdeadlinetimer.h"
+#include "private/qdeadlinetimer_p.h"
#include "qelapsedtimer.h"
#include "private/qcore_unix_p.h"
@@ -93,23 +95,25 @@ void qt_initialize_pthread_cond(pthread_cond_t *cond, const char *where)
pthread_condattr_destroy(&condattr);
}
-void qt_abstime_for_timeout(timespec *ts, int timeout)
+void qt_abstime_for_timeout(timespec *ts, QDeadlineTimer deadline)
{
#ifdef Q_OS_MAC
// on Mac, qt_gettime() (on qelapsedtimer_mac.cpp) returns ticks related to the Mach absolute time
// that doesn't work with pthread
// Mac also doesn't have clock_gettime
struct timeval tv;
+ qint64 nsec = deadline.remainingTimeNSecs();
gettimeofday(&tv, 0);
- ts->tv_sec = tv.tv_sec;
- ts->tv_nsec = tv.tv_usec * 1000;
-#else
- *ts = qt_gettime();
-#endif
+ ts->tv_sec = tv.tv_sec + nsec / (1000 * 1000 * 1000);
+ ts->tv_nsec = tv.tv_usec * 1000 + nsec % (1000 * 1000 * 1000);
- ts->tv_sec += timeout / 1000;
- ts->tv_nsec += timeout % 1000 * Q_UINT64_C(1000) * 1000;
normalizedTimespec(*ts);
+#else
+ // depends on QDeadlineTimer's internals!!
+ Q_STATIC_ASSERT(QDeadlineTimerNanosecondsInT2);
+ ts->tv_sec = deadline._q_data().first;
+ ts->tv_nsec = deadline._q_data().second;
+#endif
}
class QWaitConditionPrivate {
@@ -119,26 +123,27 @@ public:
int waiters;
int wakeups;
- int wait_relative(unsigned long time)
+ int wait_relative(QDeadlineTimer deadline)
{
timespec ti;
#ifdef Q_OS_ANDROID
- if (local_cond_timedwait_relative) {
- ti.tv_sec = time / 1000;
- ti.tv_nsec = time % 1000 * Q_UINT64_C(1000) * 1000;
+ if (!local_condattr_setclock && local_cond_timedwait_relative) {
+ qint64 nsec = deadline.remainingTimeNSecs();
+ ti.tv_sec = nsec / (1000 * 1000 * 1000);
+ ti.tv_nsec = nsec - ti.tv_sec * 1000 * 1000 * 1000;
return local_cond_timedwait_relative(&cond, &mutex, &ti);
}
#endif
- qt_abstime_for_timeout(&ti, time);
+ qt_abstime_for_timeout(&ti, deadline);
return pthread_cond_timedwait(&cond, &mutex, &ti);
}
- bool wait(unsigned long time)
+ bool wait(QDeadlineTimer deadline)
{
int code;
forever {
- if (time != ULONG_MAX) {
- code = wait_relative(time);
+ if (!deadline.isForever()) {
+ code = wait_relative(deadline);
} else {
code = pthread_cond_wait(&cond, &mutex);
}
@@ -201,6 +206,13 @@ void QWaitCondition::wakeAll()
bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
{
+ if (time > std::numeric_limits<qint64>::max())
+ return wait(mutex, QDeadlineTimer(QDeadlineTimer::Forever));
+ return wait(mutex, QDeadlineTimer(time));
+}
+
+bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
+{
if (! mutex)
return false;
if (mutex->isRecursive()) {
@@ -212,7 +224,7 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
++d->waiters;
mutex->unlock();
- bool returnValue = d->wait(time);
+ bool returnValue = d->wait(deadline);
mutex->lock();
@@ -221,6 +233,11 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
{
+ return wait(readWriteLock, QDeadlineTimer(time));
+}
+
+bool QWaitCondition::wait(QReadWriteLock *readWriteLock, QDeadlineTimer deadline)
+{
if (!readWriteLock)
return false;
auto previousState = readWriteLock->stateForWaitCondition();
@@ -236,7 +253,7 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
readWriteLock->unlock();
- bool returnValue = d->wait(time);
+ bool returnValue = d->wait(deadline);
if (previousState == QReadWriteLock::LockedForWrite)
readWriteLock->lockForWrite();
diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp
index e6610f18c8..61e4c2bcb1 100644
--- a/src/corelib/thread/qwaitcondition_win.cpp
+++ b/src/corelib/thread/qwaitcondition_win.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qwaitcondition.h"
+#include "qdeadlinetimer.h"
#include "qnamespace.h"
#include "qmutex.h"
#include "qreadwritelock.h"
@@ -184,6 +185,11 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
return returnValue;
}
+bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
+{
+ return wait(mutex, deadline.remainingTime());
+}
+
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
{
if (!readWriteLock)
@@ -210,6 +216,11 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
return returnValue;
}
+bool QWaitCondition::wait(QReadWriteLock *readWriteLock, QDeadlineTimer deadline)
+{
+ return wait(readWriteLock, deadline.remainingTime());
+}
+
void QWaitCondition::wakeOne()
{
// wake up the first waiting thread in the queue
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h
index f0cc56e899..a642fb9b39 100644
--- a/src/corelib/tools/qarraydata.h
+++ b/src/corelib/tools/qarraydata.h
@@ -159,6 +159,7 @@ struct QTypedArrayData
inline iterator &operator-=(int j) { i-=j; return *this; }
inline iterator operator+(int j) const { return iterator(i+j); }
inline iterator operator-(int j) const { return iterator(i-j); }
+ friend inline iterator operator+(int j, iterator k) { return k + j; }
inline int operator-(iterator j) const { return i - j.i; }
inline operator T*() const { return i; }
};
@@ -194,6 +195,7 @@ struct QTypedArrayData
inline const_iterator &operator-=(int j) { i-=j; return *this; }
inline const_iterator operator+(int j) const { return const_iterator(i+j); }
inline const_iterator operator-(int j) const { return const_iterator(i-j); }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
inline int operator-(const_iterator j) const { return i - j.i; }
inline operator const T*() const { return i; }
};
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 83b9f19094..d9cd20ffbf 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -963,7 +963,7 @@ static inline char qToLower(char c)
$LC_CTYPE is set, most Unix systems do "the right thing".)
Functions that this affects include contains(), indexOf(),
lastIndexOf(), operator<(), operator<=(), operator>(),
- operator>=(), toLower() and toUpper().
+ operator>=(), isLower(), isUpper(), toLower() and toUpper().
This issue does not apply to \l{QString}s since they represent
characters using Unicode.
@@ -2954,6 +2954,78 @@ bool QByteArray::endsWith(const char *str) const
return qstrncmp(d->data() + d->size - len, str, len) == 0;
}
+/*!
+ Returns true if \a c is an uppercase Latin1 letter.
+ \note The multiplication sign 0xD7 and the sz ligature 0xDF are not
+ treated as uppercase Latin1.
+ */
+static inline bool isUpperCaseLatin1(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return true;
+
+ return (uchar(c) >= 0xC0 && uchar(c) <= 0xDE && uchar(c) != 0xD7);
+}
+
+/*!
+ Returns \c true if this byte array contains only uppercase letters,
+ otherwise returns \c false. The byte array is interpreted as a Latin-1
+ encoded string.
+ \since 5.12
+
+ \sa isLower(), toUpper()
+*/
+bool QByteArray::isUpper() const
+{
+ if (isEmpty())
+ return false;
+
+ const char *d = data();
+
+ for (int i = 0, max = size(); i < max; ++i) {
+ if (!isUpperCaseLatin1(d[i]))
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ Returns true if \a c is an lowercase Latin1 letter.
+ \note The division sign 0xF7 is not treated as lowercase Latin1,
+ but the small y dieresis 0xFF is.
+ */
+static inline bool isLowerCaseLatin1(char c)
+{
+ if (c >= 'a' && c <= 'z')
+ return true;
+
+ return (uchar(c) >= 0xD0 && uchar(c) != 0xF7);
+}
+
+/*!
+ Returns \c true if this byte array contains only lowercase letters,
+ otherwise returns \c false. The byte array is interpreted as a Latin-1
+ encoded string.
+ \since 5.12
+
+ \sa isUpper(), toLower()
+ */
+bool QByteArray::isLower() const
+{
+ if (isEmpty())
+ return false;
+
+ const char *d = data();
+
+ for (int i = 0, max = size(); i < max; ++i) {
+ if (!isLowerCaseLatin1(d[i]))
+ return false;
+ }
+
+ return true;
+}
+
/*! \overload
Returns \c true if this byte array ends with character \a ch;
@@ -3065,7 +3137,7 @@ QByteArray QByteArray::mid(int pos, int len) const
Example:
\snippet code/src_corelib_tools_qbytearray.cpp 30
- \sa toUpper(), {8-bit Character Comparisons}
+ \sa isLower(), toUpper(), {8-bit Character Comparisons}
*/
// prevent the compiler from inlining the function in each of
@@ -3119,7 +3191,7 @@ QByteArray QByteArray::toLower_helper(QByteArray &a)
Example:
\snippet code/src_corelib_tools_qbytearray.cpp 31
- \sa toLower(), {8-bit Character Comparisons}
+ \sa isUpper(), toLower(), {8-bit Character Comparisons}
*/
QByteArray QByteArray::toUpper_helper(const QByteArray &a)
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index 300f795469..bed710c597 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -245,6 +245,9 @@ public:
bool endsWith(char c) const;
bool endsWith(const char *c) const;
+ bool isUpper() const;
+ bool isLower() const;
+
void truncate(int pos);
void chop(int n);
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index a1b121f1ee..3c79bb797d 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -544,6 +544,46 @@ QByteArray QCryptographicHash::hash(const QByteArray &data, Algorithm method)
return hash.result();
}
+/*!
+ Returns the size of the output of the selected hash \a method in bytes.
+
+ \since 5.12
+*/
+int QCryptographicHash::hashLength(QCryptographicHash::Algorithm method)
+{
+ switch (method) {
+ case QCryptographicHash::Sha1:
+ return 20;
+#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+ case QCryptographicHash::Md4:
+ return 16;
+ case QCryptographicHash::Md5:
+ return 16;
+ case QCryptographicHash::Sha224:
+ return SHA224HashSize;
+ case QCryptographicHash::Sha256:
+ return SHA256HashSize;
+ case QCryptographicHash::Sha384:
+ return SHA384HashSize;
+ case QCryptographicHash::Sha512:
+ return SHA512HashSize;
+ case QCryptographicHash::RealSha3_224:
+ case QCryptographicHash::Keccak_224:
+ return 224 / 8;
+ case QCryptographicHash::RealSha3_256:
+ case QCryptographicHash::Keccak_256:
+ return 256 / 8;
+ case QCryptographicHash::RealSha3_384:
+ case QCryptographicHash::Keccak_384:
+ return 384 / 8;
+ case QCryptographicHash::RealSha3_512:
+ case QCryptographicHash::Keccak_512:
+ return 512 / 8;
+#endif
+ }
+ return 0;
+}
+
QT_END_NAMESPACE
#ifndef QT_NO_QOBJECT
diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h
index 2f74d42405..ad1de7c756 100644
--- a/src/corelib/tools/qcryptographichash.h
+++ b/src/corelib/tools/qcryptographichash.h
@@ -101,6 +101,7 @@ public:
QByteArray result() const;
static QByteArray hash(const QByteArray &data, Algorithm method);
+ static int hashLength(Algorithm method);
private:
Q_DISABLE_COPY(QCryptographicHash)
QCryptographicHashPrivate *d;
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index ce663ce2ca..a586ca5671 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -348,6 +348,7 @@ public:
inline iterator operator-(int j) const { return operator+(-j); }
inline iterator &operator+=(int j) { return *this = *this + j; }
inline iterator &operator-=(int j) { return *this = *this - j; }
+ friend inline iterator operator+(int j, iterator k) { return k + j; }
#ifndef QT_STRICT_ITERATORS
public:
@@ -413,6 +414,7 @@ public:
inline const_iterator operator-(int j) const { return operator+(-j); }
inline const_iterator &operator+=(int j) { return *this = *this + j; }
inline const_iterator &operator-=(int j) { return *this = *this - j; }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
// ### Qt 5: not sure this is necessary anymore
#ifdef QT_STRICT_ITERATORS
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
index c8f3f4c8c3..1e6d4df474 100644
--- a/src/corelib/tools/qlinkedlist.h
+++ b/src/corelib/tools/qlinkedlist.h
@@ -159,6 +159,7 @@ public:
inline iterator operator-(int j) const { return operator+(-j); }
inline iterator &operator+=(int j) { return *this = *this + j; }
inline iterator &operator-=(int j) { return *this = *this - j; }
+ friend inline iterator operator+(int j, iterator k) { return k + j; }
};
friend class iterator;
@@ -193,6 +194,7 @@ public:
inline const_iterator operator-(int j) const { return operator+(-j); }
inline const_iterator &operator+=(int j) { return *this = *this + j; }
inline const_iterator &operator-=(int j) { return *this = *this - j; }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
};
friend class const_iterator;
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index af7659e995..c00220ad3a 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -269,6 +269,7 @@ public:
inline iterator &operator-=(difference_type j) { i-=j; return *this; }
inline iterator operator+(difference_type j) const { return iterator(i+j); }
inline iterator operator-(difference_type j) const { return iterator(i-j); }
+ friend inline iterator operator+(difference_type j, iterator k) { return k + j; }
inline int operator-(iterator j) const { return int(i - j.i); }
};
friend class iterator;
@@ -312,6 +313,7 @@ public:
inline const_iterator &operator-=(difference_type j) { i-=j; return *this; }
inline const_iterator operator+(difference_type j) const { return const_iterator(i+j); }
inline const_iterator operator-(difference_type j) const { return const_iterator(i-j); }
+ friend inline const_iterator operator+(difference_type j, const_iterator k) { return k + j; }
inline int operator-(const_iterator j) const { return int(i - j.i); }
};
friend class const_iterator;
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 09b148ea9e..9c1e78ee61 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -233,14 +233,6 @@ QLocaleId QLocaleId::withLikelySubtagsAdded() const
if (addLikelySubtags(id))
return id;
}
- // language_script
- if (country_id) {
- QLocaleId id = QLocaleId::fromIds(language_id, script_id, 0);
- if (addLikelySubtags(id)) {
- id.country_id = country_id;
- return id;
- }
- }
// language_region
if (script_id) {
QLocaleId id = QLocaleId::fromIds(language_id, 0, country_id);
@@ -249,6 +241,14 @@ QLocaleId QLocaleId::withLikelySubtagsAdded() const
return id;
}
}
+ // language_script
+ if (country_id) {
+ QLocaleId id = QLocaleId::fromIds(language_id, script_id, 0);
+ if (addLikelySubtags(id)) {
+ id.country_id = country_id;
+ return id;
+ }
+ }
// language
if (script_id && country_id) {
QLocaleId id = QLocaleId::fromIds(language_id, 0, 0);
@@ -258,6 +258,14 @@ QLocaleId QLocaleId::withLikelySubtagsAdded() const
return id;
}
}
+ // und_script
+ if (language_id) {
+ QLocaleId id = QLocaleId::fromIds(0, script_id, 0);
+ if (addLikelySubtags(id)) {
+ id.language_id = language_id;
+ return id;
+ }
+ }
return *this;
}
@@ -382,6 +390,13 @@ const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLoca
QList<QLocaleId> tried;
tried.push_back(likelyId);
+ // No match; try again with raw data:
+ if (!tried.contains(localeId)) {
+ if (const QLocaleData *const data = findLocaleDataById(localeId))
+ return data;
+ tried.push_back(localeId);
+ }
+
// No match; try again with likely country
if (country != QLocale::AnyCountry
&& (language != QLocale::AnyLanguage || script != QLocale::AnyScript)) {
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index a5b9096835..1cf9299e26 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -449,6 +449,7 @@ public:
inline iterator operator-(int j) const { return operator+(-j); }
inline iterator &operator+=(int j) { return *this = *this + j; }
inline iterator &operator-=(int j) { return *this = *this - j; }
+ friend inline iterator operator+(int j, iterator k) { return k + j; }
#ifndef QT_STRICT_ITERATORS
public:
@@ -512,6 +513,7 @@ public:
inline const_iterator operator-(int j) const { return operator+(-j); }
inline const_iterator &operator+=(int j) { return *this = *this + j; }
inline const_iterator &operator-=(int j) { return *this = *this - j; }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
#ifdef QT_STRICT_ITERATORS
private:
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index 96ddca56af..43e31ddb8e 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -3813,8 +3813,10 @@ struct QRegExpPrivate
};
#if !defined(QT_NO_REGEXP_OPTIM)
-typedef QCache<QRegExpEngineKey, QRegExpEngine> EngineCache;
+typedef QHash<QRegExpEngineKey, QRegExpEngine *> EngineCache;
Q_GLOBAL_STATIC(EngineCache, globalEngineCache)
+typedef QCache<QRegExpEngineKey, QRegExpEngine> UnusedEngineCache;
+Q_GLOBAL_STATIC(UnusedEngineCache, globalUnusedEngineCache)
static QBasicMutex globalEngineCacheMutex;
#endif // QT_NO_REGEXP_OPTIM
@@ -3822,14 +3824,16 @@ static void derefEngine(QRegExpEngine *eng, const QRegExpEngineKey &key)
{
if (!eng->ref.deref()) {
#if !defined(QT_NO_REGEXP_OPTIM)
- if (globalEngineCache()) {
+ if (globalUnusedEngineCache()) {
QMutexLocker locker(&globalEngineCacheMutex);
QT_TRY {
- globalEngineCache()->insert(key, eng, 4 + key.pattern.length() / 4);
+ globalUnusedEngineCache()->insert(key, eng, 4 + key.pattern.length() / 4);
} QT_CATCH(const std::bad_alloc &) {
// in case of an exception (e.g. oom), just delete the engine
delete eng;
}
+ if (globalEngineCache())
+ globalEngineCache()->remove(key);
} else {
delete eng;
}
@@ -3844,9 +3848,11 @@ static void prepareEngine_helper(QRegExpPrivate *priv)
{
bool initMatchState = !priv->eng;
#if !defined(QT_NO_REGEXP_OPTIM)
- if (!priv->eng && globalEngineCache()) {
+ if (!priv->eng && globalUnusedEngineCache()) {
QMutexLocker locker(&globalEngineCacheMutex);
- priv->eng = globalEngineCache()->take(priv->engineKey);
+ priv->eng = globalUnusedEngineCache()->take(priv->engineKey);
+ if (!priv->eng && globalEngineCache())
+ priv->eng = globalEngineCache()->value(priv->engineKey);
if (priv->eng != 0)
priv->eng->ref.ref();
}
@@ -3854,6 +3860,10 @@ static void prepareEngine_helper(QRegExpPrivate *priv)
if (!priv->eng)
priv->eng = new QRegExpEngine(priv->engineKey);
+#if !defined(QT_NO_REGEXP_OPTIM)
+ if (globalEngineCache())
+ globalEngineCache()->insert(priv->engineKey, priv->eng);
+#endif
if (initMatchState)
priv->matchState.prepareForMatch(priv->eng);
diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp
index 13eff07c04..29ad578013 100644
--- a/src/corelib/tools/qregularexpression.cpp
+++ b/src/corelib/tools/qregularexpression.cpp
@@ -798,6 +798,83 @@ Q_AUTOTEST_EXPORT unsigned int qt_qregularexpression_optimize_after_use_count =
static const unsigned int qt_qregularexpression_optimize_after_use_count = 10;
#endif // QT_BUILD_INTERNAL
+
+namespace QtPrivate {
+/*!
+ internal
+*/
+QString wildcardToRegularExpression(const QString &wildcardString)
+{
+ const int wclen = wildcardString.length();
+ QString rx;
+ int i = 0;
+ bool hasNegativeBracket = false;
+ const QChar *wc = wildcardString.unicode();
+
+ while (i < wclen) {
+ const QChar c = wc[i++];
+ switch (c.unicode()) {
+ case '*':
+ rx += QLatin1String(".*");
+ break;
+ case '?':
+ rx += QLatin1Char('.');
+ break;
+ case '$':
+ case '(':
+ case ')':
+ case '+':
+ case '.':
+ case '^':
+ case '{':
+ case '|':
+ case '}':
+ rx += QLatin1Char('\\');
+ rx += c;
+ break;
+ case '[':
+ // Support for the [!abc] or [!a-c] syntax
+ // Implements a negative look-behind for one char.
+ if (wc[i] == QLatin1Char(']')) {
+ rx += c;
+ rx += wc[i++];
+ } else if (wc[i] == QLatin1Char('!')) {
+ rx += QLatin1String(".(?<");
+ rx += wc[i++];
+ rx += c;
+ hasNegativeBracket = true;
+ } else {
+ rx += c;
+ }
+
+ if (i < wclen) {
+ if (rx[i] == QLatin1Char(']'))
+ rx += wc[i++];
+ while (i < wclen && wc[i] != QLatin1Char(']')) {
+ if (wc[i] == QLatin1Char('\\'))
+ rx += QLatin1Char('\\');
+ rx += wc[i++];
+ }
+ }
+ break;
+ case ']':
+ rx += c;
+ // Closes the negative look-behind expression.
+ if (hasNegativeBracket) {
+ rx += QLatin1Char(')');
+ hasNegativeBracket = false;
+ }
+ break;
+ default:
+ rx += c;
+ break;
+ }
+ }
+
+ return rx;
+}
+}
+
/*!
\internal
*/
@@ -1554,6 +1631,47 @@ void QRegularExpression::setPattern(const QString &pattern)
}
/*!
+ \since 5.12
+
+ Sets the pattern string of the regular expression to \a wildcard pattern.
+ The pattern options are left unchanged.
+
+ \warning Unlike QRegExp, this implementation follows closely the definition
+ of wildcard for glob patterns:
+ \table
+ \row \li \b{c}
+ \li Any character represents itself apart from those mentioned
+ below. Thus \b{c} matches the character \e c.
+ \row \li \b{?}
+ \li Matches any single character. It is the same as
+ \b{.} in full regexps.
+ \row \li \b{*}
+ \li Matches zero or more of any characters. It is the
+ same as \b{.*} in full regexps.
+ \row \li \b{[abc]}
+ \li Matches one character given in the bracket.
+ \row \li \b{[a-c]}
+ \li Matches one character from the range given in the bracket.
+ \row \li \b{[!abc]}
+ \li Matches one character that is not given in the bracket.
+ \row \li \b{[!a-c]}
+ \li matches one character that is not from the range given in the
+ bracket.
+ \endtable
+
+ \note This function generates a regular expression that will act following
+ the wildcard pattern given. However the content of the regular expression
+ will not be the same as the one set.
+
+ \sa pattern(), setPattern()
+*/
+void QRegularExpression::setWildcardPattern(const QString &pattern)
+{
+ setPattern(QtPrivate::wildcardToRegularExpression(pattern));
+}
+
+
+/*!
Returns the pattern options for the regular expression.
\sa setPatternOptions(), pattern()
diff --git a/src/corelib/tools/qregularexpression.h b/src/corelib/tools/qregularexpression.h
index 398fc9ec9c..f26f52d427 100644
--- a/src/corelib/tools/qregularexpression.h
+++ b/src/corelib/tools/qregularexpression.h
@@ -96,6 +96,7 @@ public:
QString pattern() const;
void setPattern(const QString &pattern);
+ void setWildcardPattern(const QString &pattern);
bool isValid() const;
int patternErrorOffset() const;
diff --git a/src/corelib/tools/qregularexpression_p.h b/src/corelib/tools/qregularexpression_p.h
new file mode 100644
index 0000000000..f5455de853
--- /dev/null
+++ b/src/corelib/tools/qregularexpression_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Samuel Gaist <samuel.gaist@edeltech.ch>
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QREGULAREXPRESSION_P_H
+#define QREGULAREXPRESSION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qglobal_p.h>
+
+#include <qregularexpression.h>
+#include <qstring.h>
+
+QT_REQUIRE_CONFIG(regularexpression);
+
+QT_BEGIN_NAMESPACE
+
+namespace QtPrivate {
+QString wildcardToRegularExpression(const QString &expression);
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp
index eb7bdfe95c..59650ed2f7 100644
--- a/src/corelib/tools/qringbuffer.cpp
+++ b/src/corelib/tools/qringbuffer.cpp
@@ -312,12 +312,14 @@ qint64 QRingBuffer::peek(char *data, qint64 maxLength, qint64 pos) const
Q_ASSERT(maxLength >= 0 && pos >= 0);
qint64 readSoFar = 0;
- for (int i = 0; readSoFar < maxLength && i < buffers.size(); ++i) {
- qint64 blockLength = buffers[i].size();
+ for (const QRingChunk &chunk : buffers) {
+ if (readSoFar == maxLength)
+ break;
+ qint64 blockLength = chunk.size();
if (pos < blockLength) {
blockLength = qMin(blockLength - pos, maxLength - readSoFar);
- memcpy(data + readSoFar, buffers[i].data() + pos, blockLength);
+ memcpy(data + readSoFar, chunk.data() + pos, blockLength);
readSoFar += blockLength;
pos = 0;
} else {
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index 7ded120ab7..6640c8486d 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -131,6 +131,7 @@ public:
inline iterator operator--(int) { iterator r = *this; --i; return r; }
inline iterator operator+(int j) const { return i + j; }
inline iterator operator-(int j) const { return i - j; }
+ friend inline iterator operator+(int j, iterator k) { return k + j; }
inline iterator &operator+=(int j) { i += j; return *this; }
inline iterator &operator-=(int j) { i -= j; return *this; }
};
@@ -165,6 +166,7 @@ public:
inline const_iterator operator--(int) { const_iterator r = *this; --i; return r; }
inline const_iterator operator+(int j) const { return i + j; }
inline const_iterator operator-(int j) const { return i - j; }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
inline const_iterator &operator+=(int j) { i += j; return *this; }
inline const_iterator &operator-=(int j) { i -= j; return *this; }
};
diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h
index 780f2331a8..3ef134a99d 100644
--- a/src/corelib/tools/qshareddata.h
+++ b/src/corelib/tools/qshareddata.h
@@ -136,6 +136,18 @@ private:
T *d;
};
+template <class T> inline bool operator==(std::nullptr_t p1, const QSharedDataPointer<T> &p2)
+{
+ Q_UNUSED(p1);
+ return !p2;
+}
+
+template <class T> inline bool operator==(const QSharedDataPointer<T> &p1, std::nullptr_t p2)
+{
+ Q_UNUSED(p2);
+ return !p1;
+}
+
template <class T> class QExplicitlySharedDataPointer
{
public:
@@ -271,6 +283,18 @@ Q_INLINE_TEMPLATE QExplicitlySharedDataPointer<T>::QExplicitlySharedDataPointer(
: d(adata)
{ if (d) d->ref.ref(); }
+template <class T> inline bool operator==(std::nullptr_t p1, const QExplicitlySharedDataPointer<T> &p2)
+{
+ Q_UNUSED(p1);
+ return !p2;
+}
+
+template <class T> inline bool operator==(const QExplicitlySharedDataPointer<T> &p1, std::nullptr_t p2)
+{
+ Q_UNUSED(p2);
+ return !p1;
+}
+
template <class T>
Q_INLINE_TEMPLATE void qSwap(QSharedDataPointer<T> &p1, QSharedDataPointer<T> &p2)
{ p1.swap(p2); }
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index f6360f5504..46ec8b072c 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -4883,6 +4883,50 @@ bool QString::endsWith(QChar c, Qt::CaseSensitivity cs) const
return qt_ends_with(*this, c, cs);
}
+/*!
+ Returns \c true if the string only contains uppercase letters,
+ otherwise returns \c false.
+ \since 5.12
+
+ \sa QChar::isUpper(), isLower()
+*/
+bool QString::isUpper() const
+{
+ if (isEmpty())
+ return false;
+
+ const QChar *d = data();
+
+ for (int i = 0, max = size(); i < max; ++i) {
+ if (!d[i].isUpper())
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ Returns \c true if the string only contains lowercase letters,
+ otherwise returns \c false.
+ \since 5.12
+
+ \sa QChar::isLower(), isUpper()
+ */
+bool QString::isLower() const
+{
+ if (isEmpty())
+ return false;
+
+ const QChar *d = data();
+
+ for (int i = 0, max = size(); i < max; ++i) {
+ if (!d[i].isLower())
+ return false;
+ }
+
+ return true;
+}
+
static QByteArray qt_convert_to_latin1(QStringView string);
QByteArray QString::toLatin1_helper(const QString &string)
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index f27f7efa2b..447f000486 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -409,6 +409,9 @@ public:
bool endsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool endsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool isUpper() const;
+ bool isLower() const;
+
Q_REQUIRED_RESULT QString leftJustified(int width, QChar fill = QLatin1Char(' '), bool trunc = false) const;
Q_REQUIRED_RESULT QString rightJustified(int width, QChar fill = QLatin1Char(' '), bool trunc = false) const;
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
index daa7dc1531..db6be581ec 100644
--- a/src/corelib/tools/qtimezone.cpp
+++ b/src/corelib/tools/qtimezone.cpp
@@ -66,11 +66,10 @@ static QTimeZonePrivate *newBackendTimeZone()
return new QAndroidTimeZonePrivate();
#elif defined(Q_OS_UNIX) || defined(Q_OS_ANDROID_EMBEDDED)
return new QTzTimeZonePrivate();
- // Registry based timezone backend not available on WinRT
-#elif defined Q_OS_WIN
- return new QWinTimeZonePrivate();
#elif QT_CONFIG(icu)
return new QIcuTimeZonePrivate();
+#elif defined Q_OS_WIN
+ return new QWinTimeZonePrivate();
#else
return new QUtcTimeZonePrivate();
#endif // System Locales
@@ -93,11 +92,10 @@ static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId)
return new QAndroidTimeZonePrivate(ianaId);
#elif defined(Q_OS_UNIX) || defined(Q_OS_ANDROID_EMBEDDED)
return new QTzTimeZonePrivate(ianaId);
- // Registry based timezone backend not available on WinRT
-#elif defined Q_OS_WIN
- return new QWinTimeZonePrivate(ianaId);
#elif QT_CONFIG(icu)
return new QIcuTimeZonePrivate(ianaId);
+#elif defined Q_OS_WIN
+ return new QWinTimeZonePrivate(ianaId);
#else
return new QUtcTimeZonePrivate(ianaId);
#endif // System Locales
@@ -822,8 +820,8 @@ bool QTimeZone::isTimeZoneIdAvailable(const QByteArray &ianaId)
// IDs as availableTimeZoneIds() may be slow
if (!QTimeZonePrivate::isValidId(ianaId))
return false;
- const QList<QByteArray> tzIds = availableTimeZoneIds();
- return std::binary_search(tzIds.begin(), tzIds.end(), ianaId);
+ return QUtcTimeZonePrivate().isTimeZoneIdAvailable(ianaId) ||
+ global_tz->backend->isTimeZoneIdAvailable(ianaId);
}
static QList<QByteArray> set_union(const QList<QByteArray> &l1, const QList<QByteArray> &l2)
diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp
index 1a5135f103..2b6c2ea6a5 100644
--- a/src/corelib/tools/qtimezoneprivate.cpp
+++ b/src/corelib/tools/qtimezoneprivate.cpp
@@ -486,6 +486,13 @@ QByteArray QTimeZonePrivate::systemTimeZoneId() const
return QByteArray();
}
+bool QTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray& ianaId) const
+{
+ // Fall-back implementation, can be made faster in subclasses
+ const QList<QByteArray> tzIds = availableTimeZoneIds();
+ return std::binary_search(tzIds.begin(), tzIds.end(), ianaId);
+}
+
QList<QByteArray> QTimeZonePrivate::availableTimeZoneIds() const
{
return QList<QByteArray>();
@@ -864,6 +871,17 @@ QByteArray QUtcTimeZonePrivate::systemTimeZoneId() const
return utcQByteArray();
}
+bool QUtcTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
+{
+ for (int i = 0; i < utcDataTableSize; ++i) {
+ const QUtcData *data = utcData(i);
+ if (utcId(data) == ianaId) {
+ return true;
+ }
+ }
+ return false;
+}
+
QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds() const
{
QList<QByteArray> result;
diff --git a/src/corelib/tools/qtimezoneprivate_p.h b/src/corelib/tools/qtimezoneprivate_p.h
index 4d357111f2..c9a5726216 100644
--- a/src/corelib/tools/qtimezoneprivate_p.h
+++ b/src/corelib/tools/qtimezoneprivate_p.h
@@ -128,6 +128,7 @@ public:
virtual QByteArray systemTimeZoneId() const;
+ virtual bool isTimeZoneIdAvailable(const QByteArray &ianaId) const;
virtual QList<QByteArray> availableTimeZoneIds() const;
virtual QList<QByteArray> availableTimeZoneIds(QLocale::Country country) const;
virtual QList<QByteArray> availableTimeZoneIds(int utcOffset) const;
@@ -204,6 +205,7 @@ public:
QByteArray systemTimeZoneId() const override;
+ bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override;
QList<QByteArray> availableTimeZoneIds() const override;
QList<QByteArray> availableTimeZoneIds(QLocale::Country country) const override;
QList<QByteArray> availableTimeZoneIds(int utcOffset) const override;
@@ -323,6 +325,7 @@ public:
QByteArray systemTimeZoneId() const override;
+ bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override;
QList<QByteArray> availableTimeZoneIds() const override;
QList<QByteArray> availableTimeZoneIds(QLocale::Country country) const override;
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index 6a5df6272a..f1735a80e7 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -1098,6 +1098,11 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
return ianaId;
}
+bool QTzTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
+{
+ return tzZones->contains(ianaId);
+}
+
QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds() const
{
QList<QByteArray> result = tzZones->keys();
diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp
index 8bde07c710..ec91b7e8a8 100644
--- a/src/corelib/tools/qtimezoneprivate_win.cpp
+++ b/src/corelib/tools/qtimezoneprivate_win.cpp
@@ -49,6 +49,7 @@
QT_BEGIN_NAMESPACE
#ifndef Q_OS_WINRT
+// The registry-based timezone backend is not available on WinRT, which falls back to equivalent APIs.
#define QT_USE_REGISTRY_TIMEZONE 1
#endif
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 72224f280d..30f7edb5f2 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -159,16 +159,18 @@ qtConfig(timezone) {
SOURCES += \
tools/qtimezone.cpp \
tools/qtimezoneprivate.cpp
- !nacl:darwin: \
+ !nacl:darwin: {
SOURCES += tools/qtimezoneprivate_mac.mm
- else: android:!android-embedded: \
+ } else: android:!android-embedded: {
SOURCES += tools/qtimezoneprivate_android.cpp
- else: unix: \
+ } else: unix: {
SOURCES += tools/qtimezoneprivate_tz.cpp
- else: win32: \
- SOURCES += tools/qtimezoneprivate_win.cpp
- qtConfig(icu): \
+ qtConfig(icu): SOURCES += tools/qtimezoneprivate_icu.cpp
+ } else: qtConfig(icu): {
SOURCES += tools/qtimezoneprivate_icu.cpp
+ } else: win32: {
+ SOURCES += tools/qtimezoneprivate_win.cpp
+ }
}
qtConfig(datetimeparser) {
@@ -179,7 +181,9 @@ qtConfig(datetimeparser) {
qtConfig(regularexpression) {
QMAKE_USE_PRIVATE += pcre2
- HEADERS += tools/qregularexpression.h
+ HEADERS += \
+ tools/qregularexpression.h \
+ tools/qregularexpression_p.h
SOURCES += tools/qregularexpression.cpp
}