Re: [Development] QHash iteration vs std::unordered_map

2017-04-20 Thread Matthew Woehlke
On 2017-04-20 13:18, Sergio Martins wrote:
> On 2017-04-20 18:06, Matthew Woehlke wrote:
>>   for (auto i : qtEnumerate(my_hash))
>> do_stuff(i.key(), i.value());
> 
> That doesn't work with temporaries, does it ?

No. Neither does std::add_const / qAsConst.

> Maybe something to fix in the C++ language, since the usual
> lifetime-extension tricks don't help in this case.

There has been talk, but TTBOMK no concrete proposals yet. (IIRC the
`register` proposal was published but the author decided not to present
it yet.)

-- 
Matthew
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] QHash iteration vs std::unordered_map

2017-04-20 Thread Sergio Martins

On 2017-04-20 18:06, Matthew Woehlke wrote:

On 2017-04-16 10:44, Corentin wrote:
If you want the same behavior, you can create a proxy for your 
associative
container instance, with a custom iterator whose operator*() returns a 
std

pair ( or a QPair ) - quite a bit of boilterplate code.


...or use
https://github.com/Kitware/qtextensions/blob/master/core/qtEnumerate.h.
Rather than returning a pair (which may add overhead), it creates a
proxy that just returns the iterator, so you can write:

  for (auto i : qtEnumerate(my_hash))
do_stuff(i.key(), i.value());


That doesn't work with temporaries, does it ?

Maybe something to fix in the C++ language, since the usual 
lifetime-extension tricks don't help in this case.



Regards,
--
Sérgio Martins | sergio.mart...@kdab.com | Senior Software Engineer
Klarälvdalens Datakonsult AB, a KDAB Group company
Tel: Sweden (HQ) +46-563-540090, USA +1-866-777-KDAB(5322)
KDAB - The Qt, C++ and OpenGL Experts
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] QHash iteration vs std::unordered_map

2017-04-20 Thread Matthew Woehlke
On 2017-04-16 10:44, Corentin wrote:
> If you want the same behavior, you can create a proxy for your associative
> container instance, with a custom iterator whose operator*() returns a std
> pair ( or a QPair ) - quite a bit of boilterplate code.

...or use
https://github.com/Kitware/qtextensions/blob/master/core/qtEnumerate.h.
Rather than returning a pair (which may add overhead), it creates a
proxy that just returns the iterator, so you can write:

  for (auto i : qtEnumerate(my_hash))
do_stuff(i.key(), i.value());

As a plus, `key()` and `value()` are much more readable than `first` and
`second`.

-- 
Matthew
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] QHash iteration vs std::unordered_map

2017-04-18 Thread Marc Mutz
On Tuesday 18 April 2017 10:52:47 Olivier Goffart wrote:
> On Montag, 17. April 2017 18:48:26 CEST Marc Mutz wrote:
> > On Monday 17 April 2017 18:08:20 Thiago Macieira wrote:
> > > Em segunda-feira, 17 de abril de 2017, às 00:30:23 PDT, Marc Mutz
> 
> escreveu:
> > > > The problem with QT_STRICT_ITERATORS is _not_ that they are changing
> > > > begin() and end(),
> > > 
> > > Actually, it was. You can't use QT_STRICT_ITERATORS in one TU and not
> > > in other, regardless of exporting or not.
> > 
> > Why?
> 
> ODR violation is an undefined behaviour.
> (Technically, this is also the case across library boundaries)

If QT_STRICT_ITERATORS (as-is) is an ODR violation, and technically, it is, 
then so is #ifdef Q_COMPILER_... over member functions, or 
QT_NO_CAST_FROM_ASCII. However, we'd be screwed if any compiler started to 
exploit that particular UB.

So, there's nothing out of the ordinary with QT_STRICT_ITERATORS itself. Maybe 
there was in the past, but not in its current state. In its current state, the 
problems with QT_STRICT_ITERATORS are _solely_ the two I mentioned, and they 
affect all member-function-ifdef'ery, be it about iterators, conversions, or 
c++ features, in the same way. Just try to compile QtCore with 
QT_NO_CAST_FROM_ASCII and watch the carnage that surely ensues.

We can turn a blind eye on the issue, but this wholesale exporting of non-
polymophic classes will bite us over and over again, until the naysayers will 
have learned, too.

