Re: [Development] C++20 structural types (was: C++20 @ Qt)

2022-11-04 Thread Allan Sandfeld Jensen
On Freitag, 4. November 2022 21:47:14 CET Thiago Macieira wrote:
> On Friday, 4 November 2022 10:38:30 PDT Allan Sandfeld Jensen wrote:
> > Can we even do that, and still preserve ABI and API?
> 
> I don't see why not. QFlags is already standard-layout, trivially copyable
> and trivially destructible. Changing the member from private to public
> won't affect any of those properties.

Right, but it is only forward compatible, as making members public gives new 
API options. So okay for a minor release, but not for a point release that 
also needs to be backwards compatible.

Allan



___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] C++20 structural types (was: C++20 @ Qt)

2022-11-04 Thread Thiago Macieira
On Friday, 4 November 2022 10:38:30 PDT Allan Sandfeld Jensen wrote:
> Can we even do that, and still preserve ABI and API?

I don't see why not. QFlags is already standard-layout, trivially copyable and 
trivially destructible. Changing the member from private to public won't affect 
any of those properties.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Cloud Software Architect - Intel DCAI Cloud Engineering



___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] C++20 structural types (was: C++20 @ Qt)

2022-11-04 Thread Allan Sandfeld Jensen
On Freitag, 4. November 2022 16:49:30 CET Thiago Macieira wrote:
> I've just hit this: should we make some of our very simple types even
> simpler so they're structural types[1] and thus can be passed as template
> parameters?
> 
> For example, QFlags. I've just tried it and I get:
> 
> error: ‘QFlags’ is not a valid type for a template
> non-type parameter because it is not structural
> note: ‘QFlags::i’ is not public
> 
> [1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0732r2.pdf

Can we even do that, and still preserve ABI and API?

Best regards,
Allan


___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


[Development] C++20 structural types (was: C++20 @ Qt)

2022-11-04 Thread Thiago Macieira
I've just hit this: should we make some of our very simple types even simpler 
so they're structural types[1] and thus can be passed as template parameters?

For example, QFlags. I've just tried it and I get:

error: ‘QFlags’ is not a valid type for a template non-type 
parameter because it is not structural
note: ‘QFlags::i’ is not public

[1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0732r2.pdf
-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Cloud Software Architect - Intel DCAI Cloud Engineering



___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] C++20 comparisons @ Qt (was: Re: C++20 @ Qt)

2022-11-04 Thread Marc Mutz via Development
Hi Ulf,

On 04.11.22 12:13, Ulf Hermann via Development wrote:
> One thing I haven't understood about the ordering problem is why we 
> cannot just define our "invalid" values to always be < any valid one and 
> equal to other invalid ones. This way we get at least weak ordering for 
> all our types and we're done.

That's what we're currently doing, yes. At least for QDateTime. For 
QString, we have that isNull() compares equal to empty. Each class has 
it's own semantics. I'll have a look at QTypeRevision, but that prompted 
me to remember QOperatingSystemVersion, where we really, genuinely have 
several sets of values where elements from different sets are not 
ordered (Win10  There may be types where existing operator< work differently (*cough* 
> QTypeRevision), but that just means we need to emulate that same 
> behavior with the new operators.

Without having looked at QTypeRevision, I agree in general.

> Indeed the NaN behavior has always been a pain to deal with every time 
> I've encountered it. If we have a chance to avoid it, we should.
> 
> What is the downside of such an approach?

The (potential) downside is that it's arbitrary and classes might behave 
inconsistently (one sorts invalid before valid ones, the other vice 
versa). It may also be a bit more work to document (unless we choose not 
to mention that little detail). Or we can't reap any future tool support 
that might be developed for partial_ordering (sanitizers, etc).

Overall, I don't feel strongly about it (no pun intended). From the 
ongoing discussion more and more examples pop up, though, where 
partial_ordering would be a really good idea (QVariant, QOSVersion, 
QTypeRevision?), and if those definite use-cases make people more 
familiar with partial_ordering, maybe invalid-as-unorderable would also 
come to be felt as more natural.

Thanks,
Marc

___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


[Development] How qAsConst and qExchange lead to qNN

2022-11-04 Thread Marc Mutz via Development
Hi,

After getting my head washed by Volker, lemme provide background on 
these two functions.

TL;DR: we created real maintenance and porting problems by not removing 
stop-gap functionality in a timely fashion, qNN presented as a way to 
ensure this won't happen again.

Both qAsConst and qExchange are 1:1 reimplementations of std 
functionality we couldn't rely on back then (as_const is C++17 and 
exchange is C++14), so they're exactly equivalent to the std versions. 
Or were, when they were added.

Neither std::as_const nor qAsConst have changed, so the replacement is 
easy: s/qAsConst/std::as_const/. It cannot not compile because qAsConst 
comes from qglobal.h and that transitively includes . This is 
what was intended from the get-go:

https://codereview.qt-project.org/c/qt/qtbase/+/114548
 > Intended as internal API, but not put into the QtPrivate
 > namespace to make it simpler to use.
 >
 > We could wait for std::as_const, but that is far, far
 > away (just entered the current C++17 draft as of this
 > writing), and the Qt containers with their tendency to
 > detach are a problem _now_.

I don't remember why sometime later we (I) documented it as public API, 
but I failed to add the magic sentence

 > Use std::as_const if you can (C++17). qAsConst will be removed is a
 > future version of Qt

We seem to be removing these kinds of sentences from API (currently on 
Gerrit for Q_FOREACH), but I don't think we should.

Anyway, that's qAsConst. It does what std::as_const does, so moving to 
The Real McCoy is trivial.


Unfortunately, as it always seems to happen, both std::exchange and 
qExchange changed. They're still 100% equivalent, but qExchange is now 
equivalent to std::exchange in C++20 (constexpr) and C++23 
(conditionally noexcept, technically a DR), so we can _not_ blindly 
replace qExchange with std::exchange, because we only require C++17.

It is important to dwell on the difference between the two:

std::as_const never changed, so qAsConst never had to.
std::exchange changed, so it was felt that qExchange had to, too.

The outcome is that we don't need to maintain qAsConst, and can 
trivially port away from it, but we have (continued) to maintain 
qExchange, and can _not_ trivially port away from it.

What was the mistake? The mistake was to not limit the qExchange 
implementation to the C++14 version, but directly going for C++20 
semantics (constexpr; mea culpa) and therefore not being able to remove 
qExchange when we _could_ (in 6.0, when a C++14-only qExchange and 
std::exchange would have been semantically identical). Instead, we kept 
dragging it on with unclear semantics (C++14 or C++20?), until C++23 
semantics were added to qExchange() extending the lifetime even further. 
Had we limited qExchange to C++14 and removed qExchange when we had the 
chance, this lock-in would not have happened.


But why do the deprecation _now_?

It turns out, when we decomposed qglobal.h to speed up compilation (a 
high-prio request from users), we ended up with a clean qglobal.h 
including only other includes, except qAsConst and qExchange for which 
we didn't find a good home. My idea, then, was to deprecate qAsConst and 
qExchange, introducing q20::exchange (see below), so that they could 
stay in qglobal.h, itself to be deprecated in favour of the more 
fine-grained headers and port the code base away from qAsConst and 
qExchange to pave the way for rolling out the finer-grained headers. It 
turns out I was too slow and qAsConst and qExchange are now in 
qttypetraits.h (go figure), and we have problems deprecating them 
_there_, because the Qt deprecation macros aren't defined, yet, when 
that file is included in some TUs.

One problem after the other. This is just to illustrate that there's a 
very real cost associated with keeping stop-gap reimplementations of std 
functionality around for longer than absolutely necessary.



So, late in Qt 5 I came to experiment with how we could break this 
vicious cycle: On one hand, we want to provide some std library 
reimplementations when we just don't want to or cannot wait for them to 
become available. But OTOH we want these to be stop-gaps, until we can 
depend on a version of C++ in which they ship, and remove them as soon 
as possible to avoid the above-mentioned trap where we need to maintain 
them indefinitely. And certainly, we don't want to follow the std 
implementation changes lest we never catch up with the std version.

For some time, I thought just making these functions private would be 
enough (qmemory_p.h for q_make_unique), but private API means we can't 
use it in public headers. Also, there's no indication when we can remove 
the stop-gap again. Was make_unique C++14 or C++17? Hmm, hmm...

Finally, there's the problem of whitespace: assume we've solved the 
problem with use in public headers, and I could write

auto p = q_make_unique(foo, ,
   bar, );

I can safely 

Re: [Development] Using '#pragma once' instead of include guards?

2022-11-04 Thread Ulf Hermann via Development

Once we had QString and QByteArray (and the admittedly ill-conceived
QStringRef). Now we have QStringView, QAnyStringView, QByteArrayView,
... and when asking what the prefered getter/setter-signature for
"Qt-style" interfaces is the answer I get is "We'd guess $X, but the
only guy that knows for sure is on holiday". And that's for "developers
using Qt", not "developers _of_ Qt". Is that something you'd
call "complicated"?


While I can sympathize with the idea of #pragma once, this is not a fair 
comparison. The current set of classes, while complicated, also does a 
lot more than what we previously had. If you want the only the old 
functionality you can just restrict yourself to QString, QByteArray, and 
QStringView. That's not actually more complicated.


But if you want classes that deal with UTF-8 and with views on different 
kinds of string data, you obviously need some more types.

___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Using '#pragma once' instead of include guards?

2022-11-04 Thread A . Pönitz
On Wed, Nov 02, 2022 at 02:25:25PM +, Marc Mutz via Development wrote:
> Hi Volker,
> 
> On 14.10.22 17:12, Volker Hilsheimer via Development wrote:
> > Anyway, I’ve added the respective text to the coding convention wiki 
> > page.
> > https://wiki.qt.io/Coding_Conventions
> 
> Having read the thread in total, I'm surprised about this outcome. 
> AFAIK, we haven't had problems with traditional include guards,

[Funnily enough, the same could be said for a significant part (read:
pretty much all) the deprecations and API-removals since ~5.12]

> yet, and no compelling use-case for #pragma once was presented, so I
> don't see why we're now allowing it.

The "user case" is that in Real Life(TM)

  (a) keeping the names of include guards sensible and consistent and
  "legal" is a pain. Talking about "identifiers reserved for use
  by C++ implementation" (double underscores, underscore plus 
  uppercase - and don't think about what "uppercase" /actually/ means)
  is something that quite a few people don't want to do every second week.

  (b) it gives the concept a name. It is /one/ /short/ line that hardly can
  be misspelled, bears a meaning, and typically doesn't need discussion
  besides silencing the "Fire! Wolves! Non-Standard!" voices.
  Compare that to the three lines, that could be wrong, could mean 
  something else, could use arbritrary names for the guards, which by
  itself are a perfect ground for bikeshedding and busy-work
  to "fix" them [1].

> Esp. since the rule as written is more 
> complicated than "always use header guards".

[Oh "complicated"?

Once we had QString and QByteArray (and the admittedly ill-conceived
QStringRef). Now we have QStringView, QAnyStringView, QByteArrayView,
... and when asking what the prefered getter/setter-signature for
"Qt-style" interfaces is the answer I get is "We'd guess $X, but the
only guy that knows for sure is on holiday". And that's for "developers
using Qt", not "developers _of_ Qt". Is that something you'd
call "complicated"?


Andre',
wondering whether he actually should read this list during vacations.


PS: 
[1] https://en.wikipedia.org/wiki/Busy_work - just to make sure:
this bears a /negative/ connotated.
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] C++20 comparisons @ Qt (was: Re: C++20 @ Qt)

2022-11-04 Thread Ulf Hermann via Development

Hi,

One thing I haven't understood about the ordering problem is why we 
cannot just define our "invalid" values to always be < any valid one and 
equal to other invalid ones. This way we get at least weak ordering for 
all our types and we're done.


There may be types where existing operator< work differently (*cough* 
QTypeRevision), but that just means we need to emulate that same 
behavior with the new operators.


Indeed the NaN behavior has always been a pain to deal with every time 
I've encountered it. If we have a chance to avoid it, we should.


What is the downside of such an approach?

best regards,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] C++20 comparisons @ Qt (was: Re: C++20 @ Qt)

