QStringView: stop instantiating std::char_traits<QChar> and <uchar>

It's deprecated and will be removed with LLVM 19.

Amends b1ee49b46533d39f7fabda68d0bd08a1ab130a27.

Change-Id: I5dd50a1a7ca5424d9e7afffd17ad07b3ab3fc18a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit dc2ae08e02730ab795445bc047221aa56914f723)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Thiago Macieira 2024-01-23 08:45:02 -08:00 committed by Qt Cherry-pick Bot
parent 5f4c74f045
commit 20c44b7bac

View File

@ -4,15 +4,17 @@
#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 <string> // std::char_traits
#include <string.h> // for memchr
QT_BEGIN_NAMESPACE
@ -121,6 +123,25 @@ 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;
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])
@ -129,9 +150,12 @@ lengthHelperContainer(const Char (&str)[N])
// 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 through Clang 16.0.0
100
#elif defined(Q_CC_GNU) // tested through GCC 13.1 at -O3 compilation level
#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
@ -146,24 +170,18 @@ lengthHelperContainer(const Char (&str)[N])
#endif
}
// libstdc++'s std::find_if yields a higher threshold than
// std::char_traits::find
#if __cplusplus >= 202002 && defined(__cpp_lib_constexpr_algorithms)
const auto it = std::find(str, str + N, Char(0));
return it - str;
#else
const auto it = std::char_traits<Char>::find(str, N, Char(0));
return it ? std::distance(str, it) : ptrdiff_t(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])
{
// std::char_traits::find will call memchr or __builtin_memchr for us
const auto it = std::char_traits<Char>::find(str, N, Char(0));
return it ? std::distance(str, it) : ptrdiff_t(N);
#ifdef QT_SUPPORTS_IS_CONSTANT_EVALUATED
if (!qIsConstantEvaluated())
return qstrnlen(reinterpret_cast<const char *>(str), N);
#endif
return lengthHelperContainerLoop(str);
}
template <typename Container>