On 2017-11-30 22:13, Thiago Macieira wrote:
On Thursday, 30 November 2017 12:08:45 PST Marc Mutz wrote:
Don't go off on a tangent here. I used concepts syntax to keep the
example simple. I can post with std::enable_if, if you prefer :)
Fair enough, I had not considered that.
Anyway, the point is the asymmetry of member functions.
u"Hello".compare(string) does not compile in C++ (it does in Java), so
everyone that wants to write a template like the op== above will have
to
re-invent qCompareStrings(). The Qt API rules stipulate that the
common
use case should be made simple (we do, we have member functions
whereever we can add them), but make the rest possible. And that's
where
qCompareStrings() come in. It makes the remaining 5% (random number)
possible.
Why does anyone besides us need to write the op== like above? We have
access
to QtPrivate::qCompareStrings, so we can write the comparisons to our
string
objects.
Once those operator<=> are there, what benefit is there in having the
API
public and documented?
The spaceship operator solves the problem for qCompareStrings(). One
could say we already have all relational operators for all combinations
of string-like objects to solve it for the user _now_, but
qCompareStrings(), like operator<=>() return the full information, while
relational operators only return a subset. You know that, I know. I'm
just mentioning it for completeness sake.
And we have more than qCompareStrings(). How does operator<=> help with
qFindString()/qIndexOf() (which is still missing)? Answer: it doesn't.
There's no infix notation for find-in-string. And there probably never
will be (fancy proposing operator=~, anyone?).
[...]
We all think we're smarter than the committee, yes. Maybe we are, but
swarm intelligence suggests otherwise.
To be clear: there's nothing wrong with adding constexpr where we can.
Constexpr string literals make a lot of sense.
The flaw is in doing that in detriment to performance at runtime. EVERY
SINGLE
strlen function is SIMD-optimised, sometimes even multiple versions.
There's
even a dedicated instruction added to SSE4.2 to do that, plus the
original
8086 way (rep scasb) which was slow for a long time and now is fast
again.
I don't have the benchmarks to prove it, but my gut feeling is that the
SIMD
code becomes worth it very quickly (despite the call overhead),
sometime
between 8 and 16 characters in the string.
https://godbolt.org/g/gBMykD
Ah, but you said that the flaw was in the _standard_. But what you show
are sub-optimal compiler implementations. There's nothing in the
standard that prevents a compiler to implement char_traits::length() as
a compiler intrinsic that can have different backends for constexpr and
runtime evaluation.
So, would the following be acceptable:
1. QSV uses char_traits<char16_t>::length() to calculate the length
(that was my initial implementation, but it's constexpr only starting
with C++17). Then QSV(Char*) is only constexpr in C++17. I can live with
that.
2. You/Intel work on the compiler vendors to get
char_traits<char16_t>::length() implemented as an intrinsic, with SIMD
at runtime and compiler magic at compile-time?
Then we fix the problem where it should be fixed, and just piggy-back on
the more general solution. And it's easy to sell to QSV users why that
ctor is not constexpr until C++17 (and we don't even need any #ifdefery
in the implementation).
What do you think?
Thanks,
Marc
That is, unless compiler vendors haven't yet done this already.
_______________________________________________
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development