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

Reply via email to