Thanks,
Marc

-- 
Marc Mutz  | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt, C++ and OpenGL Experts
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] QHash iteration vs std::unordered_map

2017-04-18 Thread Olivier Goffart
On Montag, 17. April 2017 18:48:26 CEST Marc Mutz wrote:
> On Monday 17 April 2017 18:08:20 Thiago Macieira wrote:
> > Em segunda-feira, 17 de abril de 2017, às 00:30:23 PDT, Marc Mutz 
escreveu:
> > > The problem with QT_STRICT_ITERATORS is _not_ that they are changing
> > > begin() and end(),
> > 
> > Actually, it was. You can't use QT_STRICT_ITERATORS in one TU and not in
> > other, regardless of exporting or not.
> 
> Why?

ODR violation is an undefined behaviour.
(Technically, this is also the case across library boundaries)

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


Re: [Development] QHash iteration vs std::unordered_map

2017-04-17 Thread Thiago Macieira
Em segunda-feira, 17 de abril de 2017, às 09:48:26 PDT, Marc Mutz escreveu:
> On Monday 17 April 2017 18:08:20 Thiago Macieira wrote:
> > Em segunda-feira, 17 de abril de 2017, às 00:30:23 PDT, Marc Mutz 
escreveu:
> > > The problem with QT_STRICT_ITERATORS is _not_ that they are changing
> > > begin() and end(),
> > 
> > Actually, it was. You can't use QT_STRICT_ITERATORS in one TU and not in
> > other, regardless of exporting or not.
> 
> Why?

Well, now it can, because of this:

  iterator begin(iterator = iterator()) Q_DECL_NOTHROW { return data(); }
  iterator end(iterator = iterator()) Q_DECL_NOTHROW { return data() + size; }

Because of the parameter, the non-strict version calls begin(T*), whereas the 
strict one calls begin(QTypedArrayData::iterator). Those are two different 
functions, with different name manglings. When they are emitted out-of-line 
and merged at link time, you'll have two copies, not one.

The difference is how the ABI returns the return value: a 
QTypedArrayData::iterator is returned by implicit reference, whereas a 
pointer is returned by value. In the former case, the caller passes an 
implicit parameter to the storage area for the called function. In the latter, 
there is no parameter. So if the two functions had the same parameters (and 
thus the same mangling), the caller of the non-strict would not pass anything 
for the first parameter, causing the called strict begin() function to 
dereference an uninitialised pointer.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

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


Re: [Development] QHash iteration vs std::unordered_map

2017-04-17 Thread Marc Mutz
On Monday 17 April 2017 18:08:20 Thiago Macieira wrote:
> Em segunda-feira, 17 de abril de 2017, às 00:30:23 PDT, Marc Mutz escreveu:
> > The problem with QT_STRICT_ITERATORS is _not_ that they are changing
> > begin() and end(),
> 
> Actually, it was. You can't use QT_STRICT_ITERATORS in one TU and not in
> other, regardless of exporting or not.

Why?

-- 
Marc Mutz  | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt, C++ and OpenGL Experts
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] QHash iteration vs std::unordered_map

2017-04-17 Thread Thiago Macieira
Em segunda-feira, 17 de abril de 2017, às 00:30:23 PDT, Marc Mutz escreveu:
> The problem with QT_STRICT_ITERATORS is _not_ that they are changing begin()
> and end(),

Actually, it was. You can't use QT_STRICT_ITERATORS in one TU and not in 
other, regardless of exporting or not.


-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

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


Re: [Development] QHash iteration vs std::unordered_map

2017-04-17 Thread Marc Mutz
On Monday 17 April 2017 00:59:55 Thiago Macieira wrote:
> Em domingo, 16 de abril de 2017, às 15:16:54 PDT, Mark Gaiser escreveu:
> > Ohh, that's great!
> >
> > 
> >
> > One question. Would it be possible and sane to - by default - provide
> > it as the patch implements it there, but with the addition of a define
> > that can influence the behavior of the iterators?
> 
> Most llikely no. Just look at the problem that QT_STRICT_ITERATORS causes.
> We  shouldn't make the same mistake again.

The problem with QT_STRICT_ITERATORS is _not_ that they are changing begin() 
and end(), but that a) classes that shouldn't be (non-polymorphic ones), are 
exported, thus breaking patterns that are deeply ingrained in C++ developers 
(inline function no longer are inline, e.g.) and b) that classes that 
shouldn't be (non-polymorphic ones with public dtor), are inherited.

_These_ are the things that need fixing, not QT_STRICT_ITERATORS, or a 
hypothetical QT_STL_COMPATIBLE_ITERSTORS, even though I consider the former, 
too, a kludge.

Thanks,
Marc

-- 
Marc Mutz  | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt, C++ and OpenGL Experts
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] QHash iteration vs std::unordered_map

2017-04-16 Thread Thiago Macieira
Em domingo, 16 de abril de 2017, às 15:16:54 PDT, Mark Gaiser escreveu:
> Ohh, that's great!
> 
> One question. Would it be possible and sane to - by default - provide
> it as the patch implements it there, but with the addition of a define
> that can influence the behavior of the iterators?

Most llikely no. Just look at the problem that QT_STRICT_ITERATORS causes. We 
shouldn't make the same mistake again.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

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


Re: [Development] QHash iteration vs std::unordered_map

2017-04-16 Thread Thiago Macieira
Em domingo, 16 de abril de 2017, às 15:09:16 PDT, Mark Gaiser escreveu:
> On Sun, Apr 16, 2017 at 5:53 PM, Thiago Macieira
> 
>  wrote:
> > Em domingo, 16 de abril de 2017, às 08:05:21 PDT, Mark Gaiser escreveu:
> >> That again makes me wonder, why did Qt diverge from that?
> > 
> > We didn't diverge. We never had that. The Qt style predates the Standard
> > Library having relevance in Qt. When the first QHash-like class was added,
> > it was just like that.
> 
> With regards to QHash vs std::unordered_map, yes.
> But STL also has std::map which certainly predates Qt and also gives
> back an std::pair.

I was referring to std::map and QDict.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

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


Re: [Development] QHash iteration vs std::unordered_map

2017-04-16 Thread Mark Gaiser
On Sun, Apr 16, 2017 at 9:48 PM, Samuel Gaist  wrote:
>
>> On 16 Apr 2017, at 17:53, Thiago Macieira  wrote:
>>
>> Em domingo, 16 de abril de 2017, às 08:05:21 PDT, Mark Gaiser escreveu:
>>> That again makes me wonder, why did Qt diverge from that?
>>
>> We didn't diverge. We never had that. The Qt style predates the Standard
>> Library having relevance in Qt. When the first QHash-like class was added, it
>> was just like that.
>>
>> Also remember that at the time, you wouldn't think of a Standard Library
>> associative container as such. It was just a sequential container that held a
>> std::pair, with some convenience functions for searching the first of the 
>> pair.
>> Returning a pair was a consequence of that. I don't know if it was 
>> intentional
>> thinking, or it just happened.
>>
>>> And... if Qt plans to change it in Qt6?
>>
>> No, cannot due to source compatibility. Ever.
>>
>> --
>> Thiago Macieira - thiago.macieira (AT) intel.com
>>  Software Architect - Intel Open Source Technology Center
>>
>> ___
>> Development mailing list
>> Development@qt-project.org
>> http://lists.qt-project.org/mailman/listinfo/development
>>
>
> Hi,
>
> Just in case, there’s a work in progress at
>
> https://codereview.qt-project.org/#/c/151511/
>
> to add these "missing" iterators to QHash and QMap.

Ohh, that's great!

One question. Would it be possible and sane to - by default - provide
it as the patch implements it there, but with the addition of a define
that can influence the behavior of the iterators?
For instance a "QT_STL_COMPATIBLE_ITERATORS" (just made that up,
doesn't exist) when defined gives the iterators
begin/constBegin/cbegin/enc/constEnd/cend STL compatible output (so
give an std::pair with key and value)?
When not defined (the default i guess) it falls back to what Qt uses now.

Providing this option makes the Qt containers easier to use with STL algorithms.
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] QHash iteration vs std::unordered_map

2017-04-16 Thread Mark Gaiser
On Sun, Apr 16, 2017 at 5:53 PM, Thiago Macieira
 wrote:
> Em domingo, 16 de abril de 2017, às 08:05:21 PDT, Mark Gaiser escreveu:
>> That again makes me wonder, why did Qt diverge from that?
>
> We didn't diverge. We never had that. The Qt style predates the Standard
> Library having relevance in Qt. When the first QHash-like class was added, it
> was just like that.

With regards to QHash vs std::unordered_map, yes.
But STL also has std::map which certainly predates Qt and also gives
back an std::pair.
>
> Also remember that at the time, you wouldn't think of a Standard Library
> associative container as such. It was just a sequential container that held a
> std::pair, with some convenience functions for searching the first of the 
> pair.
> Returning a pair was a consequence of that. I don't know if it was intentional
> thinking, or it just happened.
>
>> And... if Qt plans to change it in Qt6?
>
> No, cannot due to source compatibility. Ever.
>
> --
> Thiago Macieira - thiago.macieira (AT) intel.com
>   Software Architect - Intel Open Source Technology Center
>
> ___
> Development mailing list
> Development@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] QHash iteration vs std::unordered_map

2017-04-16 Thread Samuel Gaist

> On 16 Apr 2017, at 17:53, Thiago Macieira  wrote:
> 
> Em domingo, 16 de abril de 2017, às 08:05:21 PDT, Mark Gaiser escreveu:
>> That again makes me wonder, why did Qt diverge from that?
> 
> We didn't diverge. We never had that. The Qt style predates the Standard
> Library having relevance in Qt. When the first QHash-like class was added, it
> was just like that.
> 
> Also remember that at the time, you wouldn't think of a Standard Library
> associative container as such. It was just a sequential container that held a
> std::pair, with some convenience functions for searching the first of the 
> pair.
> Returning a pair was a consequence of that. I don't know if it was intentional
> thinking, or it just happened.
> 
>> And... if Qt plans to change it in Qt6?
> 
> No, cannot due to source compatibility. Ever.
> 
> --
> Thiago Macieira - thiago.macieira (AT) intel.com
>  Software Architect - Intel Open Source Technology Center
> 
> ___
> Development mailing list
> Development@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
> 

Hi,

Just in case, there’s a work in progress at

https://codereview.qt-project.org/#/c/151511/

to add these "missing" iterators to QHash and QMap.

Cheers,
Samuel


signature.asc
Description: Message signed with OpenPGP
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] QHash iteration vs std::unordered_map

2017-04-16 Thread Thiago Macieira
Em domingo, 16 de abril de 2017, às 08:05:21 PDT, Mark Gaiser escreveu:
> That again makes me wonder, why did Qt diverge from that?

We didn't diverge. We never had that. The Qt style predates the Standard 
Library having relevance in Qt. When the first QHash-like class was added, it 
was just like that.

Also remember that at the time, you wouldn't think of a Standard Library 
associative container as such. It was just a sequential container that held a 
std::pair, with some convenience functions for searching the first of the pair. 
Returning a pair was a consequence of that. I don't know if it was intentional 
thinking, or it just happened.

> And... if Qt plans to change it in Qt6?

No, cannot due to source compatibility. Ever.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

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


Re: [Development] QHash iteration vs std::unordered_map

