67 inline uint qHash(uint key) { return key; } |
67 inline uint qHash(uint key) { return key; } |
68 inline uint qHash(int key) { return uint(key); } |
68 inline uint qHash(int key) { return uint(key); } |
69 inline uint qHash(ulong key) |
69 inline uint qHash(ulong key) |
70 { |
70 { |
71 if (sizeof(ulong) > sizeof(uint)) { |
71 if (sizeof(ulong) > sizeof(uint)) { |
72 return uint((key >> (8 * sizeof(uint) - 1)) ^ key); |
72 return uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)); |
73 } else { |
73 } else { |
74 return uint(key); |
74 return uint(key & (~0U)); |
75 } |
75 } |
76 } |
76 } |
77 inline uint qHash(long key) { return qHash(ulong(key)); } |
77 inline uint qHash(long key) { return qHash(ulong(key)); } |
78 inline uint qHash(quint64 key) |
78 inline uint qHash(quint64 key) |
79 { |
79 { |
80 if (sizeof(quint64) > sizeof(uint)) { |
80 if (sizeof(quint64) > sizeof(uint)) { |
81 return uint((key >> (8 * sizeof(uint) - 1)) ^ key); |
81 return uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)); |
82 } else { |
82 } else { |
83 return uint(key); |
83 return uint(key & (~0U)); |
84 } |
84 } |
85 } |
85 } |
86 inline uint qHash(qint64 key) { return qHash(quint64(key)); } |
86 inline uint qHash(qint64 key) { return qHash(quint64(key)); } |
87 inline uint qHash(QChar key) { return qHash(key.unicode()); } |
87 inline uint qHash(QChar key) { return qHash(key.unicode()); } |
88 Q_CORE_EXPORT uint qHash(const QByteArray &key); |
88 Q_CORE_EXPORT uint qHash(const QByteArray &key); |
123 int nodeSize; |
123 int nodeSize; |
124 short userNumBits; |
124 short userNumBits; |
125 short numBits; |
125 short numBits; |
126 int numBuckets; |
126 int numBuckets; |
127 uint sharable : 1; |
127 uint sharable : 1; |
128 |
128 uint strictAlignment : 1; |
129 void *allocateNode(); |
129 uint reserved : 30; |
|
130 |
|
131 void *allocateNode(); // ### Qt5 remove me |
|
132 void *allocateNode(int nodeAlign); |
130 void freeNode(void *node); |
133 void freeNode(void *node); |
131 QHashData *detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize); // ### Qt5 remove me |
134 QHashData *detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize); // ### Qt5 remove me |
132 QHashData *detach_helper(void (*node_duplicate)(Node *, void *), void (*node_delete)(Node *), |
135 QHashData *detach_helper2(void (*node_duplicate)(Node *, void *), void (*node_delete)(Node *), |
133 int nodeSize); |
136 int nodeSize, int nodeAlign); |
134 void mightGrow(); |
137 void mightGrow(); |
135 bool willGrow(); |
138 bool willGrow(); |
136 void hasShrunk(); |
139 void hasShrunk(); |
137 void rehash(int hint); |
140 void rehash(int hint); |
138 void free_helper(void (*node_delete)(Node *)); |
141 void free_helper(void (*node_delete)(Node *)); |
265 |
268 |
266 static inline Node *concrete(QHashData::Node *node) { |
269 static inline Node *concrete(QHashData::Node *node) { |
267 return reinterpret_cast<Node *>(node); |
270 return reinterpret_cast<Node *>(node); |
268 } |
271 } |
269 |
272 |
|
273 #ifdef Q_ALIGNOF |
|
274 static inline int alignOfNode() { return qMax<int>(sizeof(void*), Q_ALIGNOF(Node)); } |
|
275 static inline int alignOfDummyNode() { return qMax<int>(sizeof(void*), Q_ALIGNOF(DummyNode)); } |
|
276 #else |
|
277 static inline int alignOfNode() { return 0; } |
|
278 static inline int alignOfDummyNode() { return 0; } |
|
279 #endif |
|
280 |
270 public: |
281 public: |
271 inline QHash() : d(&QHashData::shared_null) { d->ref.ref(); } |
282 inline QHash() : d(&QHashData::shared_null) { d->ref.ref(); } |
272 inline QHash(const QHash<Key, T> &other) : d(other.d) { d->ref.ref(); if (!d->sharable) detach(); } |
283 inline QHash(const QHash<Key, T> &other) : d(other.d) { d->ref.ref(); if (!d->sharable) detach(); } |
273 inline ~QHash() { if (!d->ref.deref()) freeData(d); } |
284 inline ~QHash() { if (!d->ref.deref()) freeData(d); } |
274 |
285 |
481 void detach_helper(); |
492 void detach_helper(); |
482 void freeData(QHashData *d); |
493 void freeData(QHashData *d); |
483 Node **findNode(const Key &key, uint *hp = 0) const; |
494 Node **findNode(const Key &key, uint *hp = 0) const; |
484 Node *createNode(uint h, const Key &key, const T &value, Node **nextNode); |
495 Node *createNode(uint h, const Key &key, const T &value, Node **nextNode); |
485 void deleteNode(Node *node); |
496 void deleteNode(Node *node); |
486 static void deleteNode(QHashData::Node *node); |
497 static void deleteNode2(QHashData::Node *node); |
487 |
498 |
488 static void duplicateNode(QHashData::Node *originalNode, void *newNode); |
499 static void duplicateNode(QHashData::Node *originalNode, void *newNode); |
489 }; |
500 }; |
490 |
501 |
491 |
502 |
492 template <class Key, class T> |
503 template <class Key, class T> |
493 Q_INLINE_TEMPLATE void QHash<Key, T>::deleteNode(Node *node) |
504 Q_INLINE_TEMPLATE void QHash<Key, T>::deleteNode(Node *node) |
494 { |
505 { |
495 deleteNode(reinterpret_cast<QHashData::Node*>(node)); |
506 deleteNode2(reinterpret_cast<QHashData::Node*>(node)); |
496 } |
507 d->freeNode(node); |
497 |
508 } |
498 |
509 |
499 template <class Key, class T> |
510 template <class Key, class T> |
500 Q_INLINE_TEMPLATE void QHash<Key, T>::deleteNode(QHashData::Node *node) |
511 Q_INLINE_TEMPLATE void QHash<Key, T>::deleteNode2(QHashData::Node *node) |
501 { |
512 { |
502 #ifdef Q_CC_BOR |
513 #ifdef Q_CC_BOR |
503 concrete(node)->~QHashNode<Key, T>(); |
514 concrete(node)->~QHashNode<Key, T>(); |
504 #elif defined(QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION) |
515 #elif defined(QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION) |
505 concrete(node)->~QHashNode(); |
516 concrete(node)->~QHashNode(); |
506 #else |
517 #else |
507 concrete(node)->~Node(); |
518 concrete(node)->~Node(); |
508 #endif |
519 #endif |
509 qFree(node); |
|
510 } |
520 } |
511 |
521 |
512 template <class Key, class T> |
522 template <class Key, class T> |
513 Q_INLINE_TEMPLATE void QHash<Key, T>::duplicateNode(QHashData::Node *node, void *newNode) |
523 Q_INLINE_TEMPLATE void QHash<Key, T>::duplicateNode(QHashData::Node *node, void *newNode) |
514 { |
524 { |
525 QHash<Key, T>::createNode(uint ah, const Key &akey, const T &avalue, Node **anextNode) |
535 QHash<Key, T>::createNode(uint ah, const Key &akey, const T &avalue, Node **anextNode) |
526 { |
536 { |
527 Node *node; |
537 Node *node; |
528 |
538 |
529 if (QTypeInfo<T>::isDummy) { |
539 if (QTypeInfo<T>::isDummy) { |
530 node = reinterpret_cast<Node *>(new (d->allocateNode()) DummyNode(akey)); |
540 node = reinterpret_cast<Node *>(new (d->allocateNode(alignOfDummyNode())) DummyNode(akey)); |
531 } else { |
541 } else { |
532 node = new (d->allocateNode()) Node(akey, avalue); |
542 node = new (d->allocateNode(alignOfNode())) Node(akey, avalue); |
533 } |
543 } |
534 |
544 |
535 node->h = ah; |
545 node->h = ah; |
536 node->next = *anextNode; |
546 node->next = *anextNode; |
537 *anextNode = node; |
547 *anextNode = node; |
552 } |
562 } |
553 |
563 |
554 template <class Key, class T> |
564 template <class Key, class T> |
555 Q_OUTOFLINE_TEMPLATE void QHash<Key, T>::freeData(QHashData *x) |
565 Q_OUTOFLINE_TEMPLATE void QHash<Key, T>::freeData(QHashData *x) |
556 { |
566 { |
557 x->free_helper(deleteNode); |
567 x->free_helper(deleteNode2); |
558 } |
568 } |
559 |
569 |
560 template <class Key, class T> |
570 template <class Key, class T> |
561 Q_INLINE_TEMPLATE void QHash<Key, T>::clear() |
571 Q_INLINE_TEMPLATE void QHash<Key, T>::clear() |
562 { |
572 { |
564 } |
574 } |
565 |
575 |
566 template <class Key, class T> |
576 template <class Key, class T> |
567 Q_OUTOFLINE_TEMPLATE void QHash<Key, T>::detach_helper() |
577 Q_OUTOFLINE_TEMPLATE void QHash<Key, T>::detach_helper() |
568 { |
578 { |
569 QHashData *x = d->detach_helper(duplicateNode, deleteNode, |
579 QHashData *x = d->detach_helper2(duplicateNode, deleteNode2, |
570 QTypeInfo<T>::isDummy ? sizeof(DummyNode) : sizeof(Node)); |
580 QTypeInfo<T>::isDummy ? sizeof(DummyNode) : sizeof(Node), |
|
581 QTypeInfo<T>::isDummy ? alignOfDummyNode() : alignOfNode()); |
571 if (!d->ref.deref()) |
582 if (!d->ref.deref()) |
572 freeData(d); |
583 freeData(d); |
573 d = x; |
584 d = x; |
574 } |
585 } |
575 |
586 |