QVector/QList/QLinkedList/QVarLengthArray/QSet: add missing deduction guides

Amends 2e1763d83a.

The new range ctors need deduction guides, since the compiler can't
deduce the value_type from a pair of iterators.

Change-Id: I3ec1e5f91305b317c443b6a70246be416b55bad9
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Marc Mutz 2019-07-28 14:43:24 +03:00
parent bf99c4bf55
commit 247ab241c7
15 changed files with 186 additions and 0 deletions

View File

@ -275,6 +275,13 @@ private:
template <typename T>
Q_DECLARE_TYPEINFO_BODY(QLinkedList<T>, Q_MOVABLE_TYPE|Q_RELOCATABLE_TYPE);
#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201606
template <typename InputIterator,
typename ValueType = typename std::iterator_traits<InputIterator>::value_type,
QtPrivate::IfIsInputIterator<InputIterator> = true>
QLinkedList(InputIterator, InputIterator) -> QLinkedList<ValueType>;
#endif
template <typename T>
inline QLinkedList<T>::~QLinkedList()
{

View File

@ -446,6 +446,13 @@ private:
inline int count_impl(const T &, QListData::ArrayCompatibleLayout) const;
};
#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201606
template <typename InputIterator,
typename ValueType = typename std::iterator_traits<InputIterator>::value_type,
QtPrivate::IfIsInputIterator<InputIterator> = true>
QList(InputIterator, InputIterator) -> QList<ValueType>;
#endif
#if defined(Q_CC_BOR)
template <typename T>
Q_INLINE_TEMPLATE T &QList<T>::Node::t()

View File

@ -269,6 +269,13 @@ private:
}
};
#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201606
template <typename InputIterator,
typename ValueType = typename std::iterator_traits<InputIterator>::value_type,
QtPrivate::IfIsInputIterator<InputIterator> = true>
QSet(InputIterator, InputIterator) -> QSet<ValueType>;
#endif
template <typename T>
uint qHash(const QSet<T> &key, uint seed = 0)
noexcept(noexcept(qHashRangeCommutative(key.begin(), key.end(), seed)))

View File

@ -265,6 +265,13 @@ private:
}
};
#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201606
template <typename InputIterator,
typename ValueType = typename std::iterator_traits<InputIterator>::value_type,
QtPrivate::IfIsInputIterator<InputIterator> = true>
QVarLengthArray(InputIterator, InputIterator) -> QVarLengthArray<ValueType>;
#endif
template <class T, int Prealloc>
Q_INLINE_TEMPLATE QVarLengthArray<T, Prealloc>::QVarLengthArray(int asize)
: s(asize) {

View File

@ -326,6 +326,13 @@ private:
class AlignmentDummy { Data header; T array[1]; };
};
#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201606
template <typename InputIterator,
typename ValueType = typename std::iterator_traits<InputIterator>::value_type,
QtPrivate::IfIsInputIterator<InputIterator> = true>
QVector(InputIterator, InputIterator) -> QVector<ValueType>;
#endif
#ifdef Q_CC_MSVC
// behavior change: an object of POD type constructed with an initializer of the form ()
// will be default-initialized

View File

@ -1,5 +1,7 @@
CONFIG += testcase
TARGET = tst_qlinkedlist
QT = core testlib
qtConfig(c++14): CONFIG += c++14
qtConfig(c++1z): CONFIG += c++1z
SOURCES = tst_qlinkedlist.cpp
DEFINES -= QT_NO_LINKED_LIST

View File

