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:
parent
5f4c74f045
commit
20c44b7bac
@ -4,15 +4,17 @@
|
|||||||
#ifndef QSTRINGALGORITHMS_H
|
#ifndef QSTRINGALGORITHMS_H
|
||||||
#define QSTRINGALGORITHMS_H
|
#define QSTRINGALGORITHMS_H
|
||||||
|
|
||||||
|
#include <QtCore/qbytearrayalgorithms.h>
|
||||||
|
#include <QtCore/qcontainerfwd.h>
|
||||||
#include <QtCore/qnamespace.h>
|
#include <QtCore/qnamespace.h>
|
||||||
#include <QtCore/qstringfwd.h>
|
#include <QtCore/qstringfwd.h>
|
||||||
#include <QtCore/qcontainerfwd.h>
|
|
||||||
#if 0
|
#if 0
|
||||||
#pragma qt_class(QStringAlgorithms)
|
#pragma qt_class(QStringAlgorithms)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <algorithm> // std::find
|
#include <algorithm> // std::find
|
||||||
#include <string> // std::char_traits
|
|
||||||
|
#include <string.h> // for memchr
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
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 isLatin1(QStringView s) noexcept;
|
||||||
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isValidUtf16(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
|
template <typename Char, size_t N> [[nodiscard]] constexpr Q_ALWAYS_INLINE
|
||||||
std::enable_if_t<sizeof(Char) == sizeof(char16_t), qsizetype>
|
std::enable_if_t<sizeof(Char) == sizeof(char16_t), qsizetype>
|
||||||
lengthHelperContainer(const Char (&str)[N])
|
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
|
// at which the compiler gives up pre-calculating the std::find() below and
|
||||||
// instead inserts code to be executed at runtime.
|
// instead inserts code to be executed at runtime.
|
||||||
constexpr size_t RuntimeThreshold =
|
constexpr size_t RuntimeThreshold =
|
||||||
#if defined(Q_CC_CLANG) // tested through Clang 16.0.0
|
#if defined(Q_CC_CLANG)
|
||||||
100
|
// tested on Clang 15, 16 & 17
|
||||||
#elif defined(Q_CC_GNU) // tested through GCC 13.1 at -O3 compilation level
|
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
|
__cplusplus >= 202002L ? 39 : 17
|
||||||
#else
|
#else
|
||||||
0
|
0
|
||||||
@ -146,24 +170,18 @@ lengthHelperContainer(const Char (&str)[N])
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// libstdc++'s std::find_if yields a higher threshold than
|
return lengthHelperContainerLoop(str);
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char, size_t N> [[nodiscard]] constexpr inline
|
template <typename Char, size_t N> [[nodiscard]] constexpr inline
|
||||||
std::enable_if_t<sizeof(Char) == 1, qsizetype> lengthHelperContainer(const Char (&str)[N])
|
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
|
#ifdef QT_SUPPORTS_IS_CONSTANT_EVALUATED
|
||||||
const auto it = std::char_traits<Char>::find(str, N, Char(0));
|
if (!qIsConstantEvaluated())
|
||||||
return it ? std::distance(str, it) : ptrdiff_t(N);
|
return qstrnlen(reinterpret_cast<const char *>(str), N);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return lengthHelperContainerLoop(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user