From 45be71bf7d7c855e74b84d2fabb4e626afc57a22 Mon Sep 17 00:00:00 2001 From: Roman Pasechnik Date: Thu, 10 Jan 2013 14:45:18 +0200 Subject: [PATCH] Added initializer list constructors for Qt associative containers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Affected: QSet, QMap, QMultiMap, QHash, QMultiHash. Task-number: QTBUG-25679 Change-Id: I01f3ecfbca805f4c053a75232188bd2a77fdb1f2 Reviewed-by: Thiago Macieira Reviewed-by: Jędrzej Nowacki --- src/corelib/tools/qhash.cpp | 20 +++++++++++++ src/corelib/tools/qhash.h | 21 ++++++++++++++ src/corelib/tools/qmap.cpp | 20 +++++++++++++ src/corelib/tools/qmap.h | 19 +++++++++++++ src/corelib/tools/qset.h | 11 +++++++ src/corelib/tools/qset.qdoc | 10 +++++++ tests/auto/corelib/tools/qhash/tst_qhash.cpp | 30 ++++++++++++++++++++ tests/auto/corelib/tools/qmap/tst_qmap.cpp | 30 ++++++++++++++++++++ tests/auto/corelib/tools/qset/tst_qset.cpp | 22 ++++++++++++++ 9 files changed, 183 insertions(+) diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 0103a208f32..b8cd076cb6b 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -924,6 +924,16 @@ void QHashData::checkSanity() \sa clear() */ +/*! \fn QHash::QHash(std::initializer_list > list) + \since 5.1 + + Constructs a hash with a copy of each of the elements in the + initializer list \a list. + + This function is only available if the program is being + compiled in C++11 mode. +*/ + /*! \fn QHash::QHash(const QHash &other) Constructs a copy of \a other. @@ -1981,6 +1991,16 @@ void QHashData::checkSanity() Constructs an empty hash. */ +/*! \fn QMultiHash::QMultiHash(std::initializer_list > list) + \since 5.1 + + Constructs a multi hash with a copy of each of the elements in the + initializer list \a list. + + This function is only available if the program is being + compiled in C++11 mode. +*/ + /*! \fn QMultiHash::QMultiHash(const QHash &other) Constructs a copy of \a other (which can be a QHash or a diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 98965b91216..69a8afe195d 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -48,6 +48,10 @@ #include #include +#ifdef Q_COMPILER_INITIALIZER_LISTS +#include +#endif + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -285,6 +289,15 @@ class QHash public: inline QHash() : d(const_cast(&QHashData::shared_null)) { } +#ifdef Q_COMPILER_INITIALIZER_LISTS + inline QHash(std::initializer_list > list) + : d(const_cast(&QHashData::shared_null)) + { + reserve(list.size()); + for (typename std::initializer_list >::const_iterator it = list.begin(); it != list.end(); ++it) + insert(it->first, it->second); + } +#endif inline QHash(const QHash &other) : d(other.d) { d->ref.ref(); if (!d->sharable) detach(); } inline ~QHash() { if (!d->ref.deref()) freeData(d); } @@ -921,6 +934,14 @@ class QMultiHash : public QHash { public: QMultiHash() {} +#ifdef Q_COMPILER_INITIALIZER_LISTS + inline QMultiHash(std::initializer_list > list) + { + this->reserve(list.size()); + for (typename std::initializer_list >::const_iterator it = list.begin(); it != list.end(); ++it) + insert(it->first, it->second); + } +#endif QMultiHash(const QHash &other) : QHash(other) {} inline void swap(QMultiHash &other) { QHash::swap(other); } // prevent QMultiHash<->QHash swaps diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index 75104e48257..a4c28b5bd41 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -538,6 +538,16 @@ void QMapDataBase::freeData(QMapDataBase *d) \sa toStdMap() */ +/*! \fn QMap::QMap(std::initializer_list > list) + \since 5.1 + + Constructs a map with a copy of each of the elements in the + initializer list \a list. + + This function is only available if the program is being + compiled in C++11 mode. +*/ + /*! \fn std::map QMap::toStdMap() const Returns an STL map equivalent to this QMap. @@ -1576,6 +1586,16 @@ void QMapDataBase::freeData(QMapDataBase *d) Constructs an empty map. */ +/*! \fn QMultiMap::QMultiMap(std::initializer_list > list) + \since 5.1 + + Constructs a multi map with a copy of each of the elements in the + initializer list \a list. + + This function is only available if the program is being + compiled in C++11 mode. +*/ + /*! \fn QMultiMap::QMultiMap(const QMap &other) Constructs a copy of \a other (which can be a QMap or a diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index b0ec6fb3c65..93134a43dd9 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -54,6 +54,10 @@ #include #include +#ifdef Q_COMPILER_INITIALIZER_LISTS +#include +#endif + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -327,6 +331,14 @@ class QMap public: inline QMap() : d(static_cast *>(const_cast(&QMapDataBase::shared_null))) { } +#ifdef Q_COMPILER_INITIALIZER_LISTS + inline QMap(std::initializer_list > list) + : d(static_cast *>(const_cast(&QMapDataBase::shared_null))) + { + for (typename std::initializer_list >::const_iterator it = list.begin(); it != list.end(); ++it) + insert(it->first, it->second); + } +#endif QMap(const QMap &other); inline ~QMap() { if (!d->ref.deref()) d->destroy(); } @@ -960,6 +972,13 @@ class QMultiMap : public QMap { public: QMultiMap() {} +#ifdef Q_COMPILER_INITIALIZER_LISTS + inline QMultiMap(std::initializer_list > list) + { + for (typename std::initializer_list >::const_iterator it = list.begin(); it != list.end(); ++it) + insert(it->first, it->second); + } +#endif QMultiMap(const QMap &other) : QMap(other) {} inline void swap(QMultiMap &other) { QMap::swap(other); } diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index 6fdc8e62816..ee91336c510 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -43,6 +43,9 @@ #define QSET_H #include +#ifdef Q_COMPILER_INITIALIZER_LISTS +#include +#endif QT_BEGIN_HEADER @@ -56,6 +59,14 @@ class QSet public: inline QSet() {} +#ifdef Q_COMPILER_INITIALIZER_LISTS + inline QSet(std::initializer_list list) + { + reserve(list.size()); + for (typename std::initializer_list::const_iterator it = list.begin(); it != list.end(); ++it) + insert(*it); + } +#endif inline QSet(const QSet &other) : q_hash(other.q_hash) {} inline QSet &operator=(const QSet &other) diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc index ef7a4c4f529..cd90b4949b2 100644 --- a/src/corelib/tools/qset.qdoc +++ b/src/corelib/tools/qset.qdoc @@ -103,6 +103,16 @@ \sa clear() */ +/*! \fn QSet::QSet(std::initializer_list list) + \since 5.1 + + Constructs a set with a copy of each of the elements in the + initializer list \a list. + + This function is only available if the program is being + compiled in C++11 mode. +*/ + /*! \fn QSet::QSet(const QSet &other) diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 6df84e6363a..903a4e1012e 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -74,6 +74,7 @@ private slots: void const_shared_null(); void twoArguments_qHash(); + void initializerList(); }; struct Foo { @@ -1300,5 +1301,34 @@ void tst_QHash::twoArguments_qHash() QCOMPARE(wrongqHashOverload, 0); } +void tst_QHash::initializerList() +{ +#ifdef Q_COMPILER_INITIALIZER_LISTS + QHash hash{{1, "hello"}, {2, "initializer_list"}}; + QCOMPARE(hash.count(), 2); + QVERIFY(hash[1] == "hello"); + QVERIFY(hash[2] == "initializer_list"); + + QMultiHash multiHash{{"il", 1}, {"il", 2}, {"il", 3}}; + QCOMPARE(multiHash.count(), 3); + QList values = multiHash.values("il"); + QCOMPARE(values.count(), 3); + + QHash emptyHash{}; + QVERIFY(emptyHash.isEmpty()); + + QHash emptyPairs{{}, {}}; + QVERIFY(!emptyPairs.isEmpty()); + + QMultiHash emptyMultiHash{}; + QVERIFY(emptyMultiHash.isEmpty()); + + QMultiHash emptyPairs2{{}, {}}; + QVERIFY(!emptyPairs2.isEmpty()); +#else + QSKIP("Compiler doesn't support initializer lists"); +#endif +} + QTEST_APPLESS_MAIN(tst_QHash) #include "tst_qhash.moc" diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index 5069b805bf7..801656e1c3f 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -84,6 +84,7 @@ private slots: void insert(); void checkMostLeftNode(); + void initializerList(); }; typedef QMap StringMap; @@ -1129,5 +1130,34 @@ void tst_QMap::checkMostLeftNode() sanityCheckTree(map, __LINE__); } +void tst_QMap::initializerList() +{ +#ifdef Q_COMPILER_INITIALIZER_LISTS + QMap map{{1, "hello"}, {2, "initializer_list"}}; + QCOMPARE(map.count(), 2); + QVERIFY(map[1] == "hello"); + QVERIFY(map[2] == "initializer_list"); + + QMultiMap multiMap{{"il", 1}, {"il", 2}, {"il", 3}}; + QCOMPARE(multiMap.count(), 3); + QList values = multiMap.values("il"); + QCOMPARE(values.count(), 3); + + QMap emptyMap{}; + QVERIFY(emptyMap.isEmpty()); + + QMap emptyPairs{{}, {}}; + QVERIFY(!emptyPairs.isEmpty()); + + QMultiMap emptyMultiMap{}; + QVERIFY(emptyMultiMap.isEmpty()); + + QMultiMap emptyPairs2{{}, {}}; + QVERIFY(!emptyPairs2.isEmpty()); +#else + QSKIP("Compiler doesn't support initializer lists"); +#endif +} + QTEST_APPLESS_MAIN(tst_QMap) #include "tst_qmap.moc" diff --git a/tests/auto/corelib/tools/qset/tst_qset.cpp b/tests/auto/corelib/tools/qset/tst_qset.cpp index a3232d05c3a..eaa1c018ba4 100644 --- a/tests/auto/corelib/tools/qset/tst_qset.cpp +++ b/tests/auto/corelib/tools/qset/tst_qset.cpp @@ -79,6 +79,7 @@ private slots: void javaIterator(); void javaMutableIterator(); void makeSureTheComfortFunctionsCompile(); + void initializerList(); }; void tst_QSet::operator_eq() @@ -918,6 +919,27 @@ void tst_QSet::makeSureTheComfortFunctionsCompile() set1 = set2 - set3; } +void tst_QSet::initializerList() +{ +#ifdef Q_COMPILER_INITIALIZER_LISTS + QSet set{1, 2, 3, 4, 5}; + QCOMPARE(set.count(), 5); + QVERIFY(set.contains(1)); + QVERIFY(set.contains(2)); + QVERIFY(set.contains(3)); + QVERIFY(set.contains(4)); + QVERIFY(set.contains(5)); + + QSet emptySet{}; + QVERIFY(emptySet.isEmpty()); + + QSet set3{{}, {}, {}}; + QVERIFY(!set3.isEmpty()); +#else + QSKIP("Compiler doesn't support initializer lists"); +#endif +} + QTEST_APPLESS_MAIN(tst_QSet) #include "tst_qset.moc"