summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-03-04 09:54:35 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2020-03-04 14:39:18 +0000
commit2a4b95778993b00499eb94f61a87330fdbadf947 (patch)
tree168147adcc2854cb6723335b5abffe9d7585c7f4 /src/corelib
parentb4e17a48646a1d2156b7d56ab6003db46af79cec (diff)
parent048f0a00fa7b46f531fbe3ed6d1babae9858e8c2 (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/global/qfloat16.cpp2
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp8
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h1
-rw-r--r--src/corelib/kernel/qwineventnotifier.cpp5
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp10
-rw-r--r--src/corelib/mimetypes/qmimeprovider_p.h5
-rw-r--r--src/corelib/text/qstring.cpp3
-rw-r--r--src/corelib/time/qdatetime.cpp24
-rw-r--r--src/corelib/tools/qhash.cpp8
-rw-r--r--src/corelib/tools/qhash.h43
-rw-r--r--src/corelib/tools/qiterator.h26
-rw-r--r--src/corelib/tools/qiterator.qdoc13
-rw-r--r--src/corelib/tools/qmap.cpp8
-rw-r--r--src/corelib/tools/qmap.h53
14 files changed, 126 insertions, 83 deletions
diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp
index 80a851e4e4..3d82bbe95a 100644
--- a/src/corelib/global/qfloat16.cpp
+++ b/src/corelib/global/qfloat16.cpp
@@ -147,7 +147,7 @@ QT_BEGIN_NAMESPACE
/*!
\since 5.15
- \fn qfloat16::copySign(qfloat16 sign) const noexcept
+ \fn qfloat16 qfloat16::copySign(qfloat16 sign) const noexcept
Returns a qfloat16 with the sign of \a sign but the rest of its value taken
from this qfloat16. Serves as qfloat16's equivalent of std::copysign().
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 8616631603..f2216d4113 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -884,7 +884,11 @@ void QEventDispatcherWin32::unregisterEventNotifier(QWinEventNotifier *notifier)
return;
}
#endif
+ doUnregisterEventNotifier(notifier);
+}
+void QEventDispatcherWin32::doUnregisterEventNotifier(QWinEventNotifier *notifier)
+{
Q_D(QEventDispatcherWin32);
int i = d->winEventNotifierList.indexOf(notifier);
@@ -996,6 +1000,10 @@ void QEventDispatcherWin32::closingDown()
doUnregisterSocketNotifier((*(d->sn_except.begin()))->obj);
Q_ASSERT(d->active_fd.isEmpty());
+ // clean up any eventnotifiers
+ while (!d->winEventNotifierList.isEmpty())
+ doUnregisterEventNotifier(d->winEventNotifierList.first());
+
// clean up any timers
for (int i = 0; i < d->timerVec.count(); ++i)
d->unregisterTimer(d->timerVec.at(i));
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index e6620178d8..a482c8b7db 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -110,6 +110,7 @@ protected:
QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0);
virtual void sendPostedEvents();
void doUnregisterSocketNotifier(QSocketNotifier *notifier);
+ void doUnregisterEventNotifier(QWinEventNotifier *notifier);
private:
friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp
index db5d44b276..0c574e9a4b 100644
--- a/src/corelib/kernel/qwineventnotifier.cpp
+++ b/src/corelib/kernel/qwineventnotifier.cpp
@@ -198,11 +198,8 @@ void QWinEventNotifier::setEnabled(bool enable)
d->enabled = enable;
QAbstractEventDispatcher *eventDispatcher = d->threadData.loadRelaxed()->eventDispatcher.loadRelaxed();
- if (!eventDispatcher) { // perhaps application is shutting down
- if (!enable && d->waitHandle != nullptr)
- d->unregisterWaitObject();
+ if (!eventDispatcher) // perhaps application is shutting down
return;
- }
if (Q_UNLIKELY(thread() != QThread::currentThread())) {
qWarning("QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread");
return;
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index 4aee772366..9dba72923a 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -664,7 +664,15 @@ QMimeXMLProvider::QMimeXMLProvider(QMimeDatabasePrivate *db, InternalDatabaseEnu
load(data, size);
}
-#endif
+#else // !QT_CONFIG(mimetype_database)
+// never called in release mode, but some debug builds may need
+// this to be defined.
+QMimeXMLProvider::QMimeXMLProvider(QMimeDatabasePrivate *db, InternalDatabaseEnum)
+ : QMimeProviderBase(db, QString())
+{
+ Q_UNREACHABLE();
+}
+#endif // QT_CONFIG(mimetype_database)
QMimeXMLProvider::QMimeXMLProvider(QMimeDatabasePrivate *db, const QString &directory)
: QMimeProviderBase(db, directory)
diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h
index c4e712b318..9c91903684 100644
--- a/src/corelib/mimetypes/qmimeprovider_p.h
+++ b/src/corelib/mimetypes/qmimeprovider_p.h
@@ -135,13 +135,10 @@ public:
enum InternalDatabaseEnum { InternalDatabase };
#if QT_CONFIG(mimetype_database)
enum : bool { InternalDatabaseAvailable = true };
- QMimeXMLProvider(QMimeDatabasePrivate *db, InternalDatabaseEnum);
#else
enum : bool { InternalDatabaseAvailable = false };
- QMimeXMLProvider(QMimeDatabasePrivate *db, InternalDatabaseEnum)
- : QMimeProviderBase(db, QString())
- { Q_UNREACHABLE(); };
#endif
+ QMimeXMLProvider(QMimeDatabasePrivate *db, InternalDatabaseEnum);
QMimeXMLProvider(QMimeDatabasePrivate *db, const QString &directory);
~QMimeXMLProvider();
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp
index da2c44bef6..757f248e8a 100644
--- a/src/corelib/text/qstring.cpp
+++ b/src/corelib/text/qstring.cpp
@@ -7626,7 +7626,10 @@ static ResultList splitString(const StringSource &source, const QChar *sep,
#if QT_DEPRECATED_SINCE(5, 15)
Qt::SplitBehavior mapSplitBehavior(QString::SplitBehavior sb)
{
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
return sb & QString::SkipEmptyParts ? Qt::SkipEmptyParts : Qt::KeepEmptyParts;
+QT_WARNING_POP
}
#endif
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index e9fe34110a..47539141bd 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -1383,6 +1383,10 @@ QT_WARNING_POP
If the datetime is invalid, an empty string will be returned.
+ \note If localized month and day names are desired, please switch to using
+ QLocale::system().toString() as QDate methods shall change to use English (C
+ locale) names at Qt 6.
+
\sa fromString(), QDateTime::toString(), QTime::toString(), QLocale::toString()
*/
@@ -1884,6 +1888,10 @@ QT_WARNING_POP
\snippet code/src_corelib_tools_qdatetime.cpp 3
+ \note If localized month and day names are used, please switch to using
+ QLocale::system().toDate() as QDate methods shall change to only recognize
+ English (C locale) names at Qt 6.
+
\sa toString(), QDateTime::fromString(), QTime::fromString(),
QLocale::toDate()
*/
@@ -2244,6 +2252,10 @@ QT_WARNING_POP
If the time is invalid, an empty string will be returned.
If \a format is empty, the default format "hh:mm:ss" is used.
+ \note If localized forms of am or pm (the AP, ap, A or a formats) are
+ desired, please switch to using QLocale::system().toString() as QTime
+ methods shall change to use English (C locale) at Qt 6.
+
\sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString()
*/
QString QTime::toString(QStringView format) const
@@ -2641,6 +2653,10 @@ QT_WARNING_POP
\snippet code/src_corelib_tools_qdatetime.cpp 8
+ \note If localized forms of am or pm (the AP, ap, A or a formats) are used,
+ please switch to using QLocale::system().toTime() as QTime methods shall
+ change to only recognize English (C locale) at Qt 6.
+
\sa toString(), QDateTime::fromString(), QDate::fromString(),
QLocale::toTime()
*/
@@ -4541,6 +4557,10 @@ QT_WARNING_POP
If the datetime is invalid, an empty string will be returned.
+ \note If localized month and day names are desired, please switch to using
+ QLocale::system().toString() as QDateTime methods shall change to use
+ English (C locale) names at Qt 6.
+
\sa fromString(), QDate::toString(), QTime::toString(), QLocale::toString()
*/
QString QDateTime::toString(QStringView format) const
@@ -5580,6 +5600,10 @@ QT_WARNING_POP
\snippet code/src_corelib_tools_qdatetime.cpp 14
+ \note If localized month and day names are used, please switch to using
+ QLocale::system().toDateTime() as QDateTime methods shall change to only
+ recognize English (C locale) names at Qt 6.
+
\sa toString(), QDate::fromString(), QTime::fromString(),
QLocale::toDateTime()
*/
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 15f731a603..7ebc374d9f 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -1574,7 +1574,6 @@ uint qHash(long double key, uint seed) noexcept
*/
/*! \fn template <class Key, class T> int QHash<Key, T>::count(const Key &key) const
- \obsolete
Returns the number of items associated with the \a key.
@@ -2693,13 +2692,6 @@ uint qHash(long double key, uint seed) noexcept
\sa QHash::remove()
*/
-/*! \fn template <class Key, class T> int QMultiHash<Key, T>::count(const Key &key) const
-
- Returns the number of items associated with the \a key.
-
- \sa contains(), insert()
-*/
-
/*!
\fn template <class Key, class T> int QMultiHash<Key, T>::count(const Key &key, const T &value) const
\since 4.3
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 59883e3968..c87cf56988 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -309,10 +309,10 @@ public:
QList<Key> keys(const T &value) const;
QList<T> values() const;
#if QT_DEPRECATED_SINCE(5, 15)
- QT_DEPRECATED_X("Use QMultiHash for hashes storing multiple values with the same key.") QList<Key> uniqueKeys() const;
- QT_DEPRECATED_X("Use QMultiHash for hashes storing multiple values with the same key.") QList<T> values(const Key &key) const;
- QT_DEPRECATED_X("Use QMultiHash for hashes storing multiple values with the same key.") int count(const Key &key) const;
+ QT_DEPRECATED_VERSION_X_5_15("Use QMultiHash for hashes storing multiple values with the same key.") QList<Key> uniqueKeys() const;
+ QT_DEPRECATED_VERSION_X_5_15("Use QMultiHash for hashes storing multiple values with the same key.") QList<T> values(const Key &key) const;
#endif
+ int count(const Key &key) const;
class const_iterator;
@@ -512,8 +512,8 @@ public:
iterator insert(const Key &key, const T &value);
void insert(const QHash &hash);
#if QT_DEPRECATED_SINCE(5, 15)
- QT_DEPRECATED_X("Use QMultiHash for hashes storing multiple values with the same key.") iterator insertMulti(const Key &key, const T &value);
- QT_DEPRECATED_X("Use QMultiHash for hashes storing multiple values with the same key.") QHash &unite(const QHash &other);
+ QT_DEPRECATED_VERSION_X_5_15("Use QMultiHash for hashes storing multiple values with the same key.") iterator insertMulti(const Key &key, const T &value);
+ QT_DEPRECATED_VERSION_X_5_15("Use QMultiHash for hashes storing multiple values with the same key.") QHash &unite(const QHash &other);
#endif
// STL compatibility
@@ -711,6 +711,19 @@ Q_OUTOFLINE_TEMPLATE QList<T> QHash<Key, T>::values() const
}
template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE int QHash<Key, T>::count(const Key &akey) const
+{
+ int cnt = 0;
+ Node *node = *findNode(akey);
+ if (node != e) {
+ do {
+ ++cnt;
+ } while ((node = node->next) != e && node->key == akey);
+ }
+ return cnt;
+}
+
+template <class Key, class T>
Q_INLINE_TEMPLATE const T QHash<Key, T>::operator[](const Key &akey) const
{
return value(akey);
@@ -1053,7 +1066,6 @@ public:
int remove(const Key &key, const T &value);
- int count(const Key &key) const;
int count(const Key &key, const T &value) const;
QList<Key> uniqueKeys() const;
@@ -1207,12 +1219,6 @@ Q_OUTOFLINE_TEMPLATE QList<T> QHash<Key, T>::values(const Key &akey) const
}
template <class Key, class T>
-Q_OUTOFLINE_TEMPLATE int QHash<Key, T>::count(const Key &akey) const
-{
- return static_cast<const QMultiHash<Key, T> *>(this)->count(akey);
-}
-
-template <class Key, class T>
Q_OUTOFLINE_TEMPLATE QList<Key> QHash<Key, T>::uniqueKeys() const
{
return static_cast<const QMultiHash<Key, T> *>(this)->uniqueKeys();
@@ -1232,19 +1238,6 @@ Q_OUTOFLINE_TEMPLATE QList<T> QMultiHash<Key, T>::values(const Key &akey) const
return res;
}
-template <class Key, class T>
-Q_OUTOFLINE_TEMPLATE int QMultiHash<Key, T>::count(const Key &akey) const
-{
- int cnt = 0;
- Node *node = *findNode(akey);
- if (node != this->e) {
- do {
- ++cnt;
- } while ((node = node->next) != this->e && node->key == akey);
- }
- return cnt;
-}
-
#if !defined(QT_NO_JAVA_STYLE_ITERATORS)
template <class Key, class T>
class QHashIterator
diff --git a/src/corelib/tools/qiterator.h b/src/corelib/tools/qiterator.h
index 84a0e116ca..c4665c7c87 100644
--- a/src/corelib/tools/qiterator.h
+++ b/src/corelib/tools/qiterator.h
@@ -195,7 +195,6 @@ public:
typedef typename Iterator::iterator_category iterator_category;
typedef typename Iterator::difference_type difference_type;
typedef std::pair<Key, T> value_type;
- typedef const value_type *pointer;
typedef const value_type &reference;
QKeyValueIterator() = default;
@@ -206,6 +205,31 @@ public:
return std::pair<Key, T>(i.key(), i.value());
}
+ struct pointer {
+ pointer(value_type&& r_)
+ : r(std::move(r_))
+ {}
+
+ pointer() = default;
+ pointer(const pointer &other) = default;
+ pointer(pointer &&other) = default;
+ pointer& operator=(const pointer &other) = default;
+ pointer& operator=(pointer &&other) = default;
+
+ value_type& operator*() const {
+ return r;
+ }
+
+ value_type r;
+ const value_type *operator->() const {
+ return &r;
+ }
+ };
+
+ pointer operator->() const {
+ return pointer(std::pair<Key, T>(i.key(), i.value()));
+ }
+
friend bool operator==(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept { return lhs.i == rhs.i; }
friend bool operator!=(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept { return lhs.i != rhs.i; }
diff --git a/src/corelib/tools/qiterator.qdoc b/src/corelib/tools/qiterator.qdoc
index 69f9d52ce5..8cfa665ffd 100644
--- a/src/corelib/tools/qiterator.qdoc
+++ b/src/corelib/tools/qiterator.qdoc
@@ -57,7 +57,7 @@
\internal
*/
-/*! \typedef QKeyValueIterator::pointer
+/*! \struct QKeyValueIterator::pointer
\internal
*/
@@ -75,11 +75,20 @@
Constructs a QKeyValueIterator on top of \a o.
*/
-/*! \fn template<typename Key, typename T, class Iterator> const T &QKeyValueIterator<Key, T, Iterator>::operator*() const
+/*! \fn template<typename Key, typename T, class Iterator> std::pair<Key, T> QKeyValueIterator<Key, T, Iterator>::operator*() const
Returns the current entry as a pair.
*/
+/*! \fn template<typename Key, typename T, class Iterator> pointer QKeyValueIterator<Key, T, Iterator>::operator->() const
+
+ Returns the current entry as a pointer-like object to the pair.
+
+ \since 5.15
+
+ \sa operator*()
+*/
+
/*! \fn template<typename Key, typename T, class Iterator> bool operator==(QKeyValueIterator<Key, T, Iterator> lhs, QKeyValueIterator<Key, T, Iterator> rhs)
\relates QKeyValueIterator
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index 6d2b8f7a3e..25ea5f25d7 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -814,11 +814,10 @@ void QMapDataBase::freeData(QMapDataBase *d)
*/
/*! \fn template <class Key, class T> int QMap<Key, T>::count(const Key &key) const
- \obsolete
Returns the number of items associated with key \a key.
- \sa QMultiMap::count()
+ \sa contains(), QMultiMap::count()
*/
/*! \fn template <class Key, class T> int QMap<Key, T>::count() const
@@ -2115,11 +2114,6 @@ void QMapDataBase::freeData(QMapDataBase *d)
inserted one.
*/
-/*! \fn template <class Key, class T> int QMultiMap<Key, T>::count(const Key &key) const
-
- Returns the number of items associated with key \a key.
-*/
-
/*! \fn template <class Key, class T> QList<Key> QMultiMap<Key, T>::uniqueKeys() const
\since 4.2
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index a971919e54..6081019294 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -373,10 +373,10 @@ public:
QList<Key> keys(const T &value) const;
QList<T> values() const;
#if QT_DEPRECATED_SINCE(5, 15)
- QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") QList<Key> uniqueKeys() const;
- QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") QList<T> values(const Key &key) const;
- QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") int count(const Key &key) const;
+ QT_DEPRECATED_VERSION_X_5_15("Use QMultiMap for maps storing multiple values with the same key.") QList<Key> uniqueKeys() const;
+ QT_DEPRECATED_VERSION_X_5_15("Use QMultiMap for maps storing multiple values with the same key.") QList<T> values(const Key &key) const;
#endif
+ int count(const Key &key) const;
inline const Key &firstKey() const { Q_ASSERT(!isEmpty()); return constBegin().key(); }
@@ -559,9 +559,9 @@ public:
iterator insert(const_iterator pos, const Key &key, const T &value);
void insert(const QMap<Key, T> &map);
#if QT_DEPRECATED_SINCE(5, 15)
- QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") iterator insertMulti(const Key &key, const T &value);
- QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") iterator insertMulti(const_iterator pos, const Key &akey, const T &avalue);
- QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") QMap<Key, T> &unite(const QMap<Key, T> &other);
+ QT_DEPRECATED_VERSION_X_5_15("Use QMultiMap for maps storing multiple values with the same key.") iterator insertMulti(const Key &key, const T &value);
+ QT_DEPRECATED_VERSION_X_5_15("Use QMultiMap for maps storing multiple values with the same key.") iterator insertMulti(const_iterator pos, const Key &akey, const T &avalue);
+ QT_DEPRECATED_VERSION_X_5_15("Use QMultiMap for maps storing multiple values with the same key.") QMap<Key, T> &unite(const QMap<Key, T> &other);
#endif
// STL compatibility
@@ -655,6 +655,23 @@ Q_INLINE_TEMPLATE T &QMap<Key, T>::operator[](const Key &akey)
}
template <class Key, class T>
+Q_INLINE_TEMPLATE int QMap<Key, T>::count(const Key &akey) const
+{
+ Node *firstNode;
+ Node *lastNode;
+ d->nodeRange(akey, &firstNode, &lastNode);
+
+ const_iterator ci_first(firstNode);
+ const const_iterator ci_last(lastNode);
+ int cnt = 0;
+ while (ci_first != ci_last) {
+ ++cnt;
+ ++ci_first;
+ }
+ return cnt;
+}
+
+template <class Key, class T>
Q_INLINE_TEMPLATE bool QMap<Key, T>::contains(const Key &akey) const
{
return d->findNode(akey) != nullptr;
@@ -1116,7 +1133,6 @@ public:
int remove(const Key &key, const T &value);
- int count(const Key &key) const;
int count(const Key &key, const T &value) const;
typename QMap<Key, T>::iterator find(const Key &key, const T &value) {
@@ -1290,23 +1306,6 @@ Q_INLINE_TEMPLATE int QMultiMap<Key, T>::remove(const Key &key, const T &value)
}
template <class Key, class T>
-Q_INLINE_TEMPLATE int QMultiMap<Key, T>::count(const Key &akey) const
-{
- QMultiMap::Node *firstNode;
- QMultiMap::Node *lastNode;
- this->d->nodeRange(akey, &firstNode, &lastNode);
-
- typename QMap<Key, T>::const_iterator ci_first(firstNode);
- const typename QMap<Key, T>::const_iterator ci_last(lastNode);
- int cnt = 0;
- while (ci_first != ci_last) {
- ++cnt;
- ++ci_first;
- }
- return cnt;
-}
-
-template <class Key, class T>
Q_INLINE_TEMPLATE int QMultiMap<Key, T>::count(const Key &key, const T &value) const
{
int n = 0;
@@ -1334,12 +1333,6 @@ QList<T> QMap<Key, T>::values(const Key &key) const
}
template<class Key, class T>
-int QMap<Key, T>::count(const Key &key) const
-{
- return static_cast<const QMultiMap<Key, T> *>(this)->count(key);
-}
-
-template<class Key, class T>
typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const Key &key, const T &value)
{
return static_cast<QMultiMap<Key, T> *>(this)->insert(key, value);