summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_text_qanystringview.cpp4
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_text_qstringview.cpp4
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_text_qutf8stringview.cpp5
-rw-r--r--src/corelib/text/qanystringview.h10
-rw-r--r--src/corelib/text/qanystringview.qdoc29
-rw-r--r--src/corelib/text/qstringview.cpp29
-rw-r--r--src/corelib/text/qstringview.h10
-rw-r--r--src/corelib/text/qutf8stringview.h10
-rw-r--r--src/corelib/text/qutf8stringview.qdoc28
-rw-r--r--tests/auto/corelib/text/qstringview/tst_qstringview.cpp34
10 files changed, 130 insertions, 33 deletions
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 <typename Char, size_t N>
- 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<Char>::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<UseChar8T> v) noexcept
: QAnyStringView(std::data(v), lengthHelperContainer(v)) {}
+ template <typename Char, size_t Size, if_compatible_char<Char> = true>
+ [[nodiscard]] constexpr static QAnyStringView fromArray(const Char (&string)[Size]) noexcept
+ { return QAnyStringView(string, Size); }
+
// defined in qstring.h:
template <typename Visitor>
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 <typename Char, size_t N> 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.
@@ -251,6 +249,27 @@
*/
/*!
+ \fn template <typename Char, size_t Size> 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
Returns a deep copy of this string view's data as a QString.
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 <typename Char, size_t N> 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
*/
/*!
@@ -324,6 +324,25 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn template <typename Char, size_t Size> 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
Returns a deep copy of this string view's data as a QString.
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 <typename Char, size_t N>
- 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<Char>::find(str, N, Char(0));
+ const auto end = it ? it : std::next(str, N);
+ return qsizetype(std::distance(str, end));
}
template <typename Char>
@@ -223,6 +225,10 @@ public:
constexpr QStringView(const Container &c) noexcept
: QStringView(std::data(c), lengthHelperContainer(c)) {}
+ template <typename Char, size_t Size, if_compatible_char<Char> = 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 <typename Char, size_t N>
- 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<Char>::find(str, N, Char(0));
+ const auto end = it ? it : std::next(str, N);
+ return qsizetype(std::distance(str, end));
}
template <typename Char>
@@ -216,6 +218,10 @@ public:
: QBasicUtf8StringView(other.data(), other.size()) {}
#endif
+ template <typename Char, size_t Size, if_compatible_char<Char> = 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 <typename Char, size_t N> 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
*/
/*!
@@ -353,6 +353,24 @@
*/
/*!
+ \fn template <typename Char, size_t Size> 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
Returns a deep copy of this string view's data as a QString.
diff --git a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp
index bf3454e028..b08d9ce8d9 100644
--- a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp
+++ b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp
@@ -157,6 +157,7 @@ private Q_SLOTS:
void constExpr() const;
void basics() const;
void literals() const;
+ void fromArray() const;
void at() const;
void arg() const;
@@ -425,10 +426,41 @@ void tst_QStringView::literals() const
}
// these are different results
- QCOMPARE(size_t(QStringView(withnull).size()), sizeof(withnull)/sizeof(withnull[0]) - 1);
+ QCOMPARE(size_t(QStringView(withnull).size()), 1);
+ QCOMPARE(size_t(QStringView::fromArray(withnull).size()), sizeof(withnull)/sizeof(withnull[0]));
QCOMPARE(QStringView(withnull + 0).size(), 1);
}
+void tst_QStringView::fromArray() const
+{
+ static constexpr char16_t hello[] = u"Hello\0abc\0\0.";
+
+ constexpr QStringView sv = QStringView::fromArray(hello);
+ QCOMPARE(sv.size(), 13);
+ QVERIFY(!sv.empty());
+ QVERIFY(!sv.isEmpty());
+ QVERIFY(!sv.isNull());
+ QCOMPARE(*sv.data(), 'H');
+ QCOMPARE(sv[0], 'H');
+ QCOMPARE(sv.at(0), 'H');
+ QCOMPARE(sv.front(), 'H');
+ QCOMPARE(sv.first(), 'H');
+ QCOMPARE(sv[4], 'o');
+ QCOMPARE(sv.at(4), 'o');
+ QCOMPARE(sv[5], '\0');
+ QCOMPARE(sv.at(5), '\0');
+ QCOMPARE(*(sv.data() + sv.size() - 2), '.');
+ QCOMPARE(sv.back(), '\0');
+ QCOMPARE(sv.last(), '\0');
+
+ const char16_t bytes[] = {u'a', u'b', u'c'};
+ QStringView sv2 = QStringView::fromArray(bytes);
+ QCOMPARE(sv2.data(), reinterpret_cast<const QChar *>(bytes + 0));
+ QCOMPARE(sv2.size(), 3);
+ QCOMPARE(sv2.first(), u'a');
+ QCOMPARE(sv2.last(), u'c');
+}
+
void tst_QStringView::at() const
{
QString hello("Hello");