📄 qhash.h
字号:
} else { node = new (d->allocateNode()) Node(akey, avalue); } node->h = ah; node->next = *anextNode; *anextNode = node; ++d->size; return node;}template <class Key, class T>Q_INLINE_TEMPLATE QHash<Key, T> &QHash<Key, T>::unite(const QHash<Key, T> &other){ QHash<Key, T> copy(other); const_iterator it = copy.constEnd(); while (it != copy.constBegin()) { --it; insertMulti(it.key(), it.value()); } return *this;}template <class Key, class T>Q_OUTOFLINE_TEMPLATE void QHash<Key, T>::freeData(QHashData *x){ Node *e_for_x = reinterpret_cast<Node *>(x); Node **bucket = reinterpret_cast<Node **>(x->buckets); int n = x->numBuckets; while (n--) { Node *cur = *bucket++; while (cur != e_for_x) { Node *next = cur->next; deleteNode(cur); cur = next; } } x->destroyAndFree();}template <class Key, class T>Q_INLINE_TEMPLATE void QHash<Key, T>::clear(){ *this = QHash<Key,T>();}template <class Key, class T>Q_OUTOFLINE_TEMPLATE void QHash<Key, T>::detach_helper(){ QHashData *x = d->detach_helper(duplicateNode, QTypeInfo<T>::isDummy ? sizeof(DummyNode) : sizeof(Node)); x = qAtomicSetPtr(&d, x); if (!x->ref.deref()) freeData(x);}template <class Key, class T>Q_INLINE_TEMPLATE QHash<Key, T> &QHash<Key, T>::operator=(const QHash<Key, T> &other){ if (d != other.d) { QHashData *x = other.d; x->ref.ref(); x = qAtomicSetPtr(&d, x); if (!x->ref.deref()) freeData(x); if (!d->sharable) detach_helper(); } return *this;}template <class Key, class T>Q_INLINE_TEMPLATE const T QHash<Key, T>::value(const Key &akey) const{ Node *node; if (d->size == 0 || (node = *findNode(akey)) == e) { return T(); } else { return node->value; }}template <class Key, class T>Q_INLINE_TEMPLATE const T QHash<Key, T>::value(const Key &akey, const T &adefaultValue) const{ Node *node; if (d->size == 0 || (node = *findNode(akey)) == e) { return adefaultValue; } else { return node->value; }}template <class Key, class T>Q_OUTOFLINE_TEMPLATE QList<Key> QHash<Key, T>::uniqueKeys() const{ QList<Key> res; const_iterator i = begin(); if (i != end()) { for (;;) { const Key &aKey = i.key(); res.append(aKey); do { if (++i == end()) goto break_out_of_outer_loop; } while (aKey == i.key()); } }break_out_of_outer_loop: return res;}template <class Key, class T>Q_OUTOFLINE_TEMPLATE QList<Key> QHash<Key, T>::keys() const{ QList<Key> res; const_iterator i = begin(); while (i != end()) { res.append(i.key()); ++i; } return res;}template <class Key, class T>Q_OUTOFLINE_TEMPLATE QList<Key> QHash<Key, T>::keys(const T &avalue) const{ QList<Key> res; const_iterator i = begin(); while (i != end()) { if (i.value() == avalue) res.append(i.key()); ++i; } return res;}template <class Key, class T>Q_OUTOFLINE_TEMPLATE const Key QHash<Key, T>::key(const T &avalue) const{ return key(avalue, Key());}template <class Key, class T>Q_OUTOFLINE_TEMPLATE const Key QHash<Key, T>::key(const T &avalue, const Key &defaultValue) const{ const_iterator i = begin(); while (i != end()) { if (i.value() == avalue) return i.key(); ++i; } return defaultValue;}template <class Key, class T>Q_OUTOFLINE_TEMPLATE QList<T> QHash<Key, T>::values() const{ QList<T> res; const_iterator i = begin(); while (i != end()) { res.append(i.value()); ++i; } return res;}template <class Key, class T>Q_OUTOFLINE_TEMPLATE QList<T> QHash<Key, T>::values(const Key &akey) const{ QList<T> res; Node *node = *findNode(akey); if (node != e) { do { res.append(node->value); } while ((node = node->next) != e && node->key == akey); } return res;}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);}template <class Key, class T>Q_INLINE_TEMPLATE T &QHash<Key, T>::operator[](const Key &akey){ detach(); d->mightGrow(); uint h; Node **node = findNode(akey, &h); if (*node == e) return createNode(h, akey, T(), node)->value; return (*node)->value;}template <class Key, class T>Q_INLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::insert(const Key &akey, const T &avalue){ detach(); d->mightGrow(); uint h; Node **node = findNode(akey, &h); if (*node == e) return iterator(createNode(h, akey, avalue, node)); if (!QTypeInfo<T>::isDummy) (*node)->value = avalue; return iterator(*node);}template <class Key, class T>Q_INLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::insertMulti(const Key &akey, const T &avalue){ detach(); d->mightGrow(); uint h; Node **nextNode = findNode(akey, &h); return iterator(createNode(h, akey, avalue, nextNode));}template <class Key, class T>Q_OUTOFLINE_TEMPLATE int QHash<Key, T>::remove(const Key &akey){ detach(); int oldSize = d->size; Node **node = findNode(akey); if (*node != e) { bool deleteNext = true; do { Node *next = (*node)->next; deleteNext = (next != e && next->key == (*node)->key); deleteNode(*node); *node = next; --d->size; } while (deleteNext); d->hasShrunk(); } return oldSize - d->size;}template <class Key, class T>Q_OUTOFLINE_TEMPLATE T QHash<Key, T>::take(const Key &akey){ detach(); Node **node = findNode(akey); if (*node != e) { T t = (*node)->value; Node *next = (*node)->next; deleteNode(*node); *node = next; --d->size; d->hasShrunk(); return t; } return T();}template <class Key, class T>Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::erase(iterator it){ if (it == iterator(e)) return it; iterator ret = it; ++ret; Node *node = it; Node **node_ptr = reinterpret_cast<Node **>(&d->buckets[node->h % d->numBuckets]); while (*node_ptr != node) node_ptr = &(*node_ptr)->next; *node_ptr = node->next; deleteNode(node); --d->size; return ret;}template <class Key, class T>Q_INLINE_TEMPLATE void QHash<Key, T>::reserve(int asize){ detach(); d->rehash(-qMax(asize, 1));}template <class Key, class T>Q_INLINE_TEMPLATE typename QHash<Key, T>::const_iterator QHash<Key, T>::find(const Key &akey) const{ return const_iterator(*findNode(akey));}template <class Key, class T>Q_INLINE_TEMPLATE typename QHash<Key, T>::const_iterator QHash<Key, T>::constFind(const Key &akey) const{ return const_iterator(*findNode(akey));}template <class Key, class T>Q_INLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::find(const Key &akey){ detach(); return iterator(*findNode(akey));}template <class Key, class T>Q_INLINE_TEMPLATE bool QHash<Key, T>::contains(const Key &akey) const{ return *findNode(akey) != e;}template <class Key, class T>Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::Node **QHash<Key, T>::findNode(const Key &akey, uint *ahp) const{ Node **node; uint h = qHash(akey); if (d->numBuckets) { node = reinterpret_cast<Node **>(&d->buckets[h % d->numBuckets]); Q_ASSERT(*node == e || (*node)->next); while (*node != e && !(*node)->same_key(h, akey)) node = &(*node)->next; } else { node = const_cast<Node **>(reinterpret_cast<const Node * const *>(&e)); } if (ahp) *ahp = h; return node;}template <class Key, class T>Q_OUTOFLINE_TEMPLATE bool QHash<Key, T>::operator==(const QHash<Key, T> &other) const{ if (size() != other.size()) return false; if (d == other.d) return true; const_iterator it = begin(); while (it != end()) { const Key &akey = it.key(); const_iterator it2 = other.find(akey); do { if (it2 == other.end() || !(it2.key() == akey)) return false; if (!QTypeInfo<T>::isDummy && !(it.value() == it2.value())) return false; ++it; ++it2; } while (it != end() && it.key() == akey); } return true;}template <class Key, class T>class QMultiHash : public QHash<Key, T>{public: QMultiHash() {} QMultiHash(const QHash<Key, T> &other) : QHash<Key, T>(other) {} inline typename QHash<Key, T>::iterator replace(const Key &key, const T &value) { return QHash<Key, T>::insert(key, value); } inline typename QHash<Key, T>::iterator insert(const Key &key, const T &value) { return QHash<Key, T>::insertMulti(key, value); } inline QMultiHash &operator+=(const QMultiHash &other) { unite(other); return *this; } inline QMultiHash operator+(const QMultiHash &other) const { QMultiHash result = *this; result += other; return result; }#ifndef Q_NO_USING_KEYWORD using QHash<Key, T>::contains; using QHash<Key, T>::remove; using QHash<Key, T>::count; using QHash<Key, T>::find; using QHash<Key, T>::constFind;#else inline bool contains(const Key &key) const { return QHash<Key, T>::contains(key); } inline int remove(const Key &key) { return QHash<Key, T>::remove(key); } inline int count(const Key &key) const { return QHash<Key, T>::count(key); } inline int count() const { return QHash<Key, T>::count(); } inline typename QHash<Key, T>::iterator find(const Key &key) { return QHash<Key, T>::find(key); } inline typename QHash<Key, T>::const_iterator find(const Key &key) const { return QHash<Key, T>::find(key); } inline typename QHash<Key, T>::const_iterator constFind(const Key &key) const { return QHash<Key, T>::constFind(key); }#endif bool contains(const Key &key, const T &value) const; int remove(const Key &key, const T &value); int count(const Key &key, const T &value) const; typename QHash<Key, T>::iterator find(const Key &key, const T &value) { typename QHash<Key, T>::iterator i(find(key)); typename QHash<Key, T>::iterator end(this->end()); while (i != end && i.key() == key) { if (i.value() == value) return i; ++i; } return end; } typename QHash<Key, T>::const_iterator find(const Key &key, const T &value) const { typename QHash<Key, T>::const_iterator i(constFind(key)); typename QHash<Key, T>::const_iterator end(QHash<Key, T>::constEnd()); while (i != end && i.key() == key) { if (i.value() == value) return i; ++i; } return end; } typename QHash<Key, T>::const_iterator constFind(const Key &key, const T &value) const { return find(key, value); }private: T &operator[](const Key &key); const T operator[](const Key &key) const;};template <class Key, class T>Q_INLINE_TEMPLATE bool QMultiHash<Key, T>::contains(const Key &key, const T &value) const{ return constFind(key, value) != QHash<Key, T>::constEnd();}template <class Key, class T>Q_INLINE_TEMPLATE int QMultiHash<Key, T>::remove(const Key &key, const T &value){ int n = 0; typename QHash<Key, T>::iterator i(find(key)); typename QHash<Key, T>::const_iterator end(QHash<Key, T>::constEnd()); while (i != end && i.key() == key) { if (i.value() == value) { i = erase(i); ++n; } else { ++i; } } return n;}template <class Key, class T>Q_INLINE_TEMPLATE int QMultiHash<Key, T>::count(const Key &key, const T &value) const{ int n = 0; typename QHash<Key, T>::const_iterator i(constFind(key)); typename QHash<Key, T>::const_iterator end(QHash<Key, T>::constEnd()); while (i != end && i.key() == key) { if (i.value() == value) ++n; ++i; } return n;}Q_DECLARE_ASSOCIATIVE_ITERATOR(Hash)Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(Hash)QT_END_HEADER#endif // QHASH_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -