[Development] QVariant container API

Jedrzej Nowacki Jedrzej.Nowacki at qt.io
Mon Apr 1 12:33:16 CEST 2019


On Monday, April 1, 2019 11:09:27 AM CEST Vasily Pupkin wrote:
> Hi.
> 
> I would like to submit a patch. Since it is probably going to break binary
> compatibility and is mostly about coding conventions, I would like to have
> some feedback before investing time.
Great! 

> The general idea is to create a playground project for automatic
> (de)serialization for Qt (not manual, i.e. overriding operators). The only
> stopper is container deserialization.
> To operate containers without staticaly knowing their types, one should be
> able to make conversions from QVariant containing a container to container
> of QVariants and vice versa.
> Seriazation is quite straightforward via QSequentialIterable and
> QAssociativeIterable. But deserialization is currently possible only by
> QMetaType::registerConverter. I think, that this is would be so nice to
> have an ability to create a container via QVariant from collection of
> QVariant instances without a need for custom converters.
> ~
> QList<QVariant> variantContainer;
> variantContainer.append(QVariant(123));
> variantContainer.append(QVariant(321));
> QVariant variant(QVariant::fromValue(variantContainer));
> QVariant containerVariant(variant.convert(qMetaTypeId<QList<int> >()));
> ~
You can be sure that the conversion from QList<int> to QSequentialIterable 
will be successful, but the other way around is not given. QSequentialIterable 
can contain QVariants of different types. I'm curious what is the use case for 
the feature?

I think it could be implemented by extending:
https://code.woboq.org/qt5/qtbase/src/corelib/kernel/qmetatype.h.html#2306
which registers conversion from a container to QSequentialIterable. You could 
add the opposite function. That way no binary compatibility would be broken 
nor major re-factoring would be needed.

> And so I have stumbled into a problem. QSequentialIterable  and
> QAssociativeIterable related code is scattered across <qvariant.h> and
> <qmetatype.h>. All related conversions are conveyed in templates, instead
> of
> https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/kernel/qvariant.cpp#n
> 387 .
> I just don't feel, that further
> https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/kernel/qvariant.h#n78
> 2 and
> https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/kernel/qmetatype.h#n1
> 121 development
> is the way to go.
Well, it is a bit of a mess. Conceptually, conversion code should be in 
qmetatype.cpp/qmetatype.h. QVariant should use QMetaType to access / modify / 
create / convert instances of different types. The code is not well split 
because QMetaType class is a late addition, so as usual historical reasons 
:-). If you want to cleanup it a bit I would start on moving 
QSequentialIterable and QAssociativeIterable out of qvariant.h to own headers.

The fact that the conversion happens through QVariantValueHelperInterface in 
my opinion is a mistake, this code should be de-inlined as it is hard to 
extend it. 
> And so the question is: should I try to refactor sequential and associative
> iterators, so templates are used only to staticaly gather information about
> containers and conversions are made in qvariant.cpp, where they belong?
Sure, try, you can add me to review :-)

> It also would be nice to hear, if someone acknowledges this conversion
> feature to be of use.
Yeah, there are not so many users of QXXXIterable. So as long as we can keep 
cost of it low it is fine.

> Thanks for reading this far.

Thanks!
  Jędrek





More information about the Development mailing list