From 1d31f23ce9dd438e68aee0dbf1907e17b0d66db3 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 17 Feb 2017 00:58:11 +0100 Subject: QVarLengthArray: add rvalue overload of append/push_back Improves performance when appending temporaries, esp. since the aliasing fix in the lvalue overload in 0f730ef made that overload correct, but a bit slower across reallocs. The unit tests already also pass rvalues, so the function is covered in the existing tests. [ChangeLog][QtCore][QVarLengthArray] Added rvalue overloads of append() and push_back(). Change-Id: If3a6970f03a160cba5b42d33d32d3d18948f6ce3 Reviewed-by: Thiago Macieira Reviewed-by: Edward Welbourne --- src/corelib/tools/qvarlengtharray.h | 11 +++++++++++ src/corelib/tools/qvarlengtharray.qdoc | 28 ++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index ae2c75e7df..5d0231417b 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -165,6 +165,16 @@ public: } } + void append(T &&t) { + if (s == a) + realloc(s, s << 1); + const int idx = s++; + if (QTypeInfo::isComplex) + new (ptr + idx) T(std::move(t)); + else + ptr[idx] = std::move(t); + } + void append(const T *buf, int size); inline QVarLengthArray &operator<<(const T &t) { append(t); return *this; } @@ -218,6 +228,7 @@ public: // STL compatibility: inline bool empty() const { return isEmpty(); } inline void push_back(const T &t) { append(t); } + void push_back(T &&t) { append(std::move(t)); } inline void pop_back() { removeLast(); } inline T &front() { return first(); } inline const T &front() const { return first(); } diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc index 5e53a969e8..127afcd069 100644 --- a/src/corelib/tools/qvarlengtharray.qdoc +++ b/src/corelib/tools/qvarlengtharray.qdoc @@ -302,6 +302,34 @@ Provided for STL-compatibility. */ +/*! + \fn void QVarLengthArray::append(T &&t) + \overload append + \since 5.9 + + \note Unlike the lvalue overload of append(), passing a reference to + an object that is already an element of \c *this leads to undefined + behavior: + + \code + vla.append(std::move(vla[0])); // BUG: passing an object that is already in the container + \endcode +*/ + +/*! + \fn void QVarLengthArray::push_back(T &&t) + \overload push_back + \since 5.9 + + \note Unlike the lvalue overload of push_back(), passing a reference to + an object that is already an element of \c *this leads to undefined + behavior: + + \code + vla.push_back(std::move(vla[0])); // BUG: passing an object that is already in the container + \endcode +*/ + /*! \fn inline void QVarLengthArray::removeLast() \since 4.5 -- cgit v1.2.1