diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index 24505d629b4..3aa5e701148 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -288,7 +288,7 @@ public: const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } iterator insert(const_iterator before, qsizetype n, const T &x); - iterator insert(const_iterator before, T &&x); + iterator insert(const_iterator before, T &&x) { return emplace(before, std::move(x)); } inline iterator insert(const_iterator before, const T &x) { return insert(before, 1, x); } iterator erase(const_iterator begin, const_iterator end); inline iterator erase(const_iterator pos) { return erase(pos, pos + 1); } @@ -303,6 +303,11 @@ public: inline T &back() { return last(); } inline const T &back() const { return last(); } void shrink_to_fit() { squeeze(); } + template + iterator emplace(const_iterator pos, Args &&...args); + template + T &emplace_back(Args &&...args) { return *emplace(cend(), std::forward(args)...); } + #ifdef Q_QDOC template @@ -612,7 +617,8 @@ inline void QVarLengthArray::replace(qsizetype i, const T &t) } template -Q_OUTOFLINE_TEMPLATE typename QVarLengthArray::iterator QVarLengthArray::insert(const_iterator before, T &&t) +template +Q_OUTOFLINE_TEMPLATE auto QVarLengthArray::emplace(const_iterator before, Args &&...args) -> iterator { Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid"); @@ -627,14 +633,14 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray::iterator QVarLengthA new (--j) T(std::move(*--i)); while (i != b) *--j = std::move(*--i); - *b = std::move(t); + *b = T(std::forward(args)...); } else { - new (b) T(std::move(t)); + new (b) T(std::forward(args)...); } } else { T *b = ptr + offset; memmove(static_cast(b + 1), static_cast(b), (s - offset) * sizeof(T)); - new (b) T(std::move(t)); + new (b) T(std::forward(args)...); } s += 1; return ptr + offset; diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc index 52261de4c65..485b531805a 100644 --- a/src/corelib/tools/qvarlengtharray.qdoc +++ b/src/corelib/tools/qvarlengtharray.qdoc @@ -753,6 +753,28 @@ \a before. Returns an iterator pointing at the inserted item. */ +/*! + \fn template QVarLengthArray::emplace(const_iterator before, Args &&...args); + + \since 6.3 + + Inserts an item in front of the item pointed to by the iterator + \a before, passing \a args to its constructor. + + Returns an iterator pointing at the emplaced item. +*/ + +/*! + \fn template QVarLengthArray::emplace_back(Args &&...args); + + \since 6.3 + + Inserts an item at the back of this QVarLengthArray, passing + \a args to its constructor. + + Returns a reference to the emplaced item. +*/ + /*! \fn template QVarLengthArray::iterator QVarLengthArray::insert(const_iterator before, qsizetype count, const T &value) \since 4.8 diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp index 4dd8cbf8ba9..0598a39cb6e 100644 --- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp +++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp @@ -70,6 +70,7 @@ class tst_QVarLengthArray : public QObject private slots: void append(); void prepend(); + void emplace(); void move_int_1() { move_int<1>(); } void move_int_2() { move_int<2>(); } void move_int_3() { move_int<3>(); } @@ -164,6 +165,24 @@ void tst_QVarLengthArray::prepend() QCOMPARE(v.front(), v.back()); } +void tst_QVarLengthArray::emplace() +{ + { + QVarLengthArray strings; + strings.emplace_back(); + QCOMPARE(strings.size(), 1); + QCOMPARE(strings.front().isNull(), true); + strings.emplace(strings.begin(), 42, u'x'); + QCOMPARE(strings.size(), 2); + QCOMPARE(strings.back().isNull(), true); + QCOMPARE(strings.front(), QString(42, u'x')); + auto &r = strings.emplace_back(42, u'y'); + QCOMPARE(&r, &strings.back()); + QCOMPARE(strings.size(), 3); + QCOMPARE(strings.back(), QString(42, u'y')); + } +} + template void tst_QVarLengthArray::move_Tracker() {