summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qcontainertools_impl.h43
-rw-r--r--src/corelib/tools/qhash.cpp22
-rw-r--r--src/corelib/tools/qhash.h43
3 files changed, 108 insertions, 0 deletions
diff --git a/src/corelib/tools/qcontainertools_impl.h b/src/corelib/tools/qcontainertools_impl.h
index c2de50b145..86a16eb32b 100644
--- a/src/corelib/tools/qcontainertools_impl.h
+++ b/src/corelib/tools/qcontainertools_impl.h
@@ -84,6 +84,49 @@ void reserveIfForwardIterator(Container *c, ForwardIterator f, ForwardIterator l
{
c->reserve(static_cast<typename Container::size_type>(std::distance(f, l)));
}
+
+// for detecting expression validity
+template <typename ... T>
+using void_t = void;
+
+template <typename Iterator, typename = void_t<>>
+struct AssociativeIteratorHasKeyAndValue : std::false_type
+{
+};
+
+template <typename Iterator>
+struct AssociativeIteratorHasKeyAndValue<
+ Iterator,
+ void_t<decltype(std::declval<Iterator &>().key()),
+ decltype(std::declval<Iterator &>().value())>
+ >
+ : std::true_type
+{
+};
+
+template <typename Iterator, typename = void_t<>, typename = void_t<>>
+struct AssociativeIteratorHasFirstAndSecond : std::false_type
+{
+};
+
+template <typename Iterator>
+struct AssociativeIteratorHasFirstAndSecond<
+ Iterator,
+ void_t<decltype(std::declval<Iterator &>()->first),
+ decltype(std::declval<Iterator &>()->second)>
+ >
+ : std::true_type
+{
+};
+
+template <typename Iterator>
+using IfAssociativeIteratorHasKeyAndValue =
+ typename std::enable_if<AssociativeIteratorHasKeyAndValue<Iterator>::value, bool>::type;
+
+template <typename Iterator>
+using IfAssociativeIteratorHasFirstAndSecond =
+ typename std::enable_if<AssociativeIteratorHasFirstAndSecond<Iterator>::value, bool>::type;
+
} // namespace QtPrivate
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index dd22a38be1..5c7e535c30 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -1251,6 +1251,17 @@ uint qHash(long double key, uint seed) noexcept
compiled in C++11 mode.
*/
+/*! \fn template <class Key, class T> template <class InputIterator> QHash<Key, T>::QHash(InputIterator begin, InputIterator end)
+ \since 5.14
+
+ Constructs a hash with a copy of each of the elements in the iterator range
+ [\a begin, \a end). Either the elements iterated by the range must be
+ objects with \c{first} and \c{second} data members (like \c{QPair},
+ \c{std::pair}, etc.) convertible to \c Key and to \c T respectively; or the
+ iterators must have \c{key()} and \c{value()} member functions, returning a
+ key convertible to \c Key and a value convertible to \c T respectively.
+*/
+
/*! \fn template <class Key, class T> QHash<Key, T>::QHash(const QHash &other)
Constructs a copy of \a other.
@@ -2586,6 +2597,17 @@ uint qHash(long double key, uint seed) noexcept
\sa operator=()
*/
+/*! \fn template <class Key, class T> template <class InputIterator> QMultiHash::QMultiHash(InputIterator begin, InputIterator end)
+ \since 5.14
+
+ Constructs a multi-hash with a copy of each of the elements in the iterator range
+ [\a begin, \a end). Either the elements iterated by the range must be
+ objects with \c{first} and \c{second} data members (like \c{QPair},
+ \c{std::pair}, etc.) convertible to \c Key and to \c T respectively; or the
+ iterators must have \c{key()} and \c{value()} member functions, returning a
+ key convertible to \c Key and a value convertible to \c T respectively.
+*/
+
/*! \fn template <class Key, class T> QMultiHash<Key, T>::iterator QMultiHash<Key, T>::replace(const Key &key, const T &value)
Inserts a new item with the \a key and a value of \a value.
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 120ee9cc85..a757e85386 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -46,6 +46,7 @@
#include <QtCore/qlist.h>
#include <QtCore/qrefcount.h>
#include <QtCore/qhashfunctions.h>
+#include <QtCore/qcontainertools_impl.h>
#ifdef Q_COMPILER_INITIALIZER_LISTS
#include <initializer_list>
@@ -259,6 +260,28 @@ public:
QHash &operator=(QHash &&other) noexcept
{ QHash moved(std::move(other)); swap(moved); return *this; }
#endif
+#ifdef Q_QDOC
+ template <typename InputIterator>
+ QHash(InputIterator f, InputIterator l);
+#else
+ template <typename InputIterator, QtPrivate::IfAssociativeIteratorHasKeyAndValue<InputIterator> = true>
+ QHash(InputIterator f, InputIterator l)
+ : QHash()
+ {
+ QtPrivate::reserveIfForwardIterator(this, f, l);
+ for (; f != l; ++f)
+ insert(f.key(), f.value());
+ }
+
+ template <typename InputIterator, QtPrivate::IfAssociativeIteratorHasFirstAndSecond<InputIterator> = true>
+ QHash(InputIterator f, InputIterator l)
+ : QHash()
+ {
+ QtPrivate::reserveIfForwardIterator(this, f, l);
+ for (; f != l; ++f)
+ insert(f->first, f->second);
+ }
+#endif
void swap(QHash &other) noexcept { qSwap(d, other.d); }
bool operator==(const QHash &other) const;
@@ -1029,6 +1052,26 @@ public:
insert(it->first, it->second);
}
#endif
+#ifdef Q_QDOC
+ template <typename InputIterator>
+ QMultiHash(InputIterator f, InputIterator l);
+#else
+ template <typename InputIterator, QtPrivate::IfAssociativeIteratorHasKeyAndValue<InputIterator> = true>
+ QMultiHash(InputIterator f, InputIterator l)
+ {
+ QtPrivate::reserveIfForwardIterator(this, f, l);
+ for (; f != l; ++f)
+ insert(f.key(), f.value());
+ }
+
+ template <typename InputIterator, QtPrivate::IfAssociativeIteratorHasFirstAndSecond<InputIterator> = true>
+ QMultiHash(InputIterator f, InputIterator l)
+ {
+ QtPrivate::reserveIfForwardIterator(this, f, l);
+ for (; f != l; ++f)
+ insert(f->first, f->second);
+ }
+#endif
// compiler-generated copy/move ctors/assignment operators are fine!
// compiler-generated destructor is fine!