summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2016-03-03 20:20:42 +0100
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2019-04-25 00:10:03 +0000
commite6d9617c79ea029cf60c5555a3d7a32bac1cdbf6 (patch)
tree242d90982565d2aa3c1870297ca80dffa6d30a97 /src
parentf10d37c9c10c323c37d5ec617588348458e7286f (diff)
QHash/QMultiHash: add range constructors
QMap and QMultiMap will go in a separate commit, due to QMap's insertion behavior that "reverses" the inserted elements. [ChangeLog][QtCore][QHash] Added range constructor. [ChangeLog][QtCore][QMultiHash] Added range constructor. Change-Id: Icfd0d0afde27792e8439ed6df3e8774696b134d3 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Sérgio Martins <sergio.martins@kdab.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
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!