63 inline uint
qHash(uchar key) {
return uint(key); }
64 inline uint
qHash(
signed char key) {
return uint(key); }
65 inline uint
qHash(ushort key) {
return uint(key); }
66 inline uint
qHash(
short key) {
return uint(key); }
67 inline uint
qHash(uint key) {
return key; }
68 inline uint
qHash(
int key) {
return uint(key); }
71 if (
sizeof(ulong) >
sizeof(uint)) {
72 return uint(((key >> (8 *
sizeof(uint) - 1)) ^ key) & (~0U));
74 return uint(key & (~0U));
77 inline uint
qHash(
long key) {
return qHash(ulong(key)); }
80 if (
sizeof(
quint64) >
sizeof(uint)) {
81 return uint(((key >> (8 *
sizeof(uint) - 1)) ^ key) & (~0U));
83 return uint(key & (~0U));
93 #if defined(Q_CC_MSVC)
94 #pragma warning( push )
95 #pragma warning( disable : 4311 ) // disable pointer truncation warning
97 template <
class T>
inline uint
qHash(
const T *key)
99 return qHash(reinterpret_cast<quintptr>(key));
101 #if defined(Q_CC_MSVC)
102 #pragma warning( pop )
109 return ((h1 << 16) | (h1 >> 16)) ^ h2;
128 uint strictAlignment : 1;
131 void *allocateNode();
132 void *allocateNode(
int nodeAlign);
133 void freeNode(
void *node);
134 QHashData *detach_helper(
void (*node_duplicate)(
Node *,
void *),
int nodeSize);
135 QHashData *detach_helper2(
void (*node_duplicate)(
Node *,
void *),
void (*node_delete)(
Node *),
136 int nodeSize,
int nodeAlign);
140 void rehash(
int hint);
141 void free_helper(
void (*node_delete)(
Node *));
142 void destroyAndFree();
144 #ifdef QT_QHASH_DEBUG
149 static Node *previousNode(
Node *node);
156 if (size >= numBuckets)
162 if (size >= numBuckets) {
172 if (size <= (numBuckets >> 3) && numBits > userNumBits) {
174 rehash(qMax(
int(numBits) - 2,
int(userNumBits)));
175 } QT_CATCH(
const std::bad_alloc &) {
183 Node *e =
reinterpret_cast<Node *
>(
this);
205 template <
class Key,
class T>
215 template <
class Key,
class T>
224 inline QHashNode(
const Key &key0,
const T &value0) : key(key0), value(value0) {}
225 inline bool same_key(uint h0,
const Key &key0) {
return h0 == h && key0 ==
key; }
229 #define Q_HASH_DECLARE_INT_NODES(key_type) \
231 struct QHashDummyNode<key_type, T> { \
232 QHashDummyNode *next; \
233 union { uint h; key_type key; }; \
235 inline QHashDummyNode(key_type ) {} \
239 struct QHashNode<key_type, T> { \
241 union { uint h; key_type key; }; \
244 inline QHashNode(key_type ) {} \
245 inline QHashNode(key_type , const T &value0) : value(value0) {} \
246 inline bool same_key(uint h0, key_type) { return h0 == h; } \
249 #if defined(Q_BYTE_ORDER) && Q_BYTE_ORDER == Q_LITTLE_ENDIAN
255 #undef Q_HASH_DECLARE_INT_NODES
257 template <
class Key,
class T>
269 return reinterpret_cast<Node *
>(node);
273 static inline int alignOfNode() {
return qMax<int>(
sizeof(
void*), Q_ALIGNOF(Node)); }
274 static inline int alignOfDummyNode() {
return qMax<int>(
sizeof(
void*), Q_ALIGNOF(DummyNode)); }
276 static inline int alignOfNode() {
return 0; }
277 static inline int alignOfDummyNode() {
return 0; }
286 #ifdef Q_COMPILER_RVALUE_REFS
288 {
qSwap(
d, other.d);
return *
this; }
310 int remove(
const Key &
key);
317 const T
value(
const Key &
key,
const T &defaultValue)
const;
343 inline operator Node *()
const {
return concrete(i); }
347 inline const Key &
key()
const {
return concrete(i)->key; }
348 inline T &
value()
const {
return concrete(i)->value; }
349 inline T &
operator*()
const {
return concrete(i)->value; }
373 {
iterator r = *
this;
if (j > 0)
while (j--) ++
r;
else while (j++) --
r;
return r; }
379 #ifdef QT_STRICT_ITERATORS
391 inline operator bool()
const {
return false; }
408 inline operator Node *()
const {
return concrete(i); }
411 : i(reinterpret_cast<
QHashData::Node *>(node)) { }
412 #ifdef QT_STRICT_ITERATORS
419 inline const Key &
key()
const {
return concrete(i)->key; }
420 inline const T &
value()
const {
return concrete(i)->value; }
421 inline const T &
operator*()
const {
return concrete(i)->value; }
422 inline const T *
operator->()
const {
return &concrete(i)->value; }
445 {
const_iterator r = *
this;
if (j > 0)
while (j--) ++
r;
else while (j++) --
r;
return r; }
451 #ifdef QT_STRICT_ITERATORS
459 inline operator bool()
const {
return false; }
491 #ifdef QT_QHASH_DEBUG
492 inline void dump()
const {
d->dump(); }
493 inline void checkSanity()
const {
d->checkSanity(); }
497 void detach_helper();
499 Node **findNode(
const Key &
key, uint *hp = 0)
const;
500 Node *createNode(uint
h,
const Key &
key,
const T &
value, Node **nextNode);
501 void deleteNode(Node *node);
504 static void duplicateNode(
QHashData::Node *originalNode,
void *newNode);
508 template <
class Key,
class T>
511 deleteNode2(reinterpret_cast<QHashData::Node*>(node));
515 template <
class Key,
class T>
519 concrete(node)->~QHashNode<
Key, T>();
521 concrete(node)->~Node();
525 template <
class Key,
class T>
528 Node *concreteNode = concrete(node);
529 if (QTypeInfo<T>::isDummy) {
530 (
void)
new (newNode) DummyNode(concreteNode->key);
532 (
void)
new (newNode) Node(concreteNode->key, concreteNode->value);
536 template <
class Key,
class T>
542 if (QTypeInfo<T>::isDummy) {
543 node =
reinterpret_cast<Node *
>(
new (d->allocateNode(alignOfDummyNode())) DummyNode(akey));
545 node =
new (d->allocateNode(alignOfNode())) Node(akey, avalue);
549 node->next = *anextNode;
555 template <
class Key,
class T>
567 template <
class Key,
class T>
573 template <
class Key,
class T>
579 template <
class Key,
class T>
583 QTypeInfo<T>::isDummy ?
sizeof(DummyNode) :
sizeof(Node),
584 QTypeInfo<T>::isDummy ? alignOfDummyNode() : alignOfNode());
590 template <
class Key,
class T>
605 template <
class Key,
class T>
609 if (d->size == 0 || (node = *findNode(akey)) == e) {
616 template <
class Key,
class T>
620 if (d->size == 0 || (node = *findNode(akey)) == e) {
621 return adefaultValue;
627 template <
class Key,
class T>
635 const Key &aKey = i.
key();
639 goto break_out_of_outer_loop;
640 }
while (aKey == i.
key());
643 break_out_of_outer_loop:
647 template <
class Key,
class T>
660 template <
class Key,
class T>
666 if (i.
value() == avalue)
673 template <
class Key,
class T>
676 return key(avalue,
Key());
679 template <
class Key,
class T>
684 if (i.
value() == avalue)
692 template <
class Key,
class T>
705 template <
class Key,
class T>
709 Node *node = *findNode(akey);
713 }
while ((node = node->
next) != e && node->
key == akey);
718 template <
class Key,
class T>
722 Node *node = *findNode(akey);
726 }
while ((node = node->
next) != e && node->
key == akey);
731 template <
class Key,
class T>
737 template <
class Key,
class T>
743 Node **node = findNode(akey, &h);
746 node = findNode(akey, &h);
747 return createNode(h, akey, T(), node)->
value;
749 return (*node)->value;
752 template <
class Key,
class T>
759 Node **node = findNode(akey, &h);
762 node = findNode(akey, &h);
763 return iterator(createNode(h, akey, avalue, node));
766 if (!QTypeInfo<T>::isDummy)
767 (*node)->value = avalue;
771 template <
class Key,
class T>
779 Node **nextNode = findNode(akey, &h);
780 return iterator(createNode(h, akey, avalue, nextNode));
783 template <
class Key,
class T>
790 int oldSize = d->size;
791 Node **node = findNode(akey);
793 bool deleteNext =
true;
795 Node *next = (*node)->next;
796 deleteNext = (next != e && next->
key == (*node)->key);
800 }
while (deleteNext);
803 return oldSize - d->size;
806 template <
class Key,
class T>
813 Node **node = findNode(akey);
815 T
t = (*node)->value;
816 Node *next = (*node)->next;
826 template <
class Key,
class T>
836 Node **node_ptr =
reinterpret_cast<Node **
>(&d->buckets[node->
h % d->numBuckets]);
837 while (*node_ptr != node)
838 node_ptr = &(*node_ptr)->
next;
839 *node_ptr = node->
next;
845 template <
class Key,
class T>
849 d->rehash(-qMax(asize, 1));
852 template <
class Key,
class T>
858 template <
class Key,
class T>
864 template <
class Key,
class T>
871 template <
class Key,
class T>
874 return *findNode(akey) != e;
877 template <
class Key,
class T>
885 node =
reinterpret_cast<Node **
>(&d->buckets[h % d->numBuckets]);
886 Q_ASSERT(*node == e || (*node)->next);
887 while (*node != e && !(*node)->same_key(h, akey))
888 node = &(*node)->next;
890 node =
const_cast<Node **
>(
reinterpret_cast<const Node *
const *
>(&e));
897 template <
class Key,
class T>
907 while (it !=
end()) {
908 const Key &akey = it.
key();
912 if (it2 == other.
end() || !(it2.
key() == akey))
914 if (!QTypeInfo<T>::isDummy && !(it.
value() == it2.
value()))
918 }
while (it !=
end() && it.
key() == akey);
923 template <
class Key,
class T>
938 { this->
unite(other);
return *
this; }
940 {
QMultiHash result = *
this; result += other;
return result; }
942 #if !defined(Q_NO_USING_KEYWORD) && !defined(Q_CC_RVCT)
952 inline int remove(
const Key &
key)
956 inline int count()
const
975 while (i != end && i.
key() ==
key) {
985 while (i != end && i.
key() ==
key) {
993 {
return find(key, value); }
995 T &operator[](
const Key &key);
996 const T operator[](
const Key &key)
const;
999 template <
class Key,
class T>
1005 template <
class Key,
class T>
1011 while (i != end && i.
key() == key) {
1022 template <
class Key,
class T>
1028 while (i != end && i.
key() == key) {
iterator & operator+=(int j)
GLdouble GLdouble GLdouble r
std::bidirectional_iterator_tag iterator_category
bool operator==(const iterator &o) const
QHashNode(const Key &key0)
std::bidirectional_iterator_tag iterator_category
iterator erase(iterator it)
bool operator!=(const QHash< Key, T > &other) const
const_iterator(void *node)
iterator operator+(int j) const
QHash< Key, T > & unite(const QHash< Key, T > &other)
bool operator==(const QHashDummyValue &, const QHashDummyValue &)
bool isSharedWith(const QHash< Key, T > &other) const
const_iterator operator+(int j) const
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
const T & operator*() const
int remove(const Key &key, const T &value)
QMultiHash & operator+=(const QMultiHash &other)
T & operator[](const Key &key)
static Node * previousNode(Node *node)
QHash< Key, T >::const_iterator constFind(const Key &key, const T &value) const
void swap(QMultiHash< Key, T > &other)
iterator find(const Key &key)
unsigned long long quint64
#define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C)
const_iterator & operator-=(int j)
iterator & operator-=(int j)
bool operator!=(const iterator &o) const
Q_DECLARE_TYPEINFO(QHashDummyValue, Q_MOVABLE_TYPE|Q_DUMMY_TYPE)
#define QT_BEGIN_NAMESPACE
const T * operator->() const
int remove(const Key &key)
const T value(const Key &key) const
QList< T > values() const
bool same_key(uint h0, const Key &key0)
bool operator!=(const const_iterator &o) const
QHash< Key, T >::iterator insert(const Key &key, const T &value)
bool operator==(const QHash< Key, T > &other) const
void free_helper(void(*node_delete)(Node *))
QHashData * detach_helper2(void(*node_duplicate)(Node *, void *), void(*node_delete)(Node *), int nodeSize, int nodeAlign)
Q_INLINE_TEMPLATE void qSwap(QScopedPointer< T, Cleanup > &p1, QScopedPointer< T, Cleanup > &p2)
const_iterator(const iterator &o)
const_iterator operator-(int j) const
QList< Key > uniqueKeys() const
bool operator!=(const const_iterator &o) const
#define Q_HASH_DECLARE_INT_NODES(key_type)
static QHashData shared_null
bool operator==(const const_iterator &o) const
const_iterator & operator++()
bool operator==(const const_iterator &o) const
#define Q_DECLARE_ASSOCIATIVE_ITERATOR(C)
QHash< Key, T >::const_iterator find(const Key &key, const T &value) const
GLsizei const GLfloat * value
const_iterator begin() const
static Node * nextNode(Node *node)
int int int int int int h
QHashNode(const Key &key0, const T &value0)
const_iterator ConstIterator
QMultiHash operator+(const QMultiHash &other) const
bool contains(const Key &key, const T &value) const
void swap(QHash< Key, T > &other)
const_iterator end() const
iterator operator-(int j) const
QHashDummyNode(const Key &key0)
const_iterator & operator--()
const_iterator & operator+=(int j)
friend class const_iterator
QHash< Key, T > & operator=(const QHash< Key, T > &other)
const_iterator operator++(int)
iterator insertMulti(const Key &key, const T &value)
const_iterator operator--(int)
const_iterator constFind(const Key &key) const
QMultiHash(const QHash< Key, T > &other)
const_iterator constBegin() const
const_iterator constEnd() const
QHash(const QHash< Key, T > &other)
void setSharable(bool sharable)
iterator insert(const Key &key, const T &value)
QHash< Key, T >::iterator find(const Key &key, const T &value)
bool contains(const Key &key) const
const Key key(const T &value) const
QList< Key > keys() const
QHash< Key, T >::iterator replace(const Key &key, const T &value)