QVarLengthArray: Add initializer_list constructor

Implement an initializer_list constructor, which was probably
just forgotten so far. Technically this is a SC incompatible change,
since

  QVarLengthArray<int> array = {10};

will now create an array with one element 10, instead of an empty array
with a reserved size of 10. Anyhow, keeping the inconsistency with the
STL / other Qt containers here would certainly do more harm than good
in the long run.

Task-number: QTBUG-45047
Change-Id: I4675880f93e141181250939942fa32300916b0e3
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
Kai Koehne 2015-03-18 09:28:59 +01:00
parent 5c379f3ff0
commit d3659bf88b
3 changed files with 84 additions and 0 deletions

View File

@ -42,6 +42,9 @@
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#ifdef Q_COMPILER_INITIALIZER_LISTS
#include <initializer_list>
#endif
QT_BEGIN_NAMESPACE
@ -62,6 +65,14 @@ public:
append(other.constData(), other.size());
}
#ifdef Q_COMPILER_INITIALIZER_LISTS
QVarLengthArray(std::initializer_list<T> args)
: a(Prealloc), s(0), ptr(reinterpret_cast<T *>(array))
{
append(args.begin(), args.size());
}
#endif
inline ~QVarLengthArray() {
if (QTypeInfo<T>::isComplex) {
T *i = ptr + s;

View File

@ -100,6 +100,17 @@
\l{default-constructed value}.
*/
/*! \fn QVarLengthArray::QVarLengthArray(std::initializer_list<T> args)
\since 5.5
Constructs an array from the std::initializer_list given by \a args.
This constructor is only enabled if the compiler supports C++11 initializer
lists.
*/
/*! \fn QVarLengthArray::~QVarLengthArray()
Destroys the array.

View File

@ -54,6 +54,12 @@ private slots:
void indexOf();
void lastIndexOf();
void contains();
void initializeListInt();
void initializeListMovable();
void initializeListComplex();
private:
template<typename T>
void initializeList();
};
int fooCtor = 0;
@ -333,11 +339,23 @@ struct MyPrimitive
struct MyMovable
: MyBase
{
MyMovable(char input = 'j') : i(input) {}
bool operator==(const MyMovable &other) const
{
return i == other.i;
}
char i;
};
struct MyComplex
: MyBase
{
MyComplex(char input = 'j') : i(input) {}
bool operator==(const MyComplex &other) const
{
return i == other.i;
}
char i;
};
QT_BEGIN_NAMESPACE
@ -734,5 +752,49 @@ void tst_QVarLengthArray::contains()
QVERIFY(myvec.contains(QLatin1String("I don't exist")));
}
void tst_QVarLengthArray::initializeListInt()
{
initializeList<int>();
}
void tst_QVarLengthArray::initializeListMovable()
{
const int instancesCount = MyMovable::liveCount;
initializeList<MyMovable>();
QCOMPARE(MyMovable::liveCount, instancesCount);
}
void tst_QVarLengthArray::initializeListComplex()
{
const int instancesCount = MyComplex::liveCount;
initializeList<MyComplex>();
QCOMPARE(MyComplex::liveCount, instancesCount);
}
template<typename T>
void tst_QVarLengthArray::initializeList()
{
#ifdef Q_COMPILER_INITIALIZER_LISTS
T val1(110);
T val2(105);
T val3(101);
T val4(114);
QVarLengthArray<T> v1 {val1, val2, val3};
QCOMPARE(v1, QVarLengthArray<T>() << val1 << val2 << val3);
QCOMPARE(v1, (QVarLengthArray<T> {val1, val2, val3}));
QVarLengthArray<QVarLengthArray<T>, 4> v2{ v1, {val4}, QVarLengthArray<T>(), {val1, val2, val3} };
QVarLengthArray<QVarLengthArray<T>, 4> v3;
v3 << v1 << (QVarLengthArray<T>() << val4) << QVarLengthArray<T>() << v1;
QCOMPARE(v3, v2);
QVarLengthArray<T> v4({});
QCOMPARE(v4.size(), 0);
#else
QSKIP("This tests requires a compiler that supports initializer lists.");
#endif
}
QTEST_APPLESS_MAIN(tst_QVarLengthArray)
#include "tst_qvarlengtharray.moc"