From 107ff4c1d6b5da2cb11c65b2bd9106817f7fdb02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 16 Sep 2020 12:04:31 +0200 Subject: Q(Any|Utf8)StringView: move array size deduction feature to fromArray The constructor taking an array literal will now stop at the first null-terminator encountered. And fromArray is introduced which only supports array literals. Constructs a view of the full size. Explicit so it shouldn't be surprising. Change-Id: I1497c33a5c12453a95e87c990abe6335b2817081 Reviewed-by: Andrei Golubev Reviewed-by: Lars Knoll --- .../code/src_corelib_text_qanystringview.cpp | 4 +-- .../snippets/code/src_corelib_text_qstringview.cpp | 4 --- .../code/src_corelib_text_qutf8stringview.cpp | 5 ---- src/corelib/text/qanystringview.h | 10 ++++++-- src/corelib/text/qanystringview.qdoc | 29 ++++++++++++++++++---- src/corelib/text/qstringview.cpp | 29 ++++++++++++++++++---- src/corelib/text/qstringview.h | 10 ++++++-- src/corelib/text/qutf8stringview.h | 10 ++++++-- src/corelib/text/qutf8stringview.qdoc | 28 +++++++++++++++++---- 9 files changed, 97 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/corelib/doc/snippets/code/src_corelib_text_qanystringview.cpp b/src/corelib/doc/snippets/code/src_corelib_text_qanystringview.cpp index 745e5e7e10..de5c511348 100644 --- a/src/corelib/doc/snippets/code/src_corelib_text_qanystringview.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_text_qanystringview.cpp @@ -54,6 +54,6 @@ //! [0] //! [2] - auto sv1 = QAnyStringView{std::begin(array), std::end(array)}; // using C++11 std::begin()/std::end() - auto sv2 = QAnyStringView(array, std::size(array)); // using C++17 std::size() + auto sv1 = QAnyStringView{std::begin(array), std::end(array) - 1}; // using C++11 std::begin()/std::end() + auto sv2 = QAnyStringView(array, std::size(array) - 1); // using C++17 std::size() //! [2] diff --git a/src/corelib/doc/snippets/code/src_corelib_text_qstringview.cpp b/src/corelib/doc/snippets/code/src_corelib_text_qstringview.cpp index fc426e1977..380e069b53 100644 --- a/src/corelib/doc/snippets/code/src_corelib_text_qstringview.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_text_qstringview.cpp @@ -56,7 +56,3 @@ //! [1] void fun(QChar ch) { fun(QStringView(&ch, 1)); } //! [1] - -//! [2] - auto sv = QStringView(array, std::size(array)); // using C++17 std::size() -//! [2] diff --git a/src/corelib/doc/snippets/code/src_corelib_text_qutf8stringview.cpp b/src/corelib/doc/snippets/code/src_corelib_text_qutf8stringview.cpp index b1033371b1..ba52e2d5c2 100644 --- a/src/corelib/doc/snippets/code/src_corelib_text_qutf8stringview.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_text_qutf8stringview.cpp @@ -52,8 +52,3 @@ void myfun1(QUtf8StringView sv); // preferred void myfun2(const QUtf8StringView &sv); // compiles and works, but slower //! [0] - -//! [2] - auto sv1 = QUtf8StringView{std::begin(array), std::end(array)}; // using C++11 std::begin()/std::end() - auto sv2 = QUtf8StringView(array, std::size(array)); // using C++17 std::size() -//! [2] diff --git a/src/corelib/text/qanystringview.h b/src/corelib/text/qanystringview.h index 61761c6a82..242efc6e5c 100644 --- a/src/corelib/text/qanystringview.h +++ b/src/corelib/text/qanystringview.h @@ -109,9 +109,11 @@ private: } template - static constexpr qsizetype lengthHelperContainer(const Char (&)[N]) noexcept + static constexpr qsizetype lengthHelperContainer(const Char (&str)[N]) noexcept { - return qsizetype(N - 1); + const auto it = std::char_traits::find(str, N, Char(0)); + const auto end = it ? it : std::next(str, N); + return qsizetype(std::distance(str, end)); } static QChar toQChar(char ch) noexcept { return toQChar(QLatin1Char{ch}); } // we don't handle UTF-8 multibytes @@ -180,6 +182,10 @@ public: constexpr QAnyStringView(QBasicUtf8StringView v) noexcept : QAnyStringView(std::data(v), lengthHelperContainer(v)) {} + template = true> + [[nodiscard]] constexpr static QAnyStringView fromArray(const Char (&string)[Size]) noexcept + { return QAnyStringView(string, Size); } + // defined in qstring.h: template inline constexpr decltype(auto) visit(Visitor &&v) const; diff --git a/src/corelib/text/qanystringview.qdoc b/src/corelib/text/qanystringview.qdoc index b3e8baa3f9..31b29fd7a7 100644 --- a/src/corelib/text/qanystringview.qdoc +++ b/src/corelib/text/qanystringview.qdoc @@ -197,11 +197,9 @@ \fn template QAnyStringView::QAnyStringView(const Char (&string)[N]) Constructs a string view on the character string literal \a string. - The length is set to \c{N-1}, excluding the trailing \c{Char(0)}. - If you need the full array, use the constructor from pointer and - size instead: - - \snippet code/src_corelib_text_qanystringview.cpp 2 + The view covers the array until the first \c{Char(0)} is encountered, + or \c N, whichever comes first. + If you need the full array, use fromArray() instead. \a string must remain valid for the lifetime of this string view object. @@ -250,6 +248,27 @@ \sa isNull(), isEmpty(), {Compatible Character Types} */ +/*! + \fn template static QAnyStringView fromArray(const Char (&string)[Size]) noexcept + + Constructs a string view on the full character string literal \a string, + including any trailing \c{Char(0)}. If you don't want the + null-terminator included in the view then you can use the constructor + overload taking a pointer and a size: + + \snippet code/src_corelib_text_qanystringview.cpp 2 + + Alternatively you can use the constructor overload taking an + array literal which will create a view up to, but not including, + the first null-terminator in the data. + + \a string must remain valid for the lifetime of this string view + object. + + This function will work with any array literal if \c Char is a + compatible character type. +*/ + /*! \fn QString QAnyStringView::toString() const diff --git a/src/corelib/text/qstringview.cpp b/src/corelib/text/qstringview.cpp index 971d2ffd7a..aeec699f7f 100644 --- a/src/corelib/text/qstringview.cpp +++ b/src/corelib/text/qstringview.cpp @@ -278,11 +278,9 @@ QT_BEGIN_NAMESPACE \fn template QStringView::QStringView(const Char (&string)[N]) Constructs a string view on the character string literal \a string. - The length is set to \c{N-1}, excluding the trailing \{Char(0)}. - If you need the full array, use the constructor from pointer and - size instead: - - \snippet code/src_corelib_text_qstringview.cpp 2 + The view covers the array until the first \c{Char(0)} is encountered, + or \c N, whichever comes first. + If you need the full array, use fromArray() instead. \a string must remain valid for the lifetime of this string view object. @@ -292,6 +290,8 @@ QT_BEGIN_NAMESPACE type. The compatible character types are: \c QChar, \c ushort, \c char16_t and (on platforms, such as Windows, where it is a 16-bit type) \c wchar_t. + + \sa fromArray */ /*! @@ -323,6 +323,25 @@ QT_BEGIN_NAMESPACE \sa isNull(), isEmpty() */ +/*! + \fn template static QStringView fromArray(const Char (&string)[Size]) noexcept + + Constructs a string view on the full character string literal \a string, + including any trailing \c{Char(0)}. If you don't want the + null-terminator included in the view then you can chop() it off + when you are certain it is at the end. Alternatively you can use + the constructor overload taking an array literal which will create + a view up to, but not including, the first null-terminator in the data. + + \a string must remain valid for the lifetime of this string view + object. + + This function will work with any array literal if \c Char is a + compatible character type. The compatible character types are: \c QChar, \c ushort, \c + char16_t and (on platforms, such as Windows, where it is a 16-bit + type) \c wchar_t. +*/ + /*! \fn QString QStringView::toString() const diff --git a/src/corelib/text/qstringview.h b/src/corelib/text/qstringview.h index f88871ff5d..a4d0a78e5b 100644 --- a/src/corelib/text/qstringview.h +++ b/src/corelib/text/qstringview.h @@ -172,9 +172,11 @@ private: } template - static constexpr qsizetype lengthHelperContainer(const Char (&)[N]) noexcept + static constexpr qsizetype lengthHelperContainer(const Char (&str)[N]) noexcept { - return qsizetype(N - 1); + const auto it = std::char_traits::find(str, N, Char(0)); + const auto end = it ? it : std::next(str, N); + return qsizetype(std::distance(str, end)); } template @@ -223,6 +225,10 @@ public: constexpr QStringView(const Container &c) noexcept : QStringView(std::data(c), lengthHelperContainer(c)) {} + template = true> + [[nodiscard]] constexpr static QStringView fromArray(const Char (&string)[Size]) noexcept + { return QStringView(string, Size); } + Q_REQUIRED_RESULT inline QString toString() const; // defined in qstring.h #if defined(Q_OS_DARWIN) || defined(Q_QDOC) // defined in qcore_foundation.mm diff --git a/src/corelib/text/qutf8stringview.h b/src/corelib/text/qutf8stringview.h index a197d14a63..ac42a3d73f 100644 --- a/src/corelib/text/qutf8stringview.h +++ b/src/corelib/text/qutf8stringview.h @@ -160,9 +160,11 @@ private: // Note: Do not replace with std::size(const Char (&)[N]), cause the result // will be of by one. template - static constexpr qsizetype lengthHelperContainer(const Char (&)[N]) noexcept + static constexpr qsizetype lengthHelperContainer(const Char (&str)[N]) noexcept { - return qsizetype(N - 1); + const auto it = std::char_traits::find(str, N, Char(0)); + const auto end = it ? it : std::next(str, N); + return qsizetype(std::distance(str, end)); } template @@ -216,6 +218,10 @@ public: : QBasicUtf8StringView(other.data(), other.size()) {} #endif + template = true> + [[nodiscard]] constexpr static QBasicUtf8StringView fromArray(const Char (&string)[Size]) noexcept + { return QBasicUtf8StringView(string, Size); } + [[nodiscard]] inline QString toString() const; // defined in qstring.h [[nodiscard]] constexpr qsizetype size() const noexcept { return m_size; } diff --git a/src/corelib/text/qutf8stringview.qdoc b/src/corelib/text/qutf8stringview.qdoc index 9c0c620d88..031769440c 100644 --- a/src/corelib/text/qutf8stringview.qdoc +++ b/src/corelib/text/qutf8stringview.qdoc @@ -318,11 +318,9 @@ \fn template QUtf8StringView::QUtf8StringView(const Char (&string)[N]) Constructs a string view on the character string literal \a string. - The length is set to \c{N-1}, excluding the trailing \c{Char(0)}. - If you need the full array, use the constructor from pointer and - size instead: - - \snippet code/src_corelib_text_qutf8stringview.cpp 2 + The view covers the array until the first \c{Char(0)} is encountered, + or \c N, whichever comes first. + If you need the full array, use fromArray() instead. \a string must remain valid for the lifetime of this string view object. @@ -331,6 +329,8 @@ is an actual array and if \c Char is a compatible character type. The compatible character types are: \c char8_t, \c char, \c{signed char} and \c{unsigned char}. + + \sa fromArray */ /*! @@ -352,6 +352,24 @@ \sa isNull(), isEmpty() */ +/*! + \fn template static QBasicUtf8StringView fromArray(const Char (&string)[Size]) + + Constructs a string view on the full character string literal \a string, + including any trailing \c{Char(0)}. If you don't want the + null-terminator included in the view then you can chop() it off + when you are certain it is at the end. Alternatively you can use + the constructor overload taking an array literal which will create + a view up to, but not including, the first null-terminator in the data. + + \a string must remain valid for the lifetime of this string view + object. + + This function will work with any array literal if \c Char is a + compatible character type. The compatible character types + are: \c char8_t, \c char, \c{signed char} and \c{unsigned char}. +*/ + /*! \fn QString QUtf8StringView::toString() const -- cgit v1.2.3