2022-11-04 Thread Edward Welbourne via Development
On Thursday, 3 November 2022 09:48:49 PDT Marc Mutz via Development wrote:
>>> Here, too, I feel lost. I'm struggling to see what a NIH
>>> std::partial_ordering w/o the weak and strong counterparts and w/o
>>> op<=> language support could achieve, except another vocabulary type
>>> mismatch.  Can you elaborate?

On 03.11.22 18:38, Thiago Macieira wrote:
>> We can use it until we can depend on C++20. Like QSpan, that's why it's 
>> there.

Marc Mutz (4 November 2022 11:22)
> The difference is that QSpan vs. std::span doesn't create an impedance
> mismatch. QPartialOrdering vs. std::partial_ordering does, esp. since
> QPartialOrdering lacks an implicit conversion to/from
> std::partial_ordering, and the member names are different.

Since my comments on QDateTime are implicated here, I should note that -
since it would be a behaviour change - an initial transition to a weak
ordering that preserves invalid < valid could perfectly well suffice
until we *do* transition to C++20 and *can* use std::partial_order, at
which point I do think it would make sense to change our types with
invalid (but supported) null-forms to make them incomparable, ideally
all at the same time.

> With the exception of qfloat32, I'm not aware of any Qt type that
> would exhibit partial ordering semantics atm.

