diff options
author | Karsten Heimrich <karsten.heimrich@qt.io> | 2020-10-21 15:24:10 +0200 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@qt.io> | 2020-10-27 12:49:40 +0100 |
commit | 626a9b66f2b9f8a7e3977bee32afa64778b6b8f2 (patch) | |
tree | bbb8255f331bd1b6bc3759768d067bc103ec8417 | |
parent | 5c352f47b977c72db323bb8e7b6ac25e1a453202 (diff) |
Doc: Add notes on how to use View classes in Qt6
Task-number: QTBUG-87168
Change-Id: I631937ebaf7cfa3ed54c6c8a3641693fda910b36
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
-rw-r--r-- | src/corelib/doc/src/qt6-changes.qdoc | 130 | ||||
-rw-r--r-- | src/corelib/text/qanystringview.qdoc | 4 | ||||
-rw-r--r-- | src/corelib/text/qutf8stringview.qdoc | 8 |
3 files changed, 136 insertions, 6 deletions
diff --git a/src/corelib/doc/src/qt6-changes.qdoc b/src/corelib/doc/src/qt6-changes.qdoc index d04c74efe8..69208a2628 100644 --- a/src/corelib/doc/src/qt6-changes.qdoc +++ b/src/corelib/doc/src/qt6-changes.qdoc @@ -247,6 +247,136 @@ Other methods of QtConcurrent have no behavioral changes and do not introduce source compatibility breaks. + \section1 View classes in Qt6 + + \section2 General Overview + + There are several new \c View classes coming with Qt6. There is the already + existing \l QStringView, now accompanied by \l QByteArrayView and followed + by a specialized \l QUtf8StringView and a more universal \l QAnyStringView. + + \section2 Introduction to view classes on the example of QStringView + + The QStringView class provides a unified view on UTF-16 strings with a + read-only subset of the QString API. Unlike QString, which keeps its own + copy of the string (possibly ref-counted), QStringView provides a view of + a string that is stored elsewhere. + + \code + char hello[]{ "Hello." }; // narrow multi-byte string literal + QString str{hello}; // needs to make a copy of the string literal + QString strToStr(str); // atomic increment involved to not create a copy of hello again + + // The above code can be re-written to avoid copying and atomic increment. + + QStringView view{ u"Hello." }; // view to UTF-16 encoded string literal + QStringView viewToView{ view }; // view of the same UTF-16 encoded string literal + \endcode + + The string \c "Hello." is stored in the binary and is not allocated at + run-time. \c view is only a view onto the string \c "Hello.", therefore + no copy has to be created. When we copy a QStringView, the \c viewToView + observes the same string as the copied-from \c view is observing. This + means that \c viewToView does not need to create a copy or an atomic + increment. They are views onto the existing string \c "Hello.". + + \section2 Views as function argument + + Views should be passed by value, not by reference-to-const. + + \code + void myfun1(QStringView sv); // preferred + void myfun2(const QStringView &sv); // compiles and works, but slower + \endcode + + \section2 View manipulation functions + + QStringView supports functions that let us manipulate the view of the + string. This allows us to change the view without creating a partial copy + of the viewed string. + + \code + QString pineapple = "Pineapple"; + QString pine = pineapple.left(4); + + // The above code can be re-written to avoid creating a partial copy. + + QStringView pineappleView{ pineapple }; + QStringView pineView = pineappleView.left(4); + \endcode + + \section2 Non null-terminated strings and strings containing \c {'\0'} + + QStringView supports both null-terminated and non null-terminated strings. + The difference comes from the way you initialize the QStringView: + + \code + QChar aToE[]{ 'a', 'b', 'c', 'd', 'e' }; + + QStringView nonNull{ aToE, std::size(aToE) }; // with length given + QStringView nonNull{ aToE }; // automatically determines the length + + QChar fToJ[]{ 'f', 'g', 'h', '\0', 'j' }; + + // uses given length, doesn't search for '\0', so '\0' at position 3 + // is considered to be a part of the string similarly to 'h' and 'j + QStringView nonNull{ fToJ, std::size(fToJ) }; + QStringView part{ fToJ }; //stops on the first encounter of '\0' + \endcode + + \section2 Ownership model of views + + As \c views do not own the memory they reference, care must be taken to + ensure that the referenced data (for example, owned by a \l QString) + outlives the \c view on all code paths. + + \badcode + QStringView sayHello() + { + QString hello("Hello."); + return QStringView{ hello }; // hello gets out of scope and destroyed + } + + void main() + { + QStringView hello{ sayHello() }; + qDebug() << hello; // undefined behavior + } + \endcode + + \section2 Converting an QStringView to QString + + QStringView will not implicitly or explicitly convert to a QString, but can + create a deep copy of its data: + + \code + void print(const QString &s) { qDebug() << s; } + + void main() + { + QStringView string{ u"string"}; + + // print(string); // invalid, no implicit conversion + // QString str{ string }; // invalid, no explicit conversion + + print(string.toString()); + QString str = string.toString(); // create QString from view + } + \endcode + + \section2 Important notes + + By leveraging the new view classes, one can achieve a lot of performance + boost in many use cases. However, it is important to know that there might + be some caveats. Therefore it is important to remember: + + \list + \li Views should be passed by value, not by reference-to-const. + \li Constructing a view with a negative length is undefined behavior. + \li Care must be taken to ensure that the referenced data (for example, + owned by a \l QString) outlives the view on all code paths. + \endlist + \section1 String related classes \section2 QStringView diff --git a/src/corelib/text/qanystringview.qdoc b/src/corelib/text/qanystringview.qdoc index f15f89d636..096eea821c 100644 --- a/src/corelib/text/qanystringview.qdoc +++ b/src/corelib/text/qanystringview.qdoc @@ -83,7 +83,7 @@ QAnyStringView is a \e{Literal Type}. - \section Compatible Character Types + \section2 Compatible Character Types QAnyStringView accepts strings over a variety of character types: @@ -100,7 +100,7 @@ presented as a QLatin1String) while the 16-bit character types are interpreted as UTF-16 data in host byte order (the same as QString). - \section Sizes and Sub-Strings + \section2 Sizes and Sub-Strings All sizes and positions in QAnyStringView functions are in the encoding's code points (that is, UTF-16 surrogate pairs count as diff --git a/src/corelib/text/qutf8stringview.qdoc b/src/corelib/text/qutf8stringview.qdoc index 031769440c..a5f05a8fb4 100644 --- a/src/corelib/text/qutf8stringview.qdoc +++ b/src/corelib/text/qutf8stringview.qdoc @@ -77,7 +77,7 @@ QUtf8StringView is a \e{Literal Type}. - \section Compatible Character Types + \section2 Compatible Character Types QUtf8StringView accepts strings over a variety of character types: @@ -86,16 +86,16 @@ \li \c char8_t (C++20 only) \endlist - \section Sizes and Sub-Strings + \section2 Sizes and Sub-Strings - All sizes and postions in QUtf8StringView functions are in + All sizes and positions in QUtf8StringView functions are in UTF-8 code points (that is, UTF-8 multibyte sequences count as two, three or four, depending on their length). QUtf8StringView does not an attempt to detect or prevent slicing right through UTF-8 multibyte sequences. This is similar to the situation with QStringView and surrogate pairs. - \section C++20, char8_t, and QUtf8StringView + \section2 C++20, char8_t, and QUtf8StringView In C++20, \c{u8""} string literals changed their type from \c{const char[]} to \c{const char8_t[]}. If Qt 6 could have depended |