summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qstringalgorithms.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/text/qstringalgorithms.h')
-rw-r--r--src/corelib/text/qstringalgorithms.h100
1 files changed, 98 insertions, 2 deletions
diff --git a/src/corelib/text/qstringalgorithms.h b/src/corelib/text/qstringalgorithms.h
index 52bb9736ba..538ae892b0 100644
--- a/src/corelib/text/qstringalgorithms.h
+++ b/src/corelib/text/qstringalgorithms.h
@@ -4,19 +4,27 @@
#ifndef QSTRINGALGORITHMS_H
#define QSTRINGALGORITHMS_H
+#include <QtCore/qbytearrayalgorithms.h>
+#include <QtCore/qcontainerfwd.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qstringfwd.h>
-#include <QtCore/qcontainerfwd.h>
#if 0
#pragma qt_class(QStringAlgorithms)
#endif
+#include <algorithm> // std::find
+#include <iterator> // std::size
+
+#include <QtCore/q20type_traits.h> // q20::is_constant_evaluated
+
QT_BEGIN_NAMESPACE
namespace QtPrivate {
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype qustrlen(const char16_t *str) noexcept;
+[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype qustrnlen(const char16_t *str, qsizetype maxlen) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION const char16_t *qustrchr(QStringView str, char16_t ch) noexcept;
+[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION const char16_t *qustrcasechr(QStringView str, char16_t ch) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QStringView lhs, QStringView rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QStringView lhs, QLatin1StringView rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
@@ -48,11 +56,14 @@ namespace QtPrivate {
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool endsWith(QLatin1StringView haystack, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool endsWith(QLatin1StringView haystack, QLatin1StringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
+[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype findStringInsensitive(QStringView haystack, qsizetype from, char16_t needle) noexcept;
+[[nodiscard]] inline qsizetype findString(QStringView str, qsizetype from, QChar needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype findString(QStringView haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype findString(QStringView haystack, qsizetype from, QLatin1StringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype findString(QLatin1StringView haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype findString(QLatin1StringView haystack, qsizetype from, QLatin1StringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
+[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype lastIndexOf(QStringView haystack, qsizetype from, char16_t needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype lastIndexOf(QStringView haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype lastIndexOf(QStringView haystack, qsizetype from, QLatin1StringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype lastIndexOf(QLatin1StringView haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
@@ -61,6 +72,9 @@ namespace QtPrivate {
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QStringView trimmed(QStringView s) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QLatin1StringView trimmed(QLatin1StringView s) noexcept;
+[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isLower(QStringView s) noexcept;
+[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isUpper(QStringView s) noexcept;
+
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QStringView haystack, QChar needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QStringView haystack, QLatin1StringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive);
@@ -69,14 +83,30 @@ namespace QtPrivate {
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QLatin1StringView haystack, QChar needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
#if QT_CONFIG(regularexpression)
+// ### Qt 7: unify these overloads;
+// remove the ones taking only a QStringView, export the others, adjust callers
+[[nodiscard]] qsizetype indexOf(QStringView viewHaystack,
+ const QString *stringHaystack,
+ const QRegularExpression &re,
+ qsizetype from = 0,
+ QRegularExpressionMatch *rmatch = nullptr);
[[nodiscard]] Q_CORE_EXPORT qsizetype indexOf(QStringView haystack,
const QRegularExpression &re,
qsizetype from = 0,
QRegularExpressionMatch *rmatch = nullptr);
+[[nodiscard]] qsizetype lastIndexOf(QStringView viewHaystack,
+ const QString *stringHaystack,
+ const QRegularExpression &re,
+ qsizetype from = -1,
+ QRegularExpressionMatch *rmatch = nullptr);
[[nodiscard]] Q_CORE_EXPORT qsizetype lastIndexOf(QStringView haystack,
const QRegularExpression &re,
qsizetype from = -1,
QRegularExpressionMatch *rmatch = nullptr);
+[[nodiscard]] bool contains(QStringView viewHaystack,
+ const QString *stringHaystack,
+ const QRegularExpression &re,
+ QRegularExpressionMatch *rmatch = nullptr);
[[nodiscard]] Q_CORE_EXPORT bool contains(QStringView haystack,
const QRegularExpression &re,
QRegularExpressionMatch *rmatch = nullptr);
@@ -98,7 +128,73 @@ namespace QtPrivate {
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isLatin1(QStringView s) noexcept;
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isValidUtf16(QStringView s) noexcept;
-} // namespace QtPRivate
+template <typename Char, size_t N> [[nodiscard]] constexpr Q_ALWAYS_INLINE
+qsizetype lengthHelperContainerLoop(const Char (&str)[N])
+{
+#if defined(__cpp_lib_constexpr_algorithms) && defined(Q_CC_GNU_ONLY)
+ // libstdc++'s std::find / std::find_if manages to execute more steps
+ // than the loop below
+ const auto it = std::find(str, str + N, Char(0));
+ return it - str;
+#else
+ // std::char_traits<C> is deprecated for C not one of the standard char
+ // types, so we have to roll out our own loop.
+ for (size_t i = 0; i < N; ++i) {
+ if (str[i] == Char(0))
+ return qsizetype(i);
+ }
+ return qsizetype(N);
+#endif
+}
+
+template <typename Char, size_t N> [[nodiscard]] constexpr Q_ALWAYS_INLINE
+std::enable_if_t<sizeof(Char) == sizeof(char16_t), qsizetype>
+lengthHelperContainer(const Char (&str)[N])
+{
+ // The following values were empirically determined to detect the threshold
+ // at which the compiler gives up pre-calculating the std::find() below and
+ // instead inserts code to be executed at runtime.
+ constexpr size_t RuntimeThreshold =
+#if defined(Q_CC_CLANG)
+ // tested on Clang 15, 16 & 17
+ 1023
+#elif defined(Q_CC_GNU)
+ // tested through GCC 13.1 at -O3 compilation level
+ // note: at -O2, GCC always generates a loop!
+ __cplusplus >= 202002L ? 39 : 17
+#else
+ 0
+#endif
+ ;
+ if constexpr (N == 1) {
+ return str[0] == Char(0) ? 0 : 1;
+ } else if constexpr (N > RuntimeThreshold) {
+#ifdef QT_SUPPORTS_IS_CONSTANT_EVALUATED
+ if (!q20::is_constant_evaluated())
+ return QtPrivate::qustrnlen(reinterpret_cast<const char16_t *>(str), N);
+#endif
+ }
+
+ return lengthHelperContainerLoop(str);
+}
+
+template <typename Char, size_t N> [[nodiscard]] constexpr inline
+std::enable_if_t<sizeof(Char) == 1, qsizetype> lengthHelperContainer(const Char (&str)[N])
+{
+#ifdef QT_SUPPORTS_IS_CONSTANT_EVALUATED
+ if (!q20::is_constant_evaluated())
+ return qstrnlen(reinterpret_cast<const char *>(str), N);
+#endif
+
+ return lengthHelperContainerLoop(str);
+}
+
+template <typename Container>
+constexpr qsizetype lengthHelperContainer(const Container &c) noexcept
+{
+ return qsizetype(std::size(c));
+}
+} // namespace QtPrivate
QT_END_NAMESPACE