I take it you mean qfloat16, whose NaN is incomparable,

Eddy.
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] C++20 comparisons @ Qt (was: Re: C++20 @ Qt)

2022-11-04 Thread Marc Mutz via Development
Hi Thiago,

On 03.11.22 18:38, Thiago Macieira wrote:
> On Thursday, 3 November 2022 09:48:49 PDT Marc Mutz via Development wrote:
>> On 03.11.22 16:17, Thiago Macieira wrote:
>>> For some classes, we could postpone changing anything until C++20 is
>>> required.
>> You lost me there. Why do you think so? Because of the sentence above?
>> Requiring C++20 won't be a BC break, so we'd still have all the old
>> exported relational operators to QT_REMOVED_SINCE.
> 
> A simple question of code readability. If it's not that important and it makes
> the code significantly uglier, we can simply postpone until it's not ugly.

Yes, we could postpone, but I feel that would be a disservice to both us and 
our users.

To us, because we simply don't have the bandwidth to do all C++20 
changes at once, so we need to select which ones we can do before we 
require C++20, and this is one of them.

To our users, because we currently don't have a clue whether our 
relational operators are free of C++20 ambiguities. We _think_ we caught 
them all, but we don't have a C++20 build on the CI, yet to know for 
sure, and,even if we did, we typically don't have the test coverage to 
test all combinations (incl. const/mutable and l/rvalue). Ambiguities 
are detected at call time, not declaration time, so we need exhaustive 
checking, anyway. I believe it's better to fix this issue before we 
require users to use C++20, forcing them into exposing our remaining 
bugs. And to fix them consistently. A user doesn't care whether his 
C++20 build breaks because of QJsonValue or QWaylandBufferRef.

