QVector: add an rvalue overload of push_back/append
This is low-hanging fruit, for two reasons: 1. The implementation is dead-simple (unlike, say, in QList). 2. It's completely transparent to the QVector user (unlike, say, emplace_back, which can only be used inside an ifdef). Change-Id: Iaf750100cf61ced77aa452f0e4e3c4ec36b29639 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>bb10
parent
8d1d12a328
commit
4ea3c0ba80
|
|
@ -84,14 +84,27 @@ for (int i = 0; i < 10; ++i)
|
|||
|
||||
|
||||
//! [7]
|
||||
QVector<QString> vector(0);
|
||||
QVector<QString> vector;
|
||||
vector.append("one");
|
||||
vector.append("two");
|
||||
vector.append("three");
|
||||
QString three = "three";
|
||||
vector.append(three);
|
||||
// vector: ["one", "two", "three"]
|
||||
// three: "three"
|
||||
//! [7]
|
||||
|
||||
|
||||
//! [move-append]
|
||||
QVector<QString> vector;
|
||||
vector.append("one");
|
||||
vector.append("two");
|
||||
QString three = "three";
|
||||
vector.append(std::move(three));
|
||||
// vector: ["one", "two", "three"]
|
||||
// three: ""
|
||||
//! [move-append]
|
||||
|
||||
|
||||
//! [8]
|
||||
QVector<QString> vector;
|
||||
vector.prepend("one");
|
||||
|
|
|
|||
|
|
@ -522,6 +522,16 @@
|
|||
\sa operator<<(), prepend(), insert()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void QVector::append(T &&value)
|
||||
\since 5.6
|
||||
|
||||
\overload
|
||||
|
||||
Example:
|
||||
\snippet code/src_corelib_tools_qvector.cpp move-append
|
||||
*/
|
||||
|
||||
/*! \fn void QVector::append(const QVector<T> &value)
|
||||
|
||||
\overload
|
||||
|
|
@ -1026,6 +1036,11 @@
|
|||
to append(\a value).
|
||||
*/
|
||||
|
||||
/*! \fn void QVector::push_back(T &&value)
|
||||
\since 5.6
|
||||
\overload
|
||||
*/
|
||||
|
||||
/*! \fn void QVector::push_front(const T &value)
|
||||
|
||||
This function is provided for STL compatibility. It is equivalent
|
||||
|
|
|
|||
|
|
@ -129,6 +129,9 @@ public:
|
|||
T &operator[](int i);
|
||||
const T &operator[](int i) const;
|
||||
void append(const T &t);
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
void append(T &&t);
|
||||
#endif
|
||||
inline void append(const QVector<T> &l) { *this += l; }
|
||||
void prepend(const T &t);
|
||||
void insert(int i, const T &t);
|
||||
|
|
@ -247,6 +250,9 @@ public:
|
|||
typedef const_iterator ConstIterator;
|
||||
typedef int size_type;
|
||||
inline void push_back(const T &t) { append(t); }
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
void push_back(T &&t) { append(std::move(t)); }
|
||||
#endif
|
||||
inline void push_front(const T &t) { prepend(t); }
|
||||
void pop_back() { removeLast(); }
|
||||
void pop_front() { removeFirst(); }
|
||||
|
|
@ -643,6 +649,22 @@ void QVector<T>::append(const T &t)
|
|||
++d->size;
|
||||
}
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
template <typename T>
|
||||
void QVector<T>::append(T &&t)
|
||||
{
|
||||
const bool isTooSmall = uint(d->size + 1) > d->alloc;
|
||||
if (!isDetached() || isTooSmall) {
|
||||
QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default);
|
||||
reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt);
|
||||
}
|
||||
|
||||
new (d->end()) T(std::move(t));
|
||||
|
||||
++d->size;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
void QVector<T>::removeLast()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
CONFIG += testcase parallel_test
|
||||
contains(QT_CONFIG, c++11):CONFIG += c++11
|
||||
TARGET = tst_qvector
|
||||
QT = core testlib
|
||||
SOURCES = $$PWD/tst_qvector.cpp
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ private slots:
|
|||
void appendInt() const;
|
||||
void appendMovable() const;
|
||||
void appendCustom() const;
|
||||
void appendRvalue() const;
|
||||
void at() const;
|
||||
void capacityInt() const;
|
||||
void capacityMovable() const;
|
||||
|
|
@ -638,6 +639,21 @@ void tst_QVector::appendCustom() const
|
|||
QCOMPARE(instancesCount, Custom::counter.loadAcquire());
|
||||
}
|
||||
|
||||
void tst_QVector::appendRvalue() const
|
||||
{
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
QVector<QString> v;
|
||||
v.append("hello");
|
||||
QString world = "world";
|
||||
v.append(std::move(world));
|
||||
QVERIFY(world.isEmpty());
|
||||
QCOMPARE(v.front(), QString("hello"));
|
||||
QCOMPARE(v.back(), QString("world"));
|
||||
#else
|
||||
QSKIP("This test requires that C++11 move semantics support is enabled in the compiler");
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QVector::at() const
|
||||
{
|
||||
QVector<QString> myvec;
|
||||
|
|
|
|||
Loading…
Reference in New Issue