diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2016-03-03 20:20:42 +0100 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2019-04-25 00:10:03 +0000 |
commit | e6d9617c79ea029cf60c5555a3d7a32bac1cdbf6 (patch) | |
tree | 242d90982565d2aa3c1870297ca80dffa6d30a97 /src | |
parent | f10d37c9c10c323c37d5ec617588348458e7286f (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.h | 43 | ||||
-rw-r--r-- | src/corelib/tools/qhash.cpp | 22 | ||||
-rw-r--r-- | src/corelib/tools/qhash.h | 43 |
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! |