>>> Meanwhile, we have qcompare.h.
>>
>> Here, too, I feel lost. I'm struggling to see what a NIH
>> std::partial_ordering w/o the weak and strong counterparts and w/o op<=>
>> language support could achieve, except another vocabulary type mismatch.
>> Can you elaborate?
> 
> We can use it until we can depend on C++20. Like QSpan, that's why it's there.

The difference is that QSpan vs. std::span doesn't create an impedance 
mismatch. QPartialOrdering vs. std::partial_ordering does, esp. since 
QPartialOrdering lacks an implicit conversion to/from 
std::partial_ordering, and the member names are different.

> Or the methods can simply return int, like I intended in QCborValue.

That's what I was thinking, yes.

>> Meanwhile, in a Jira comment, Eddy discovered a potential problem with
>> partial_ordering::unordered: we have a lot of types that have
>> std::optional folded into them (isNull/isValid) and, if they're ordered,
>> they need to have decided on a total order, ie. incl. for invalid/null
>> ones (QDateTime sorts invalid before valid e.g.). These types' op<=>
>> could now return unordered for invalid values, but that would change the
>> semantics of the op< derived from it vis a vis the existing op<.
> 
> What's the recommendation? Create a total order where null < empty < any non-
> empty, or use partial ordering?

For new classes, knowing what I know now, I'd use partial ordering 
(though I'd also ask to consider avoiding baking in optional<> semantics 
to elegantly side-step the issue). For existing classes, we need to keep 
the total order they most likely are currently using. With the exception 
of qfloat32, I'm not aware of any Qt type that would exhibit partial 
ordering semantics atm. Whether we then switch to a partial order come 
Qt 7 is a different question. I would make that contingent on how 
support for partial_ordering in the wider C++ ecosystem in coming along.

Thanks,
Marc

___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] Nominating Sami Shalayel as approver

2022-11-04 Thread Ulf Hermann via Development

+1

Unsurprisingly, I'm part of the same team as Sami
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


[Development] Nominating Sami Shalayel as approver

2022-11-04 Thread Fabian Kosmale via Development
Hi,

I'd like to nominate Sami Shalayel as an approver for the Qt project.

Sami is employed by the Qt Company and has been working since May on Qt, mostly
on QtDeclarative, with a focus on qmltc.
He made several good contributions there, and also participates in the review
process of QML related patches.

I trust him to be a good approver. Link to his gerrit dashboard:

Patches:
https://codereview.qt-project.org/q/owner:sami.shalayel%2540qt.io
Reviews:
https://codereview.qt-project.org/q/reviewer:sami.shalayel%2540qt.io

Disclosure: I'm Sami's direct line manager at the Qt Company, and share
an office with him.

Fabian
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development