@ -187,6 +187,7 @@ private slots:
void countInt() const;
void countMovable() const;
void countComplex() const;
void cpp17ctad() const;
void emptyInt() const;
void emptyMovable() const;
void emptyComplex() const;
@ -594,6 +595,33 @@ void tst_QLinkedList::countComplex() const
QCOMPARE(liveCount, Complex::getLiveCount());
}
void tst_QLinkedList::cpp17ctad() const
{
#ifdef __cpp_deduction_guides
#define QVERIFY_IS_LIST_OF(obj, Type) \
QVERIFY2((std::is_same<decltype(obj), QLinkedList<Type>>::value), \
QMetaType::typeName(qMetaTypeId<decltype(obj)::value_type>()))
#define CHECK(Type, One, Two, Three) \
do { \
const Type v[] = {One, Two, Three}; \
QLinkedList v1 = {One, Two, Three}; \
QVERIFY_IS_LIST_OF(v1, Type); \
QLinkedList v2(v1.begin(), v1.end()); \
QVERIFY_IS_LIST_OF(v2, Type); \
QLinkedList v3(std::begin(v), std::end(v)); \
QVERIFY_IS_LIST_OF(v3, Type); \
} while (false) \
/*end*/
CHECK(int, 1, 2, 3);
CHECK(double, 1.0, 2.0, 3.0);
CHECK(QString, QStringLiteral("one"), QStringLiteral("two"), QStringLiteral("three"));
#undef QVERIFY_IS_LIST_OF
#undef CHECK
#else
QSKIP("This test requires C++17 Constructor Template Argument Deduction support enabled in the compiler.");
#endif
}
template<typename T>
void tst_QLinkedList::empty() const
{

View File

@ -1,4 +1,6 @@
CONFIG += testcase
TARGET = tst_qlist
QT = core testlib
qtConfig(c++14): CONFIG += c++14
qtConfig(c++1z): CONFIG += c++1z
SOURCES = $$PWD/tst_qlist.cpp

View File

@ -310,6 +310,7 @@ private slots:
void lastComplex() const;
void constFirst() const;
void constLast() const;
void cpp17ctad() const;
void beginOptimal() const;
void beginMovable() const;
void beginComplex() const;
@ -864,6 +865,33 @@ void tst_QList::constLast() const
QVERIFY(listCopy.isSharedWith(list));
}
void tst_QList::cpp17ctad() const
{
#ifdef __cpp_deduction_guides
#define QVERIFY_IS_LIST_OF(obj, Type) \
QVERIFY2((std::is_same<decltype(obj), QList<Type>>::value), \
QMetaType::typeName(qMetaTypeId<decltype(obj)::value_type>()))
#define CHECK(Type, One, Two, Three) \
do { \
const Type v[] = {One, Two, Three}; \
QList v1 = {One, Two, Three}; \
QVERIFY_IS_LIST_OF(v1, Type); \
QList v2(v1.begin(), v1.end()); \
QVERIFY_IS_LIST_OF(v2, Type); \
QList v3(std::begin(v), std::end(v)); \
QVERIFY_IS_LIST_OF(v3, Type); \
} while (false) \
/*end*/
CHECK(int, 1, 2, 3);
CHECK(double, 1.0, 2.0, 3.0);
CHECK(QString, QStringLiteral("one"), QStringLiteral("two"), QStringLiteral("three"));
#undef QVERIFY_IS_LIST_OF
#undef CHECK
#else
QSKIP("This test requires C++17 Constructor Template Argument Deduction support enabled in the compiler.");
#endif
}
template<typename T>
void tst_QList::last() const
{

View File

@ -1,6 +1,8 @@
CONFIG += testcase
TARGET = tst_qset
QT = core testlib
qtConfig(c++14): CONFIG += c++14
qtConfig(c++1z): CONFIG += c++1z
SOURCES = tst_qset.cpp
DEFINES -= QT_NO_JAVA_STYLE_ITERATORS

View File

@ -54,6 +54,7 @@ private slots:
void detach();
void isDetached();
void clear();
void cpp17ctad();
void remove();
void contains();
void containsSet();
@ -325,6 +326,33 @@ void tst_QSet::clear()
QVERIFY(set2.size() == 0);
}
void tst_QSet::cpp17ctad()
{
#ifdef __cpp_deduction_guides
#define QVERIFY_IS_SET_OF(obj, Type) \
QVERIFY2((std::is_same<decltype(obj), QSet<Type>>::value), \
QMetaType::typeName(qMetaTypeId<decltype(obj)::value_type>()))
#define CHECK(Type, One, Two, Three) \
do { \
const Type v[] = {One, Two, Three}; \
QSet v1 = {One, Two, Three}; \
QVERIFY_IS_SET_OF(v1, Type); \
QSet v2(v1.begin(), v1.end()); \
QVERIFY_IS_SET_OF(v2, Type); \
QSet v3(std::begin(v), std::end(v)); \
QVERIFY_IS_SET_OF(v3, Type); \
} while (false) \
/*end*/
CHECK(int, 1, 2, 3);
CHECK(double, 1.0, 2.0, 3.0);
CHECK(QString, QStringLiteral("one"), QStringLiteral("two"), QStringLiteral("three"));
#undef QVERIFY_IS_SET_OF
#undef CHECK
#else
QSKIP("This test requires C++17 Constructor Template Argument Deduction support enabled in the compiler.");
#endif
}
void tst_QSet::remove()
{
QSet<QString> set1;

View File

@ -1,4 +1,6 @@
CONFIG += testcase
TARGET = tst_qvarlengtharray
QT = core testlib
qtConfig(c++14): CONFIG += c++14
qtConfig(c++1z): CONFIG += c++1z
SOURCES = tst_qvarlengtharray.cpp

View File

@ -44,6 +44,7 @@ private slots:
void realloc();
void reverseIterators();
void count();
void cpp17ctad();
void first();
void last();
void squeeze();
@ -717,6 +718,34 @@ void tst_QVarLengthArray::count()
}
}
void tst_QVarLengthArray::cpp17ctad()
{
#ifdef __cpp_deduction_guides
#define QVERIFY_IS_VLA_OF(obj, Type) \
QVERIFY2((std::is_same<decltype(obj), QVarLengthArray<Type>>::value), \
QMetaType::typeName(qMetaTypeId<decltype(obj)::value_type>()))
#define CHECK(Type, One, Two, Three) \
do { \
const Type v[] = {One, Two, Three}; \
QVarLengthArray v1 = {One, Two, Three}; \
QVERIFY_IS_VLA_OF(v1, Type); \
QVarLengthArray v2(v1.begin(), v1.end()); \
QVERIFY_IS_VLA_OF(v2, Type); \
QVarLengthArray v3(std::begin(v), std::end(v)); \
QVERIFY_IS_VLA_OF(v3, Type); \
} while (false) \
/*end*/
CHECK(int, 1, 2, 3);
CHECK(double, 1.0, 2.0, 3.0);
CHECK(QString, QStringLiteral("one"), QStringLiteral("two"), QStringLiteral("three"));
#undef QVERIFY_IS_VLA_OF
#undef CHECK
#else
QSKIP("This test requires C++17 Constructor Template Argument Deduction support enabled in the compiler.");
#endif
}
void tst_QVarLengthArray::first()
{
// append some items, make sure it stays sane

View File

@ -1,5 +1,7 @@
CONFIG += testcase
qtConfig(c++11): CONFIG += c++11
qtConfig(c++14): CONFIG += c++14
qtConfig(c++1z): CONFIG += c++1z
TARGET = tst_qvector
QT = core testlib
SOURCES = $$PWD/tst_qvector.cpp

View File

@ -230,6 +230,7 @@ private slots:
void countInt() const;
void countMovable() const;
void countCustom() const;
void cpp17ctad() const;
void data() const;
void emptyInt() const;
void emptyMovable() const;
@ -914,6 +915,33 @@ void tst_QVector::countCustom() const
QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
void tst_QVector::cpp17ctad() const
{
#ifdef __cpp_deduction_guides
#define QVERIFY_IS_VECTOR_OF(obj, Type) \
QVERIFY2((std::is_same<decltype(obj), QVector<Type>>::value), \
QMetaType::typeName(qMetaTypeId<decltype(obj)::value_type>()))
#define CHECK(Type, One, Two, Three) \
do { \
const Type v[] = {One, Two, Three}; \
QVector v1 = {One, Two, Three}; \
QVERIFY_IS_VECTOR_OF(v1, Type); \
QVector v2(v1.begin(), v1.end()); \
QVERIFY_IS_VECTOR_OF(v2, Type); \
QVector v3(std::begin(v), std::end(v)); \
QVERIFY_IS_VECTOR_OF(v3, Type); \
} while (false) \
/*end*/
CHECK(int, 1, 2, 3);
CHECK(double, 1.0, 2.0, 3.0);
CHECK(QString, QStringLiteral("one"), QStringLiteral("two"), QStringLiteral("three"));
#undef QVERIFY_IS_VECTOR_OF
#undef CHECK
#else
QSKIP("This test requires C++17 Constructor Template Argument Deduction support enabled in the compiler.");
#endif
}
void tst_QVector::data() const
{
QVector<int> myvec;