summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorStephen Kelly <stephen.kelly@kdab.com>2013-09-11 18:56:02 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-13 14:37:41 +0200
commit8b0624182bd4998d32c23eded5dbe6dccfd26d5b (patch)
tree8e74d2fa946718d8fe2f0060829cfd8a96cf1bde /src/corelib
parenta9770c4b6c9fb80ae1b33f5e901ed0a5e5bfb25c (diff)
MetaType: Fix operator{+,-}(int) with the type-erased const_iterators.
Make sure we don't modify the lhs. Instead copy it and advance the copy. Change-Id: I3440e8e175bfc299f8f83b816faca54fa3f79e43 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qmetatype.h28
-rw-r--r--src/corelib/kernel/qvariant.h8
2 files changed, 32 insertions, 4 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 0b8be3af89..4ccfc7b7f0 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -892,6 +892,7 @@ public:
typedef VariantData (*getFunc)( void * const *p, int metaTypeId, uint flags);
typedef void (*destroyIterFunc)(void **p);
typedef bool (*equalIterFunc)(void * const *p, void * const *other);
+ typedef void (*copyIterFunc)(void **, void * const *);
sizeFunc _size;
atFunc _at;
@@ -901,6 +902,7 @@ public:
getFunc _get;
destroyIterFunc _destroyIter;
equalIterFunc _equalIter;
+ copyIterFunc _copyIter;
template<class T>
static int sizeImpl(const void *p)
@@ -938,6 +940,10 @@ public:
static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, IteratorOwner<typename T::const_iterator>::getData(iterator), flags); }
+ template<class T>
+ static void copyIterImpl(void **dest, void * const * src)
+ { IteratorOwner<typename T::const_iterator>::assign(dest, *static_cast<typename T::const_iterator*>(*src)); }
+
public:
template<class T> QSequentialIterableImpl(const T*p)
: _iterable(p)
@@ -953,6 +959,7 @@ public:
, _get(getImpl<T>)
, _destroyIter(destroyIterImpl<T>)
, _equalIter(equalIterImpl<T>)
+ , _copyIter(copyIterImpl<T>)
{
}
@@ -970,6 +977,7 @@ public:
, _get(0)
, _destroyIter(0)
, _equalIter(0)
+ , _copyIter(0)
{
}
@@ -990,6 +998,12 @@ public:
int size() const { Q_ASSERT(_iterable); return _size(_iterable); }
inline void destroyIter() { _destroyIter(&_iterator); }
+
+ void copy(const QSequentialIterableImpl &other)
+ {
+ *this = other;
+ _copyIter(&_iterator, &other._iterator);
+ }
};
template<typename From>
@@ -1055,6 +1069,7 @@ public:
typedef VariantData (*getFunc)(void * const *p, int metaTypeId, uint flags);
typedef void (*destroyIterFunc)(void **p);
typedef bool (*equalIterFunc)(void * const *p, void * const *other);
+ typedef void (*copyIterFunc)(void **, void * const *);
sizeFunc _size;
findFunc _find;
@@ -1065,6 +1080,7 @@ public:
getFunc _getValue;
destroyIterFunc _destroyIter;
equalIterFunc _equalIter;
+ copyIterFunc _copyIter;
template<class T>
static int sizeImpl(const void *p)
@@ -1104,6 +1120,10 @@ public:
static bool equalIterImpl(void * const *iterator, void * const *other)
{ return *static_cast<typename T::const_iterator*>(*iterator) == *static_cast<typename T::const_iterator*>(*other); }
+ template<class T>
+ static void copyIterImpl(void **dest, void * const * src)
+ { IteratorOwner<typename T::const_iterator>::assign(dest, *static_cast<typename T::const_iterator*>(*src)); }
+
public:
template<class T> QAssociativeIterableImpl(const T*p)
: _iterable(p)
@@ -1120,6 +1140,7 @@ public:
, _getValue(getValueImpl<T>)
, _destroyIter(destroyIterImpl<T>)
, _equalIter(equalIterImpl<T>)
+ , _copyIter(copyIterImpl<T>)
{
}
@@ -1138,6 +1159,7 @@ public:
, _getValue(0)
, _destroyIter(0)
, _equalIter(0)
+ , _copyIter(0)
{
}
@@ -1155,6 +1177,12 @@ public:
{ _find(_iterable, key.data, &_iterator); }
int size() const { Q_ASSERT(_iterable); return _size(_iterable); }
+
+ void copy(const QAssociativeIterableImpl &other)
+ {
+ *this = other;
+ _copyIter(&_iterator, &other._iterator);
+ }
};
template<typename From>
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 3345131c0f..3115c6a50b 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -615,8 +615,8 @@ public:
inline const_iterator operator--(int) { QtMetaTypePrivate::QSequentialIterableImpl impl = m_impl; m_impl.advance(-1); return const_iterator(impl, this->ref); }
inline const_iterator &operator+=(int j) { m_impl.advance(j); return *this; }
inline const_iterator &operator-=(int j) { m_impl.advance(-j); return *this; }
- inline const_iterator operator+(int j) const { QtMetaTypePrivate::QSequentialIterableImpl impl = m_impl; impl.advance(j); return const_iterator(impl, this->ref); }
- inline const_iterator operator-(int j) const { QtMetaTypePrivate::QSequentialIterableImpl impl = m_impl; impl.advance(-j); return const_iterator(impl, this->ref); }
+ inline const_iterator operator+(int j) const { QtMetaTypePrivate::QSequentialIterableImpl impl; impl.copy(m_impl); impl.advance(j); return const_iterator(impl, new QAtomicInt(0)); }
+ inline const_iterator operator-(int j) const { QtMetaTypePrivate::QSequentialIterableImpl impl; impl.copy(m_impl); impl.advance(-j); return const_iterator(impl, new QAtomicInt(0)); }
};
friend struct const_iterator;
@@ -700,8 +700,8 @@ public:
inline const_iterator operator--(int) { QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl; m_impl.advance(-1); return const_iterator(impl, this->ref); }
inline const_iterator &operator+=(int j) { m_impl.advance(j); return *this; }
inline const_iterator &operator-=(int j) { m_impl.advance(-j); return *this; }
- inline const_iterator operator+(int j) const { QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl; impl.advance(j); return const_iterator(impl, this->ref); }
- inline const_iterator operator-(int j) const { QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl; impl.advance(-j); return const_iterator(impl, this->ref); }
+ inline const_iterator operator+(int j) const { QtMetaTypePrivate::QAssociativeIterableImpl impl; impl.copy(m_impl); impl.advance(j); return const_iterator(impl, new QAtomicInt(0)); }
+ inline const_iterator operator-(int j) const { QtMetaTypePrivate::QAssociativeIterableImpl impl; impl.copy(m_impl); impl.advance(-j); return const_iterator(impl, new QAtomicInt(0)); }
};
friend struct const_iterator;