diff options
Diffstat (limited to 'src/corelib/tools/qvector.h')
-rw-r--r-- | src/corelib/tools/qvector.h | 57 |
1 files changed, 27 insertions, 30 deletions
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 288c082c44..85393a3598 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -337,20 +337,14 @@ QVector(InputIterator, InputIterator) -> QVector<ValueType>; // behavior change: an object of POD type constructed with an initializer of the form () // will be default-initialized # pragma warning ( push ) -# pragma warning ( disable : 4345 ) # pragma warning(disable : 4127) // conditional expression is constant #endif template <typename T> void QVector<T>::defaultConstruct(T *from, T *to) { - if (QTypeInfo<T>::isComplex) { - while (from != to) { - new (from++) T(); - } - } else { - ::memset(static_cast<void *>(from), 0, (to - from) * sizeof(T)); - } + while (from != to) + new (from++) T(); } template <typename T> @@ -529,7 +523,7 @@ QVector<T>::QVector(int asize, const T &t) d = Data::allocate(asize); Q_CHECK_PTR(d); d->size = asize; - T* i = d->end(); + auto i = d->end(); while (i != d->begin()) new (--i) T(t); } else { @@ -641,17 +635,13 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo if (asize > d->size) { // construct all new objects when growing - if (!QTypeInfo<T>::isComplex) { - ::memset(static_cast<void *>(dst), 0, (static_cast<T *>(x->end()) - dst) * sizeof(T)); - } else { - QT_TRY { - while (dst != x->end()) - new (dst++) T(); - } QT_CATCH (...) { - // destruct already copied objects - destruct(x->begin(), dst); - QT_RETHROW; - } + QT_TRY { + while (dst != x->end()) + new (dst++) T(); + } QT_CATCH (...) { + // destruct already copied objects + destruct(x->begin(), dst); + QT_RETHROW; } } } QT_CATCH (...) { @@ -845,18 +835,25 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c if (!isDetached() || d->size + n > int(d->alloc)) realloc(d->size + n, QArrayData::Grow); if (!QTypeInfoQuery<T>::isRelocatable) { - T *b = d->end(); - T *i = d->end() + n; - while (i != b) - new (--i) T; - i = d->end(); + T *const e = d->end(); + T *const b = d->begin() + offset; + + T *i = e; T *j = i + n; - b = d->begin() + offset; - while (i != b) - *--j = *--i; - i = b+n; + + // move old elements into the uninitialized space + while (i != b && j > e) + new (--j) T(std::move(*--i)); + // move the rest of old elements into the tail using assignment while (i != b) - *--i = copy; + *--j = std::move(*--i); + + // construct copies of t inside the uninitialized space + while (j != b && j > e) + new (--j) T(copy); + // use assignment to fill the recently-moved-from space + while (j != b) + *--j = copy; } else { T *b = d->begin() + offset; T *i = b + n; |