From 747800675044bc1782b9bc9b97cea2cc2ef2c06f Mon Sep 17 00:00:00 2001 From: Ievgenii Meshcheriakov Date: Tue, 12 Oct 2021 16:17:32 +0200 Subject: QVector: Don't require default-constructible types with insert() Don't require existence of a default constructor inside 3-argument insert() and use copy constructor and assignment operator instead. This makes insert() and other operations usable with types that have neither a default constructor nor a move constructor. Also use std::move() to shift the existing content. Add new testcases to tst_qvector to verify the functionality. Fixes: QTBUG-93392 Change-Id: I88fb4b882339d64f17e6477a974502efbb0dfb88 Reviewed-by: Edward Welbourne Reviewed-by: Sona Kurazyan --- src/corelib/tools/qvector.h | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'src/corelib/tools/qvector.h') diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index efdea05714..e8f6bd99d8 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -835,18 +835,25 @@ typename QVector::iterator QVector::insert(iterator before, size_type n, c if (!isDetached() || d->size + n > int(d->alloc)) realloc(d->size + n, QArrayData::Grow); if (!QTypeInfoQuery::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; -- cgit v1.2.3