Fix a memleak in QAssociativeIterable::value()
QtMetaTypePrivate::QAssociativeIterableImpl::{find,begin,end}() allocate a new _iterator,
so when they're used outside of the ref-counted world of QAssociativeIterable::const_iterator,
their lifetime needs to be manually managed.
Instead of going to that length, which failed in previous iterations of this patch, implement
value() in terms of (new) find() and let find() operate on const_iterator.
Because of forwards compatibility between patch releases, use (unexported) friend functions
for now with the intention to make them proper member functions come Qt 5.5.
Task-number: QTBUG-41469
Change-Id: I43b21eae0c2fc4c182369e669a8b3b457be68885
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
parent
350c60b79e
commit
d7fa2d060a
|
|
@ -3844,6 +3844,13 @@ void QAssociativeIterable::const_iterator::end()
|
|||
m_impl.end();
|
||||
}
|
||||
|
||||
void find(QAssociativeIterable::const_iterator &it, const QVariant &key)
|
||||
{
|
||||
Q_ASSERT(key.userType() == it.m_impl._metaType_id_key);
|
||||
const QtMetaTypePrivate::VariantData dkey(key.userType(), key.constData(), 0 /*key.flags()*/);
|
||||
it.m_impl.find(dkey);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a QAssociativeIterable::const_iterator for the beginning of the container. This
|
||||
can be used in stl-style iteration.
|
||||
|
|
@ -3870,28 +3877,38 @@ QAssociativeIterable::const_iterator QAssociativeIterable::end() const
|
|||
return it;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
Returns a QAssociativeIterable::const_iterator for the given key \a key
|
||||
in the container, if the types are convertible.
|
||||
|
||||
If the key is not found, returns end().
|
||||
|
||||
This can be used in stl-style iteration.
|
||||
|
||||
\sa begin(), end(), value()
|
||||
*/
|
||||
QAssociativeIterable::const_iterator find(const QAssociativeIterable &iterable, const QVariant &key)
|
||||
{
|
||||
QAssociativeIterable::const_iterator it(iterable, new QAtomicInt(0));
|
||||
QVariant key_ = key;
|
||||
if (key_.canConvert(iterable.m_impl._metaType_id_key) && key_.convert(iterable.m_impl._metaType_id_key))
|
||||
find(it, key_);
|
||||
else
|
||||
it.end();
|
||||
return it;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the value for the given \a key in the container, if the types are convertible.
|
||||
*/
|
||||
QVariant QAssociativeIterable::value(const QVariant &key) const
|
||||
{
|
||||
QVariant key_ = key;
|
||||
if (!key_.canConvert(m_impl._metaType_id_key))
|
||||
const const_iterator it = find(*this, key);
|
||||
if (it == end())
|
||||
return QVariant();
|
||||
if (!key_.convert(m_impl._metaType_id_key))
|
||||
return QVariant();
|
||||
const QtMetaTypePrivate::VariantData dkey(key_.userType(), key_.constData(), 0 /*key.flags()*/);
|
||||
QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl;
|
||||
impl.find(dkey);
|
||||
QtMetaTypePrivate::QAssociativeIterableImpl endIt = m_impl;
|
||||
endIt.end();
|
||||
if (impl.equal(endIt))
|
||||
return QVariant();
|
||||
const QtMetaTypePrivate::VariantData d = impl.getCurrentValue();
|
||||
QVariant v(d.metaTypeId, d.data, d.flags);
|
||||
if (d.metaTypeId == qMetaTypeId<QVariant>())
|
||||
return *reinterpret_cast<const QVariant*>(d.data);
|
||||
return v;
|
||||
return *it;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -633,6 +633,9 @@ public:
|
|||
|
||||
void begin();
|
||||
void end();
|
||||
// ### Qt 5.5: make find() (1st one) a member function
|
||||
friend void find(const_iterator &it, const QVariant &key);
|
||||
friend const_iterator find(const QAssociativeIterable &iterable, const QVariant &key);
|
||||
public:
|
||||
~const_iterator();
|
||||
const_iterator(const const_iterator &other);
|
||||
|
|
@ -662,6 +665,9 @@ public:
|
|||
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
private: // ### Qt 5.5: make it a public find() member function:
|
||||
friend const_iterator find(const QAssociativeIterable &iterable, const QVariant &key);
|
||||
public:
|
||||
|
||||
QVariant value(const QVariant &key) const;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue