OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserv
ed. |
3 * Copyright (C) 2008 David Levin <levin@chromium.org> | 3 * Copyright (C) 2008 David Levin <levin@chromium.org> |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 ++m_stats->numAccesses; \ | 62 ++m_stats->numAccesses; \ |
63 int perTableProbeCount = 0 | 63 int perTableProbeCount = 0 |
64 #else | 64 #else |
65 #define UPDATE_PROBE_COUNTS() do { } while (0) | 65 #define UPDATE_PROBE_COUNTS() do { } while (0) |
66 #define UPDATE_ACCESS_COUNTS() do { } while (0) | 66 #define UPDATE_ACCESS_COUNTS() do { } while (0) |
67 #endif | 67 #endif |
68 #endif | 68 #endif |
69 | 69 |
70 namespace WTF { | 70 namespace WTF { |
71 | 71 |
| 72 // Custom secondary hash function. |
| 73 unsigned doubleHash(unsigned key); |
| 74 |
72 #if DUMP_HASHTABLE_STATS | 75 #if DUMP_HASHTABLE_STATS |
73 | 76 |
74 struct HashTableStats { | 77 struct HashTableStats { |
75 // The following variables are all atomically incremented when modified. | 78 // The following variables are all atomically incremented when modified. |
76 static int numAccesses; | 79 static int numAccesses; |
77 static int numRehashes; | 80 static int numRehashes; |
78 static int numRemoves; | 81 static int numRemoves; |
79 static int numReinserts; | 82 static int numReinserts; |
80 | 83 |
81 // The following variables are only modified in the recordCollisionAtCou
nt method within a mutex. | 84 // The following variables are only modified in the recordCollisionAtCou
nt method within a mutex. |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 | 242 |
240 operator const_iterator() const { return m_iterator; } | 243 operator const_iterator() const { return m_iterator; } |
241 | 244 |
242 private: | 245 private: |
243 const_iterator m_iterator; | 246 const_iterator m_iterator; |
244 }; | 247 }; |
245 | 248 |
246 using std::swap; | 249 using std::swap; |
247 | 250 |
248 // Work around MSVC's standard library, whose swap for pairs does not swap b
y component. | 251 // Work around MSVC's standard library, whose swap for pairs does not swap b
y component. |
249 template<typename T> inline void hashTableSwap(T& a, T& b) | 252 template<typename T> void hashTableSwap(T& a, T& b) |
250 { | 253 { |
251 swap(a, b); | 254 swap(a, b); |
252 } | 255 } |
253 | 256 |
254 template<typename T, typename U> inline void hashTableSwap(KeyValuePair<T, U
>& a, KeyValuePair<T, U>& b) | 257 template<typename T, typename U> void hashTableSwap(KeyValuePair<T, U>& a, K
eyValuePair<T, U>& b) |
255 { | 258 { |
256 swap(a.key, b.key); | 259 swap(a.key, b.key); |
257 swap(a.value, b.value); | 260 swap(a.value, b.value); |
258 } | 261 } |
259 | 262 |
260 template<typename T, typename Allocator, bool useSwap> struct Mover; | 263 template<typename T, typename Allocator, bool useSwap> struct Mover; |
261 template<typename T, typename Allocator> struct Mover<T, Allocator, true> { | 264 template<typename T, typename Allocator> struct Mover<T, Allocator, true> { |
262 static void move(T& from, T& to) | 265 static void move(T& from, T& to) |
263 { | 266 { |
264 // A swap operation should not normally allocate, but it may do so | 267 // A swap operation should not normally allocate, but it may do so |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 // This is done at compile time to initialize the HashTraits. | 602 // This is done at compile time to initialize the HashTraits. |
600 template<unsigned size> | 603 template<unsigned size> |
601 struct HashTableCapacityForSize { | 604 struct HashTableCapacityForSize { |
602 static const unsigned value = HashTableCapacityForSizeSplitter<size, !(s
ize & (size - 1))>::value; | 605 static const unsigned value = HashTableCapacityForSizeSplitter<size, !(s
ize & (size - 1))>::value; |
603 COMPILE_ASSERT(size > 0, HashTableNonZeroMinimumCapacity); | 606 COMPILE_ASSERT(size > 0, HashTableNonZeroMinimumCapacity); |
604 COMPILE_ASSERT(!static_cast<int>(value >> 31), HashTableNoCapacityOverfl
ow); | 607 COMPILE_ASSERT(!static_cast<int>(value >> 31), HashTableNoCapacityOverfl
ow); |
605 COMPILE_ASSERT(value > (2 * size), HashTableCapacityHoldsContentSize); | 608 COMPILE_ASSERT(value > (2 * size), HashTableCapacityHoldsContentSize); |
606 }; | 609 }; |
607 | 610 |
608 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 611 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
609 inline HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Al
locator>::HashTable() | 612 HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator
>::HashTable() |
610 : m_table(0) | 613 : m_table(0) |
611 , m_tableSize(0) | 614 , m_tableSize(0) |
612 , m_keyCount(0) | 615 , m_keyCount(0) |
613 , m_deletedCount(0) | 616 , m_deletedCount(0) |
614 , m_queueFlag(false) | 617 , m_queueFlag(false) |
615 #if ENABLE(ASSERT) | 618 #if ENABLE(ASSERT) |
616 , m_modifications(0) | 619 , m_modifications(0) |
617 #endif | 620 #endif |
618 #if DUMP_HASHTABLE_STATS_PER_TABLE | 621 #if DUMP_HASHTABLE_STATS_PER_TABLE |
619 , m_stats(adoptPtr(new Stats)) | 622 , m_stats(adoptPtr(new Stats)) |
620 #endif | 623 #endif |
621 { | 624 { |
622 } | 625 } |
623 | 626 |
624 inline unsigned doubleHash(unsigned key) | |
625 { | |
626 key = ~key + (key >> 23); | |
627 key ^= (key << 12); | |
628 key ^= (key >> 7); | |
629 key ^= (key << 2); | |
630 key ^= (key >> 20); | |
631 return key; | |
632 } | |
633 | |
634 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 627 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
635 template<typename HashTranslator, typename T> | 628 template<typename HashTranslator, typename T> |
636 inline Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTra
its, Allocator>::lookup(T key) | 629 Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Al
locator>::lookup(T key) |
637 { | 630 { |
638 return const_cast<Value*>(const_cast<const HashTable*>(this)->lookup<Has
hTranslator, T>(key)); | 631 return const_cast<Value*>(const_cast<const HashTable*>(this)->lookup<Has
hTranslator, T>(key)); |
639 } | 632 } |
640 | 633 |
641 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 634 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
642 template<typename HashTranslator, typename T> | 635 template<typename HashTranslator, typename T> |
643 inline const Value* HashTable<Key, Value, Extractor, HashFunctions, Traits,
KeyTraits, Allocator>::lookup(T key) const | 636 const Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrai
ts, Allocator>::lookup(T key) const |
644 { | 637 { |
645 ASSERT((HashTableKeyChecker<HashTranslator, KeyTraits, HashFunctions::sa
feToCompareToEmptyOrDeleted>::checkKey(key))); | 638 ASSERT((HashTableKeyChecker<HashTranslator, KeyTraits, HashFunctions::sa
feToCompareToEmptyOrDeleted>::checkKey(key))); |
646 const ValueType* table = m_table; | 639 const ValueType* table = m_table; |
647 if (!table) | 640 if (!table) |
648 return 0; | 641 return 0; |
649 | 642 |
650 size_t k = 0; | 643 size_t k = 0; |
651 size_t sizeMask = tableSizeMask(); | 644 size_t sizeMask = tableSizeMask(); |
652 unsigned h = HashTranslator::hash(key); | 645 unsigned h = HashTranslator::hash(key); |
653 size_t i = h & sizeMask; | 646 size_t i = h & sizeMask; |
(...skipping 18 matching lines...) Expand all Loading... |
672 } | 665 } |
673 UPDATE_PROBE_COUNTS(); | 666 UPDATE_PROBE_COUNTS(); |
674 if (!k) | 667 if (!k) |
675 k = 1 | doubleHash(h); | 668 k = 1 | doubleHash(h); |
676 i = (i + k) & sizeMask; | 669 i = (i + k) & sizeMask; |
677 } | 670 } |
678 } | 671 } |
679 | 672 |
680 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 673 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
681 template<typename HashTranslator, typename T> | 674 template<typename HashTranslator, typename T> |
682 inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyT
raits, Allocator>::LookupType HashTable<Key, Value, Extractor, HashFunctions, Tr
aits, KeyTraits, Allocator>::lookupForWriting(const T& key) | 675 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits,
Allocator>::LookupType HashTable<Key, Value, Extractor, HashFunctions, Traits, K
eyTraits, Allocator>::lookupForWriting(const T& key) |
683 { | 676 { |
684 ASSERT(m_table); | 677 ASSERT(m_table); |
685 registerModification(); | 678 registerModification(); |
686 | 679 |
687 ValueType* table = m_table; | 680 ValueType* table = m_table; |
688 size_t k = 0; | 681 size_t k = 0; |
689 size_t sizeMask = tableSizeMask(); | 682 size_t sizeMask = tableSizeMask(); |
690 unsigned h = HashTranslator::hash(key); | 683 unsigned h = HashTranslator::hash(key); |
691 size_t i = h & sizeMask; | 684 size_t i = h & sizeMask; |
692 | 685 |
(...skipping 21 matching lines...) Expand all Loading... |
714 } | 707 } |
715 UPDATE_PROBE_COUNTS(); | 708 UPDATE_PROBE_COUNTS(); |
716 if (!k) | 709 if (!k) |
717 k = 1 | doubleHash(h); | 710 k = 1 | doubleHash(h); |
718 i = (i + k) & sizeMask; | 711 i = (i + k) & sizeMask; |
719 } | 712 } |
720 } | 713 } |
721 | 714 |
722 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 715 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
723 template<typename HashTranslator, typename T> | 716 template<typename HashTranslator, typename T> |
724 inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyT
raits, Allocator>::FullLookupType HashTable<Key, Value, Extractor, HashFunctions
, Traits, KeyTraits, Allocator>::fullLookupForWriting(const T& key) | 717 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits,
Allocator>::FullLookupType HashTable<Key, Value, Extractor, HashFunctions, Trait
s, KeyTraits, Allocator>::fullLookupForWriting(const T& key) |
725 { | 718 { |
726 ASSERT(m_table); | 719 ASSERT(m_table); |
727 registerModification(); | 720 registerModification(); |
728 | 721 |
729 ValueType* table = m_table; | 722 ValueType* table = m_table; |
730 size_t k = 0; | 723 size_t k = 0; |
731 size_t sizeMask = tableSizeMask(); | 724 size_t sizeMask = tableSizeMask(); |
732 unsigned h = HashTranslator::hash(key); | 725 unsigned h = HashTranslator::hash(key); |
733 size_t i = h & sizeMask; | 726 size_t i = h & sizeMask; |
734 | 727 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 template<typename Traits, typename Value> static void initialize(Value&
bucket) | 767 template<typename Traits, typename Value> static void initialize(Value&
bucket) |
775 { | 768 { |
776 // This initializes the bucket without copying the empty value. | 769 // This initializes the bucket without copying the empty value. |
777 // That makes it possible to use this with types that don't support
copying. | 770 // That makes it possible to use this with types that don't support
copying. |
778 // The memset to 0 looks like a slow operation but is optimized by t
he compilers. | 771 // The memset to 0 looks like a slow operation but is optimized by t
he compilers. |
779 memset(&bucket, 0, sizeof(bucket)); | 772 memset(&bucket, 0, sizeof(bucket)); |
780 } | 773 } |
781 }; | 774 }; |
782 | 775 |
783 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 776 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
784 inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait
s, Allocator>::initializeBucket(ValueType& bucket) | 777 void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allo
cator>::initializeBucket(ValueType& bucket) |
785 { | 778 { |
786 // For hash maps the key and value cannot be initialied simultaneously, | 779 // For hash maps the key and value cannot be initialied simultaneously, |
787 // and it would be wrong to have a GC when only one was initialized and | 780 // and it would be wrong to have a GC when only one was initialized and |
788 // the other still contained garbage (eg. from a previous use of the | 781 // the other still contained garbage (eg. from a previous use of the |
789 // same slot). Therefore we forbid allocation (and thus GC) while the | 782 // same slot). Therefore we forbid allocation (and thus GC) while the |
790 // slot is initalized to an empty value. | 783 // slot is initalized to an empty value. |
791 Allocator::enterNoAllocationScope(); | 784 Allocator::enterNoAllocationScope(); |
792 HashTableBucketInitializer<Traits::emptyValueIsZero>::template initializ
e<Traits>(bucket); | 785 HashTableBucketInitializer<Traits::emptyValueIsZero>::template initializ
e<Traits>(bucket); |
793 Allocator::leaveNoAllocationScope(); | 786 Allocator::leaveNoAllocationScope(); |
794 } | 787 } |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 ++m_stats->numReinserts; | 899 ++m_stats->numReinserts; |
907 #endif | 900 #endif |
908 Value* newEntry = lookupForWriting(Extractor::extract(entry)).first; | 901 Value* newEntry = lookupForWriting(Extractor::extract(entry)).first; |
909 Mover<ValueType, Allocator, Traits::needsDestruction>::move(entry, *newE
ntry); | 902 Mover<ValueType, Allocator, Traits::needsDestruction>::move(entry, *newE
ntry); |
910 | 903 |
911 return newEntry; | 904 return newEntry; |
912 } | 905 } |
913 | 906 |
914 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 907 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
915 template <typename HashTranslator, typename T> | 908 template <typename HashTranslator, typename T> |
916 inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyT
raits, Allocator>::iterator HashTable<Key, Value, Extractor, HashFunctions, Trai
ts, KeyTraits, Allocator>::find(const T& key) | 909 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits,
Allocator>::iterator HashTable<Key, Value, Extractor, HashFunctions, Traits, Key
Traits, Allocator>::find(const T& key) |
917 { | 910 { |
918 ValueType* entry = lookup<HashTranslator>(key); | 911 ValueType* entry = lookup<HashTranslator>(key); |
919 if (!entry) | 912 if (!entry) |
920 return end(); | 913 return end(); |
921 | 914 |
922 return makeKnownGoodIterator(entry); | 915 return makeKnownGoodIterator(entry); |
923 } | 916 } |
924 | 917 |
925 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 918 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
926 template <typename HashTranslator, typename T> | 919 template <typename HashTranslator, typename T> |
927 inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyT
raits, Allocator>::const_iterator HashTable<Key, Value, Extractor, HashFunctions
, Traits, KeyTraits, Allocator>::find(const T& key) const | 920 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits,
Allocator>::const_iterator HashTable<Key, Value, Extractor, HashFunctions, Trait
s, KeyTraits, Allocator>::find(const T& key) const |
928 { | 921 { |
929 ValueType* entry = const_cast<HashTable*>(this)->lookup<HashTranslator>(
key); | 922 ValueType* entry = const_cast<HashTable*>(this)->lookup<HashTranslator>(
key); |
930 if (!entry) | 923 if (!entry) |
931 return end(); | 924 return end(); |
932 | 925 |
933 return makeKnownGoodConstIterator(entry); | 926 return makeKnownGoodConstIterator(entry); |
934 } | 927 } |
935 | 928 |
936 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 929 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
937 template <typename HashTranslator, typename T> | 930 template <typename HashTranslator, typename T> |
(...skipping 15 matching lines...) Expand all Loading... |
953 | 946 |
954 deleteBucket(*pos); | 947 deleteBucket(*pos); |
955 ++m_deletedCount; | 948 ++m_deletedCount; |
956 --m_keyCount; | 949 --m_keyCount; |
957 | 950 |
958 if (shouldShrink()) | 951 if (shouldShrink()) |
959 shrink(); | 952 shrink(); |
960 } | 953 } |
961 | 954 |
962 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 955 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
963 inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait
s, Allocator>::remove(iterator it) | 956 void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allo
cator>::remove(iterator it) |
964 { | 957 { |
965 if (it == end()) | 958 if (it == end()) |
966 return; | 959 return; |
967 | 960 |
968 remove(const_cast<ValueType*>(it.m_iterator.m_position)); | 961 remove(const_cast<ValueType*>(it.m_iterator.m_position)); |
969 } | 962 } |
970 | 963 |
971 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 964 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
972 inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait
s, Allocator>::remove(const_iterator it) | 965 void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allo
cator>::remove(const_iterator it) |
973 { | 966 { |
974 if (it == end()) | 967 if (it == end()) |
975 return; | 968 return; |
976 | 969 |
977 remove(const_cast<ValueType*>(it.m_position)); | 970 remove(const_cast<ValueType*>(it.m_position)); |
978 } | 971 } |
979 | 972 |
980 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 973 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
981 inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait
s, Allocator>::remove(KeyPeekInType key) | 974 void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allo
cator>::remove(KeyPeekInType key) |
982 { | 975 { |
983 remove(find(key)); | 976 remove(find(key)); |
984 } | 977 } |
985 | 978 |
986 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 979 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
987 Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Al
locator>::allocateTable(unsigned size) | 980 Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Al
locator>::allocateTable(unsigned size) |
988 { | 981 { |
989 typedef typename Allocator::template HashTableBackingHelper<HashTable>::
Type HashTableBacking; | 982 typedef typename Allocator::template HashTableBackingHelper<HashTable>::
Type HashTableBacking; |
990 | 983 |
991 size_t allocSize = size * sizeof(ValueType); | 984 size_t allocSize = size * sizeof(ValueType); |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1316 operator HashTableConstIteratorAdapter<HashTableType, Traits>() | 1309 operator HashTableConstIteratorAdapter<HashTableType, Traits>() |
1317 { | 1310 { |
1318 typename HashTableType::const_iterator i = m_impl; | 1311 typename HashTableType::const_iterator i = m_impl; |
1319 return i; | 1312 return i; |
1320 } | 1313 } |
1321 | 1314 |
1322 typename HashTableType::iterator m_impl; | 1315 typename HashTableType::iterator m_impl; |
1323 }; | 1316 }; |
1324 | 1317 |
1325 template<typename T, typename U> | 1318 template<typename T, typename U> |
1326 inline bool operator==(const HashTableConstIteratorAdapter<T, U>& a, const H
ashTableConstIteratorAdapter<T, U>& b) | 1319 bool operator==(const HashTableConstIteratorAdapter<T, U>& a, const HashTabl
eConstIteratorAdapter<T, U>& b) |
1327 { | 1320 { |
1328 return a.m_impl == b.m_impl; | 1321 return a.m_impl == b.m_impl; |
1329 } | 1322 } |
1330 | 1323 |
1331 template<typename T, typename U> | 1324 template<typename T, typename U> |
1332 inline bool operator!=(const HashTableConstIteratorAdapter<T, U>& a, const H
ashTableConstIteratorAdapter<T, U>& b) | 1325 bool operator!=(const HashTableConstIteratorAdapter<T, U>& a, const HashTabl
eConstIteratorAdapter<T, U>& b) |
1333 { | 1326 { |
1334 return a.m_impl != b.m_impl; | 1327 return a.m_impl != b.m_impl; |
1335 } | 1328 } |
1336 | 1329 |
1337 template<typename T, typename U> | 1330 template<typename T, typename U> |
1338 inline bool operator==(const HashTableIteratorAdapter<T, U>& a, const HashTa
bleIteratorAdapter<T, U>& b) | 1331 bool operator==(const HashTableIteratorAdapter<T, U>& a, const HashTableIter
atorAdapter<T, U>& b) |
1339 { | 1332 { |
1340 return a.m_impl == b.m_impl; | 1333 return a.m_impl == b.m_impl; |
1341 } | 1334 } |
1342 | 1335 |
1343 template<typename T, typename U> | 1336 template<typename T, typename U> |
1344 inline bool operator!=(const HashTableIteratorAdapter<T, U>& a, const HashTa
bleIteratorAdapter<T, U>& b) | 1337 bool operator!=(const HashTableIteratorAdapter<T, U>& a, const HashTableIter
atorAdapter<T, U>& b) |
1345 { | 1338 { |
1346 return a.m_impl != b.m_impl; | 1339 return a.m_impl != b.m_impl; |
1347 } | 1340 } |
1348 | 1341 |
1349 // All 4 combinations of ==, != and Const,non const. | 1342 // All 4 combinations of ==, != and Const,non const. |
1350 template<typename T, typename U> | 1343 template<typename T, typename U> |
1351 inline bool operator==(const HashTableConstIteratorAdapter<T, U>& a, const H
ashTableIteratorAdapter<T, U>& b) | 1344 bool operator==(const HashTableConstIteratorAdapter<T, U>& a, const HashTabl
eIteratorAdapter<T, U>& b) |
1352 { | 1345 { |
1353 return a.m_impl == b.m_impl; | 1346 return a.m_impl == b.m_impl; |
1354 } | 1347 } |
1355 | 1348 |
1356 template<typename T, typename U> | 1349 template<typename T, typename U> |
1357 inline bool operator!=(const HashTableConstIteratorAdapter<T, U>& a, const H
ashTableIteratorAdapter<T, U>& b) | 1350 bool operator!=(const HashTableConstIteratorAdapter<T, U>& a, const HashTabl
eIteratorAdapter<T, U>& b) |
1358 { | 1351 { |
1359 return a.m_impl != b.m_impl; | 1352 return a.m_impl != b.m_impl; |
1360 } | 1353 } |
1361 | 1354 |
1362 template<typename T, typename U> | 1355 template<typename T, typename U> |
1363 inline bool operator==(const HashTableIteratorAdapter<T, U>& a, const HashTa
bleConstIteratorAdapter<T, U>& b) | 1356 bool operator==(const HashTableIteratorAdapter<T, U>& a, const HashTableCons
tIteratorAdapter<T, U>& b) |
1364 { | 1357 { |
1365 return a.m_impl == b.m_impl; | 1358 return a.m_impl == b.m_impl; |
1366 } | 1359 } |
1367 | 1360 |
1368 template<typename T, typename U> | 1361 template<typename T, typename U> |
1369 inline bool operator!=(const HashTableIteratorAdapter<T, U>& a, const HashTa
bleConstIteratorAdapter<T, U>& b) | 1362 bool operator!=(const HashTableIteratorAdapter<T, U>& a, const HashTableCons
tIteratorAdapter<T, U>& b) |
1370 { | 1363 { |
1371 return a.m_impl != b.m_impl; | 1364 return a.m_impl != b.m_impl; |
1372 } | 1365 } |
1373 | 1366 |
1374 template<typename Collection1, typename Collection2> | 1367 template<typename Collection1, typename Collection2> |
1375 inline void removeAll(Collection1& collection, const Collection2& toBeRemove
d) | 1368 void removeAll(Collection1& collection, const Collection2& toBeRemoved) |
1376 { | 1369 { |
1377 if (collection.isEmpty() || toBeRemoved.isEmpty()) | 1370 if (collection.isEmpty() || toBeRemoved.isEmpty()) |
1378 return; | 1371 return; |
1379 typedef typename Collection2::const_iterator CollectionIterator; | 1372 typedef typename Collection2::const_iterator CollectionIterator; |
1380 CollectionIterator end(toBeRemoved.end()); | 1373 CollectionIterator end(toBeRemoved.end()); |
1381 for (CollectionIterator it(toBeRemoved.begin()); it != end; ++it) | 1374 for (CollectionIterator it(toBeRemoved.begin()); it != end; ++it) |
1382 collection.remove(*it); | 1375 collection.remove(*it); |
1383 } | 1376 } |
1384 | 1377 |
1385 } // namespace WTF | 1378 } // namespace WTF |
1386 | 1379 |
1387 #include "wtf/HashIterators.h" | 1380 #include "wtf/HashIterators.h" |
1388 | 1381 |
1389 #endif // WTF_HashTable_h | 1382 #endif // WTF_HashTable_h |
OLD | NEW |