QByteArrayView: inline the char overload of lastIndexOf()
It's just memrchr()... which unfortunately is a GNU extension (picked by FreeBSD and OpenBSD too), so we need to provide a fallback implementation for other OSes and bootstrap mode. By creating a new overload instead of doing the inlining trick, this gets inlined in QtCore uses as well and has a simpler #ifdef'ery. We still reach the C library function indirectly, but that's going to be minimal (and unavoidable) overhead, more than offset by the gain in accessing an optimized memrchr(). Change-Id: If05cb740b64f42eba21efffd17d0b681bcfe9cf3 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
This commit is contained in:
parent
5bf0c3d5d3
commit
4c12ae7e67
@ -954,6 +954,15 @@ bool QPersistentModelIndex::operator!=(const QModelIndex &other) const noexcept
|
||||
|
||||
#include "qbytearray.h" // inlined API
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace QtPrivate {
|
||||
Q_CORE_EXPORT qsizetype lastIndexOf(QByteArrayView haystack, qsizetype from, char needle) noexcept
|
||||
{
|
||||
return lastIndexOf(haystack, from, uchar(needle));
|
||||
}
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "qcborarray.h" // inlined API
|
||||
|
||||
#include "qcbormap.h" // inlined API
|
||||
|
@ -324,6 +324,21 @@ linkat(AT_FDCWD, \"foo\", AT_FDCWD, \"bar\", AT_SYMLINK_FOLLOW);
|
||||
}
|
||||
")
|
||||
|
||||
# memrchr
|
||||
qt_config_compile_test(memrchr
|
||||
LABEL "memrchr()"
|
||||
CODE
|
||||
"#define _BSD_SOURCE 1 /* For FreeBSD */
|
||||
#define _GNU_SOURCE 1 /* For glibc, Bionic */
|
||||
#include <string.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const void *r = memrchr(\"abc\", 'a', 3);
|
||||
(void)r;
|
||||
return 0;
|
||||
}")
|
||||
|
||||
# ppoll
|
||||
qt_config_compile_test(ppoll
|
||||
LABEL "ppoll()"
|
||||
@ -554,6 +569,10 @@ qt_feature("std-atomic64" PUBLIC
|
||||
LABEL "64 bit atomic operations"
|
||||
CONDITION WrapAtomic_FOUND
|
||||
)
|
||||
qt_feature("memrchr" PRIVATE
|
||||
LABEL "C library function memrchr()"
|
||||
CONDITION TEST_memrchr
|
||||
)
|
||||
qt_feature("mimetype" PUBLIC
|
||||
SECTION "Utilities"
|
||||
LABEL "Mimetype handling"
|
||||
|
@ -72,6 +72,7 @@
|
||||
# define QT_FEATURE_linkat -1
|
||||
#endif
|
||||
#define QT_FEATURE_lttng -1
|
||||
#define QT_FEATURE_memrchr -1
|
||||
#define QT_NO_QOBJECT
|
||||
#define QT_FEATURE_process -1
|
||||
#define QT_FEATURE_regularexpression 1
|
||||
|
@ -60,6 +60,30 @@ static constexpr inline uchar asciiLower(uchar c)
|
||||
Safe and portable C string functions; extensions to standard string.h
|
||||
*****************************************************************************/
|
||||
|
||||
/*! \relates QByteArray
|
||||
\internal
|
||||
|
||||
Wrapper around memrchr() for systems that don't have it. It's provided in
|
||||
every system because, as a GNU extension, memrchr() may not be declared in
|
||||
string.h depending on how strict the compiler was asked to be.
|
||||
|
||||
Used in QByteArrayView::lastIndexOf() overload for a single char.
|
||||
*/
|
||||
const void *qmemrchr(const void *s, int needle, size_t size) noexcept
|
||||
{
|
||||
#if QT_CONFIG(memrchr)
|
||||
return memrchr(s, needle, size);
|
||||
#endif
|
||||
auto b = static_cast<const char *>(s);
|
||||
const char *n = b + size;
|
||||
while (n-- != b) {
|
||||
if (*n == needle)
|
||||
return n;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
/*! \relates QByteArray
|
||||
|
||||
Returns a duplicate string.
|
||||
@ -2738,30 +2762,6 @@ static qsizetype lastIndexOfHelper(const char *haystack, qsizetype l, const char
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline qsizetype lastIndexOfCharHelper(QByteArrayView haystack, qsizetype from, char needle) noexcept
|
||||
{
|
||||
if (haystack.size() == 0)
|
||||
return -1;
|
||||
if (from < 0)
|
||||
from += haystack.size();
|
||||
else if (from > haystack.size())
|
||||
from = haystack.size() - 1;
|
||||
if (from >= 0) {
|
||||
const char *b = haystack.data();
|
||||
const char *n = b + from + 1;
|
||||
while (n-- != b) {
|
||||
if (*n == needle)
|
||||
return n - b;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
qsizetype QtPrivate::lastIndexOf(QByteArrayView haystack, qsizetype from, char needle) noexcept
|
||||
{
|
||||
return lastIndexOfCharHelper(haystack, from, needle);
|
||||
}
|
||||
|
||||
qsizetype QtPrivate::lastIndexOf(QByteArrayView haystack, qsizetype from, QByteArrayView needle) noexcept
|
||||
{
|
||||
if (haystack.isEmpty()) {
|
||||
@ -2771,7 +2771,7 @@ qsizetype QtPrivate::lastIndexOf(QByteArrayView haystack, qsizetype from, QByteA
|
||||
}
|
||||
const auto ol = needle.size();
|
||||
if (ol == 1)
|
||||
return lastIndexOfCharHelper(haystack, from, needle.front());
|
||||
return QtPrivate::lastIndexOf(haystack, from, needle.front());
|
||||
|
||||
return lastIndexOfHelper(haystack.data(), haystack.size(), needle.data(), ol, from);
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ qsizetype findByteArray(QByteArrayView haystack, qsizetype from, char needle) no
|
||||
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION
|
||||
qsizetype findByteArray(QByteArrayView haystack, qsizetype from, QByteArrayView needle) noexcept;
|
||||
|
||||
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION
|
||||
qsizetype lastIndexOf(QByteArrayView haystack, qsizetype from, char needle) noexcept;
|
||||
[[nodiscard]] inline Q_DECL_PURE_FUNCTION
|
||||
qsizetype lastIndexOf(QByteArrayView haystack, qsizetype from, uchar needle) noexcept;
|
||||
|
||||
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION
|
||||
qsizetype lastIndexOf(QByteArrayView haystack, qsizetype from, QByteArrayView needle) noexcept;
|
||||
@ -99,6 +99,8 @@ static inline T toIntegral(ByteArrayView data, bool *ok, int base)
|
||||
Safe and portable C string functions; extensions to standard string.h
|
||||
*****************************************************************************/
|
||||
|
||||
[[nodiscard]] Q_DECL_PURE_FUNCTION Q_CORE_EXPORT
|
||||
const void *qmemrchr(const void *s, int needle, size_t n) noexcept;
|
||||
Q_CORE_EXPORT char *qstrdup(const char *);
|
||||
|
||||
inline size_t qstrlen(const char *str)
|
||||
|
@ -401,6 +401,18 @@ qsizetype QtPrivate::findByteArray(QByteArrayView haystack, qsizetype from, char
|
||||
return -1;
|
||||
}
|
||||
|
||||
qsizetype QtPrivate::lastIndexOf(QByteArrayView haystack, qsizetype from, uchar needle) noexcept
|
||||
{
|
||||
if (from < 0)
|
||||
from = qMax(from + haystack.size(), qsizetype(0));
|
||||
else
|
||||
from = qMin(from, haystack.size() - 1);
|
||||
|
||||
const char *const b = haystack.data();
|
||||
const void *n = b ? qmemrchr(b, needle, from + 1) : nullptr;
|
||||
return n ? static_cast<const char *>(n) - b : -1;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBYTEARRAYVIEW_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user