From 84467d70a831eea78f288f76fff91c5def01f14f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 27 Jan 2025 16:54:58 -0800 Subject: [PATCH] QByteArray/QList/QString: mark size() constexpr and always in-range Using the C++20 [[assume]] attribute, which GCC and Clang support in C++17 mode too. This may help the compiler generate slightly better code, avoiding the need to check if the size is negative or overflows. I've also marked count() and length() as constexpr. Change-Id: Ida6c9a7ba67574a952f3fffd44dea52a0e0e61c2 Reviewed-by: Marc Mutz --- src/corelib/text/qbytearray.h | 13 ++++++++++--- src/corelib/text/qstring.h | 13 ++++++++++--- src/corelib/tools/qlist.h | 13 ++++++++++--- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/corelib/text/qbytearray.h b/src/corelib/text/qbytearray.h index 1e1a8c9c5e4..b7b33fa3ac1 100644 --- a/src/corelib/text/qbytearray.h +++ b/src/corelib/text/qbytearray.h @@ -495,12 +495,19 @@ public: // -1 to deal with the NUL terminator return Data::maxSize() - 1; } - inline qsizetype size() const noexcept { return d.size; } + constexpr qsizetype size() const noexcept + { +#if __has_cpp_attribute(assume) + constexpr size_t MaxSize = maxSize(); + [[assume(size_t(d.size) <= MaxSize)]]; +#endif + return d.size; + } #if QT_DEPRECATED_SINCE(6, 4) QT_DEPRECATED_VERSION_X_6_4("Use size() or length() instead.") - inline qsizetype count() const noexcept { return size(); } + constexpr qsizetype count() const noexcept { return size(); } #endif - inline qsizetype length() const noexcept { return size(); } + constexpr qsizetype length() const noexcept { return size(); } QT_CORE_INLINE_SINCE(6, 4) bool isNull() const noexcept; diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h index b36ac709a2c..c1875688a48 100644 --- a/src/corelib/text/qstring.h +++ b/src/corelib/text/qstring.h @@ -232,12 +232,19 @@ public: // -1 to deal with the NUL terminator return Data::maxSize() - 1; } - inline qsizetype size() const noexcept { return d.size; } + constexpr qsizetype size() const noexcept + { +#if __has_cpp_attribute(assume) + constexpr size_t MaxSize = maxSize(); + [[assume(size_t(d.size) <= MaxSize)]]; +#endif + return d.size; + } #if QT_DEPRECATED_SINCE(6, 4) QT_DEPRECATED_VERSION_X_6_4("Use size() or length() instead.") - inline qsizetype count() const { return d.size; } + constexpr qsizetype count() const { return size(); } #endif - inline qsizetype length() const noexcept { return d.size; } + constexpr qsizetype length() const noexcept { return size(); } inline bool isEmpty() const noexcept { return d.size == 0; } void resize(qsizetype size); void resize(qsizetype size, QChar fillChar); diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 81139c5891b..c9b931e420a 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -438,9 +438,16 @@ public: #endif // Q_QDOC static constexpr qsizetype maxSize() { return Data::maxSize(); } - qsizetype size() const noexcept { return d->size; } - qsizetype count() const noexcept { return size(); } - qsizetype length() const noexcept { return size(); } + constexpr qsizetype size() const noexcept + { +#if __has_cpp_attribute(assume) + constexpr size_t MaxSize = maxSize(); + [[assume(size_t(d.size) <= MaxSize)]]; +#endif + return d.size; + } + constexpr qsizetype count() const noexcept { return size(); } + constexpr qsizetype length() const noexcept { return size(); } inline bool isEmpty() const noexcept { return d->size == 0; }