[Development] RFC: Proposal for a semi-radical change in Qt APIs taking strings

Smith Martin Martin.Smith at theqtcompany.com
Sun Oct 18 20:30:40 CEST 2015


After watching the video on string_view, it seems clear we have to offer a QStringView, so I don't see what is "semi-radical" about your proposal.

martin

________________________________________
From: development-bounces+martin.smith=theqtcompany.com at qt-project.org <development-bounces+martin.smith=theqtcompany.com at qt-project.org> on behalf of Marc Mutz <marc.mutz at kdab.com>
Sent: Tuesday, October 13, 2015 10:46 PM
To: development at qt-project.org
Subject: [Development] RFC: Proposal for a semi-radical change in Qt APIs       taking strings

Hi,

After looking quite a bit into the current state of string handling in Qt for
my QtWS talk last week, I have become frustrated by the state of string
handling in Qt.

We have such powerful tools for string handling (QStringRef, QStringBuilder),
but all APIs outside QString and its immediate surroundings only deal in
QString. The correct way would be to overload every function taking QString
with QLatin1String and QStringRef versions, and then, for some other rare
cases, const QChar *, int size. Let alone std::basic_string<char16_t>.

I would therefore like to propose to abandon QString for new API (and over
time phase it out of existing API), and only provide (const QChar*, size_t) as
the most general form. I would propose to package the two into a class, called
- you guessed it - QStringView.

=FAQ=

Q: Why not just use QStringRef?

A: QStringRef is tied to QString. E.g. you can't create a QStringRef from a
pair of QChar*, int. It also is kind of stuck in historic mistakes making it
undesireable as a cheap-to-pass parameter type.

Q: What mistakes do you refer to?

A: The fact that it has copy ctor and assignment operator, so it's not a
trivally-copyable type and thus cannot efficiently passed by-value. It may also
be too large for pass-by-value due to the rather useless QString pointer
(should have been QStringData*, if any). Neither can be fixed before Qt 6.

Q: Why size_t?

A: The intent of QStringView (and std::experimental::string_view) is to act as
an interface between modules written with different compilers and different
flags. A std::string will never be compatible between compilers or even just
different flags, but a simple struct {char*, size_t} will always be, by way of
it's C compatibility.

So the goal is not just to accept QString, QStringRef, and (QChar*,int) (and
QVarLengthArray<QChar>!) as input to QStringView, but also
std::basic_string<char16_t> and std::vector<char16_t>.

Q: What about the plans to make QString UTF-8-backed?

A: QStringView-using code will need to be ported just as QString-using code
will.

Q: What future do you have in mind for QStringRef?

A: None in particular, though I have found a need for an owning QStringRef in
some places. But I expect Qt 6' QString to be able to provide a restricted
view on shared data, such that it would subsume QStringRef completely.

Q: What about QLatin1String?

A: Once QString is backed by UTF-8, latin-1 ceases to be a special charset. We
might want something like QUsAsciiString, but it would just be a UTF-8 string,
so it could be packed into QStringView.

Q: What about QByteArray, QVector?

A: I'm unsure about QByteArrayView. It might not pull its weight compared to
std::(experimental::)string_view, but I also note that we're currently missing
a QByteArrayRef, so a QBAView might make sense while we wait for the std one
to become available to us.

I'm actively opposed to a QArrayView, because I don't think it provides us
with anything std::(experimental::)array_view doesn't already.

Q: What about a rope?

A: A rope is a more complex string that can provide complex views on existing
data as well as store rules for generating stretches of data (as opposed to
the data itself).

A rope is a very complex data structure and would not work as a universal
interface type. It would be cool if Qt had a rope, but that is outside the
scope of my proposal.

Q: What do you mean when you say "abandon QString"?

A: I mean that functions should not take QStrings as arguments, but
QStringViews. Then users can transparently pass QString, QStringRef and any of
a number of other "string" types without overloading the function on each of
them.

I do not mean to abandon QString, the class. Only QString, the interface type.

Q: What API should QStringView have?

A: Since it's mainly an interface type, it should have implicit conversions
from all kinds of "string" types, but explicit conversion _to_ those string
types. It should carry all the API from QString that can be implemented on
just a (QChar*, size_t) (e.g. trimmed(), left(), mid(), section(), split(),
but not append(), replace() (except maybe the (QChar,QChar) overload.
Corresponding QString/Ref API could (eventually) just forward to the
QStringView one.

Thanks, now fire away,
Marc

--
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt Experts
_______________________________________________
Development mailing list
Development at qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


More information about the Development mailing list