diff options
author | Liang Qi <liang.qi@qt.io> | 2017-09-26 16:08:55 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-09-26 16:14:54 +0200 |
commit | aadfe7d634de04519102c5827ca885dc2e2199c9 (patch) | |
tree | d92db346ca95332b177036a53f1f6beb2e24fb74 /src/corelib/tools/qstring.cpp | |
parent | 4b6c1448047362b8c38d265e6414f0e3e59b8d37 (diff) | |
parent | a732e16d5fd9dbf8a0289fec9f948b12e9ba2c19 (diff) |
Merge remote-tracking branch 'origin/5.10' into dev
Conflicts:
src/gui/kernel/qguiapplication.cpp
src/platformsupport/input/libinput/qlibinputpointer.cpp
src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
src/plugins/platforms/cocoa/qcocoawindow.h
src/testlib/qtestsystem.h
Change-Id: I5975ffb3261c2dd82fe02ec4e57df7c0950226c5
Diffstat (limited to 'src/corelib/tools/qstring.cpp')
-rw-r--r-- | src/corelib/tools/qstring.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index ea157a23d0..eeeff280ff 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -72,6 +72,7 @@ #include <stdlib.h> #include <stdio.h> #include <stdarg.h> +#include <wchar.h> #include "qchar.cpp" #include "qstringmatcher.cpp" @@ -159,6 +160,43 @@ static inline bool qt_ends_with(QStringView haystack, QStringView needle, Qt::Ca static inline bool qt_ends_with(QStringView haystack, QLatin1String needle, Qt::CaseSensitivity cs); static inline bool qt_ends_with(QStringView haystack, QChar needle, Qt::CaseSensitivity cs); +qssize_t qustrlen(const ushort *str) Q_DECL_NOTHROW +{ + qssize_t result = 0; + +#ifdef __SSE2__ + // progress until we get an aligned pointer + const ushort *ptr = str; + while (*ptr && quintptr(ptr) % 16) + ++ptr; + if (*ptr == 0) + return ptr - str; + + // load 16 bytes and see if we have a null + // (aligned loads can never segfault) + int mask; + const __m128i zeroes = _mm_setzero_si128(); + do { + __m128i data = _mm_load_si128(reinterpret_cast<const __m128i *>(ptr)); + ptr += 8; + + __m128i comparison = _mm_cmpeq_epi16(data, zeroes); + mask = _mm_movemask_epi8(comparison); + } while (mask == 0); + + // found a null + uint idx = qCountTrailingZeroBits(quint32(mask)); + return ptr - str - 8 + idx / 2; +#endif + + if (sizeof(wchar_t) == sizeof(ushort)) + return wcslen(reinterpret_cast<const wchar_t *>(str)); + + while (*str++) + ++result; + return result; +} + #if defined(Q_COMPILER_LAMBDA) && !defined(__OPTIMIZE_SIZE__) namespace { template <uint MaxCount> struct UnrollTailLoop |