2017-04-16 Thread Mark Gaiser
On Sun, Apr 16, 2017 at 4:44 PM, Corentin  wrote:
> Funny, a friend at kdab asked me about that exact question a few minutes
> ago.
> The reason for the difference is most certainly an historical one ( and
> can't be changed because it would break quite a bit of code ).
>
> If you want the same behavior, you can create a proxy for your associative
> container instance, with a custom iterator whose operator*() returns a std
> pair ( or a QPair ) - quite a bit of boilterplate code.

It probably does come down to historic reasons, but that would be
strange as well.
I doubt that the C++ committee changed what is returned by operator*()
(correct me if i'm wrong) so i'm inclined to think that the
std:: stuff is returning it as an std::pair for quite a
while now.
That again makes me wonder, why did Qt diverge from that?

And... if Qt plans to change it in Qt6?

>
>
>
>
> Le dim. 16 avr. 2017 à 15:57, Mark Gaiser  a écrit :
>>
>> Hi,
>>
>> Take this simple example:
>>
>>   QHash test = {
>> {10, "aaa"},
>> {20, "bbb"},
>> {30, "ccc"}
>>   };
>>
>>   for (const auto : qAsConst(test)) {
>> qDebug() << entry;
>>   }
>>
>> It returns:
>> "aaa"
>> "ccc"
>> "bbb"
>>
>> and the std::unordered_map version:
>>   std::unordered_map test = {
>> {10, "aaa"},
>> {20, "bbb"},
>> {30, "ccc"}
>>   };
>>
>>   for (const auto : test) {
>> qDebug() << entry;
>>   }
>>
>> it returns:
>> std::pair(30,"ccc")
>> std::pair(10,"aaa")
>> std::pair(20,"bbb")
>>
>> As you can see, the QHash iteration directly returns the value. The
>> std::unordered_map returns a std::par with the key and value for the
>> current iteration (in it's respective first and second members). Both
>> approaches probably have arguments in favor and against. What i'm
>> curious about is why there is a difference at all?
>>
>> I'm curious because the behavior is a bit unexpected when compared to
>> std::unordered_map. I would have guessed QHash to follow the same
>> logic as std::unordered_map, only with a Qt syntax. So for instance a
>> return of QPair(...), not the value directly.
>>
>> Thanks,
>> Mark
>> ___
>> Development mailing list
>> Development@qt-project.org
>> http://lists.qt-project.org/mailman/listinfo/development
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] QHash iteration vs std::unordered_map

2017-04-16 Thread Corentin
Funny, a friend at kdab asked me about that exact question a few minutes
ago.
The reason for the difference is most certainly an historical one ( and
can't be changed because it would break quite a bit of code ).

If you want the same behavior, you can create a proxy for your associative
container instance, with a custom iterator whose operator*() returns a std
pair ( or a QPair ) - quite a bit of boilterplate code.




Le dim. 16 avr. 2017 à 15:57, Mark Gaiser  a écrit :

> Hi,
>
> Take this simple example:
>
>   QHash test = {
> {10, "aaa"},
> {20, "bbb"},
> {30, "ccc"}
>   };
>
>   for (const auto : qAsConst(test)) {
> qDebug() << entry;
>   }
>
> It returns:
> "aaa"
> "ccc"
> "bbb"
>
> and the std::unordered_map version:
>   std::unordered_map test = {
> {10, "aaa"},
> {20, "bbb"},
> {30, "ccc"}
>   };
>
>   for (const auto : test) {
> qDebug() << entry;
>   }
>
> it returns:
> std::pair(30,"ccc")
> std::pair(10,"aaa")
> std::pair(20,"bbb")
>
> As you can see, the QHash iteration directly returns the value. The
> std::unordered_map returns a std::par with the key and value for the
> current iteration (in it's respective first and second members). Both
> approaches probably have arguments in favor and against. What i'm
> curious about is why there is a difference at all?
>
> I'm curious because the behavior is a bit unexpected when compared to
> std::unordered_map. I would have guessed QHash to follow the same
> logic as std::unordered_map, only with a Qt syntax. So for instance a
> return of QPair(...), not the value directly.
>
> Thanks,
> Mark
> ___
> Development mailing list
> Development@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
>
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


[Development] QHash iteration vs std::unordered_map

2017-04-16 Thread Mark Gaiser
Hi,

Take this simple example:

  QHash test = {
{10, "aaa"},
{20, "bbb"},
{30, "ccc"}
  };

  for (const auto : qAsConst(test)) {
qDebug() << entry;
  }

It returns:
"aaa"
"ccc"
"bbb"

and the std::unordered_map version:
  std::unordered_map test = {
{10, "aaa"},
{20, "bbb"},
{30, "ccc"}
  };

  for (const auto : test) {
qDebug() << entry;
  }

it returns:
std::pair(30,"ccc")
std::pair(10,"aaa")
std::pair(20,"bbb")

As you can see, the QHash iteration directly returns the value. The
std::unordered_map returns a std::par with the key and value for the
current iteration (in it's respective first and second members). Both
approaches probably have arguments in favor and against. What i'm
curious about is why there is a difference at all?

I'm curious because the behavior is a bit unexpected when compared to
std::unordered_map. I would have guessed QHash to follow the same
logic as std::unordered_map, only with a Qt syntax. So for instance a
return of QPair(...), not the value directly.

Thanks,
Mark
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development