| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 #endif | 56 #endif |
| 57 | 57 |
| 58 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 58 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
| 59 class HashTable; | 59 class HashTable; |
| 60 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 60 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
| 61 class HashTableIterator; | 61 class HashTableIterator; |
| 62 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 62 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
| 63 class HashTableConstIterator; | 63 class HashTableConstIterator; |
| 64 template<typename Value, typename HashFunctions, typename HashTraits, typena
me Allocator> |
| 65 class LinkedHashSet; |
| 64 template<bool x, typename T, typename U, typename V, typename W, typename X,
typename Y, typename Z> | 66 template<bool x, typename T, typename U, typename V, typename W, typename X,
typename Y, typename Z> |
| 65 struct WeakProcessingHashTableHelper; | 67 struct WeakProcessingHashTableHelper; |
| 66 | 68 |
| 67 typedef enum { HashItemKnownGood } HashItemKnownGoodTag; | 69 typedef enum { HashItemKnownGood } HashItemKnownGoodTag; |
| 68 | 70 |
| 69 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 71 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
| 70 class HashTableConstIterator { | 72 class HashTableConstIterator { |
| 71 private: | 73 private: |
| 72 typedef HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait
s, Allocator> HashTableType; | 74 typedef HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait
s, Allocator> HashTableType; |
| 73 typedef HashTableIterator<Key, Value, Extractor, HashFunctions, Traits,
KeyTraits, Allocator> iterator; | 75 typedef HashTableIterator<Key, Value, Extractor, HashFunctions, Traits,
KeyTraits, Allocator> iterator; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 97 } | 99 } |
| 98 | 100 |
| 99 HashTableConstIterator(PointerType position, PointerType endPosition, co
nst HashTableType* container, HashItemKnownGoodTag) | 101 HashTableConstIterator(PointerType position, PointerType endPosition, co
nst HashTableType* container, HashItemKnownGoodTag) |
| 100 : m_position(position) | 102 : m_position(position) |
| 101 , m_endPosition(endPosition) | 103 , m_endPosition(endPosition) |
| 102 #ifdef ASSERT_ENABLED | 104 #ifdef ASSERT_ENABLED |
| 103 , m_container(container) | 105 , m_container(container) |
| 104 , m_containerModifications(container->modifications()) | 106 , m_containerModifications(container->modifications()) |
| 105 #endif | 107 #endif |
| 106 { | 108 { |
| 109 ASSERT(m_containerModifications == m_container->modifications()); |
| 107 } | 110 } |
| 108 | 111 |
| 109 void checkModifications() const | 112 void checkModifications() const |
| 110 { | 113 { |
| 111 // HashTable and collections that build on it do not support | 114 // HashTable and collections that build on it do not support |
| 112 // modifications while there is an iterator in use. The exception | 115 // modifications while there is an iterator in use. The exception |
| 113 // is ListHashSet, which has its own iterators that tolerate | 116 // is ListHashSet, which has its own iterators that tolerate |
| 114 // modification of the underlying set. | 117 // modification of the underlying set. |
| 115 ASSERT(m_containerModifications == m_container->modifications()); | 118 ASSERT(m_containerModifications == m_container->modifications()); |
| 116 } | 119 } |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 | 368 |
| 366 void remove(KeyPeekInType); | 369 void remove(KeyPeekInType); |
| 367 void remove(iterator); | 370 void remove(iterator); |
| 368 void remove(const_iterator); | 371 void remove(const_iterator); |
| 369 void clear(); | 372 void clear(); |
| 370 | 373 |
| 371 static bool isEmptyBucket(const ValueType& value) { return isHashTraitsE
mptyValue<KeyTraits>(Extractor::extract(value)); } | 374 static bool isEmptyBucket(const ValueType& value) { return isHashTraitsE
mptyValue<KeyTraits>(Extractor::extract(value)); } |
| 372 static bool isDeletedBucket(const ValueType& value) { return KeyTraits::
isDeletedValue(Extractor::extract(value)); } | 375 static bool isDeletedBucket(const ValueType& value) { return KeyTraits::
isDeletedValue(Extractor::extract(value)); } |
| 373 static bool isEmptyOrDeletedBucket(const ValueType& value) { return Hash
TableHelper<ValueType, Extractor, KeyTraits>:: isEmptyOrDeletedBucket(value); } | 376 static bool isEmptyOrDeletedBucket(const ValueType& value) { return Hash
TableHelper<ValueType, Extractor, KeyTraits>:: isEmptyOrDeletedBucket(value); } |
| 374 | 377 |
| 375 ValueType* lookup(KeyPeekInType key) { return lookup<IdentityTranslatorT
ype>(key); } | 378 ValueType* lookup(KeyPeekInType key) { return lookup<IdentityTranslatorT
ype, KeyPeekInType>(key); } |
| 376 template<typename HashTranslator, typename T> ValueType* lookup(const T&
); | 379 template<typename HashTranslator, typename T> ValueType* lookup(T); |
| 380 template<typename HashTranslator, typename T> const ValueType* lookup(T)
const; |
| 377 | 381 |
| 378 void trace(typename Allocator::Visitor*); | 382 void trace(typename Allocator::Visitor*); |
| 379 | 383 |
| 380 #ifdef ASSERT_ENABLED | 384 #ifdef ASSERT_ENABLED |
| 381 int64_t modifications() const { return m_modifications; } | 385 int64_t modifications() const { return m_modifications; } |
| 382 void registerModification() { m_modifications++; } | 386 void registerModification() { m_modifications++; } |
| 387 // HashTable and collections that build on it do not support |
| 388 // modifications while there is an iterator in use. The exception is |
| 389 // ListHashSet, which has its own iterators that tolerate modification |
| 390 // of the underlying set. |
| 391 void checkModifications(int64_t mods) const { ASSERT(mods == m_modificat
ions); } |
| 383 #else | 392 #else |
| 384 int64_t modifications() const { return 0; } | 393 int64_t modifications() const { return 0; } |
| 385 void registerModification() { } | 394 void registerModification() { } |
| 395 void checkModifications(int64_t mods) const { } |
| 386 #endif | 396 #endif |
| 387 | 397 |
| 388 private: | 398 private: |
| 389 static ValueType* allocateTable(unsigned size); | 399 static ValueType* allocateTable(unsigned size); |
| 390 static void deleteAllBucketsAndDeallocate(ValueType* table, unsigned siz
e); | 400 static void deleteAllBucketsAndDeallocate(ValueType* table, unsigned siz
e); |
| 391 | 401 |
| 392 typedef std::pair<ValueType*, bool> LookupType; | 402 typedef std::pair<ValueType*, bool> LookupType; |
| 393 typedef std::pair<LookupType, unsigned> FullLookupType; | 403 typedef std::pair<LookupType, unsigned> FullLookupType; |
| 394 | 404 |
| 395 LookupType lookupForWriting(const Key& key) { return lookupForWriting<Id
entityTranslatorType>(key); }; | 405 LookupType lookupForWriting(const Key& key) { return lookupForWriting<Id
entityTranslatorType>(key); }; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 #ifdef ASSERT_ENABLED | 439 #ifdef ASSERT_ENABLED |
| 430 unsigned m_modifications; | 440 unsigned m_modifications; |
| 431 #endif | 441 #endif |
| 432 | 442 |
| 433 #if DUMP_HASHTABLE_STATS_PER_TABLE | 443 #if DUMP_HASHTABLE_STATS_PER_TABLE |
| 434 public: | 444 public: |
| 435 mutable OwnPtr<Stats> m_stats; | 445 mutable OwnPtr<Stats> m_stats; |
| 436 #endif | 446 #endif |
| 437 | 447 |
| 438 template<bool x, typename T, typename U, typename V, typename W, typenam
e X, typename Y, typename Z> friend struct WeakProcessingHashTableHelper; | 448 template<bool x, typename T, typename U, typename V, typename W, typenam
e X, typename Y, typename Z> friend struct WeakProcessingHashTableHelper; |
| 449 template<typename T, typename U, typename V, typename W> friend class Li
nkedHashSet; |
| 439 }; | 450 }; |
| 440 | 451 |
| 441 // Set all the bits to one after the most significant bit: 00110101010 -> 00
111111111. | 452 // Set all the bits to one after the most significant bit: 00110101010 -> 00
111111111. |
| 442 template<unsigned size> struct OneifyLowBits; | 453 template<unsigned size> struct OneifyLowBits; |
| 443 template<> | 454 template<> |
| 444 struct OneifyLowBits<0> { | 455 struct OneifyLowBits<0> { |
| 445 static const unsigned value = 0; | 456 static const unsigned value = 0; |
| 446 }; | 457 }; |
| 447 template<unsigned number> | 458 template<unsigned number> |
| 448 struct OneifyLowBits { | 459 struct OneifyLowBits { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 key = ~key + (key >> 23); | 508 key = ~key + (key >> 23); |
| 498 key ^= (key << 12); | 509 key ^= (key << 12); |
| 499 key ^= (key >> 7); | 510 key ^= (key >> 7); |
| 500 key ^= (key << 2); | 511 key ^= (key << 2); |
| 501 key ^= (key >> 20); | 512 key ^= (key >> 20); |
| 502 return key; | 513 return key; |
| 503 } | 514 } |
| 504 | 515 |
| 505 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 516 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
| 506 template<typename HashTranslator, typename T> | 517 template<typename HashTranslator, typename T> |
| 507 inline Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTra
its, Allocator>::lookup(const T& key) | 518 inline Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTra
its, Allocator>::lookup(T key) |
| 508 { | 519 { |
| 509 ValueType* table = m_table; | 520 return const_cast<Value*>(const_cast<const HashTable*>(this)->lookup<Has
hTranslator, T>(key)); |
| 521 } |
| 522 |
| 523 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
| 524 template<typename HashTranslator, typename T> |
| 525 inline const Value* HashTable<Key, Value, Extractor, HashFunctions, Traits,
KeyTraits, Allocator>::lookup(T key) const |
| 526 { |
| 527 const ValueType* table = m_table; |
| 510 if (!table) | 528 if (!table) |
| 511 return 0; | 529 return 0; |
| 512 | 530 |
| 513 size_t k = 0; | 531 size_t k = 0; |
| 514 size_t sizeMask = m_tableSizeMask; | 532 size_t sizeMask = m_tableSizeMask; |
| 515 unsigned h = HashTranslator::hash(key); | 533 unsigned h = HashTranslator::hash(key); |
| 516 size_t i = h & sizeMask; | 534 size_t i = h & sizeMask; |
| 517 | 535 |
| 518 #if DUMP_HASHTABLE_STATS | 536 #if DUMP_HASHTABLE_STATS |
| 519 atomicIncrement(&HashTableStats::numAccesses); | 537 atomicIncrement(&HashTableStats::numAccesses); |
| 520 int probeCount = 0; | 538 int probeCount = 0; |
| 521 #endif | 539 #endif |
| 522 | 540 |
| 523 #if DUMP_HASHTABLE_STATS_PER_TABLE | 541 #if DUMP_HASHTABLE_STATS_PER_TABLE |
| 524 ++m_stats->numAccesses; | 542 ++m_stats->numAccesses; |
| 525 int perTableProbeCount = 0; | 543 int perTableProbeCount = 0; |
| 526 #endif | 544 #endif |
| 527 | 545 |
| 528 while (1) { | 546 while (1) { |
| 529 ValueType* entry = table + i; | 547 const ValueType* entry = table + i; |
| 530 | 548 |
| 531 // we count on the compiler to optimize out this branch | 549 // we count on the compiler to optimize out this branch |
| 532 if (HashFunctions::safeToCompareToEmptyOrDeleted) { | 550 if (HashFunctions::safeToCompareToEmptyOrDeleted) { |
| 533 if (HashTranslator::equal(Extractor::extract(*entry), key)) | 551 if (HashTranslator::equal(Extractor::extract(*entry), key)) |
| 534 return entry; | 552 return entry; |
| 535 | 553 |
| 536 if (isEmptyBucket(*entry)) | 554 if (isEmptyBucket(*entry)) |
| 537 return 0; | 555 return 0; |
| 538 } else { | 556 } else { |
| 539 if (isEmptyBucket(*entry)) | 557 if (isEmptyBucket(*entry)) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 556 k = 1 | doubleHash(h); | 574 k = 1 | doubleHash(h); |
| 557 i = (i + k) & sizeMask; | 575 i = (i + k) & sizeMask; |
| 558 } | 576 } |
| 559 } | 577 } |
| 560 | 578 |
| 561 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 579 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
| 562 template<typename HashTranslator, typename T> | 580 template<typename HashTranslator, typename T> |
| 563 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) | 581 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) |
| 564 { | 582 { |
| 565 ASSERT(m_table); | 583 ASSERT(m_table); |
| 584 registerModification(); |
| 566 | 585 |
| 567 size_t k = 0; | 586 size_t k = 0; |
| 568 ValueType* table = m_table; | 587 ValueType* table = m_table; |
| 569 size_t sizeMask = m_tableSizeMask; | 588 size_t sizeMask = m_tableSizeMask; |
| 570 unsigned h = HashTranslator::hash(key); | 589 unsigned h = HashTranslator::hash(key); |
| 571 size_t i = h & sizeMask; | 590 size_t i = h & sizeMask; |
| 572 | 591 |
| 573 #if DUMP_HASHTABLE_STATS | 592 #if DUMP_HASHTABLE_STATS |
| 574 atomicIncrement(&HashTableStats::numAccesses); | 593 atomicIncrement(&HashTableStats::numAccesses); |
| 575 int probeCount = 0; | 594 int probeCount = 0; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 k = 1 | doubleHash(h); | 637 k = 1 | doubleHash(h); |
| 619 i = (i + k) & sizeMask; | 638 i = (i + k) & sizeMask; |
| 620 } | 639 } |
| 621 } | 640 } |
| 622 | 641 |
| 623 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 642 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
| 624 template<typename HashTranslator, typename T> | 643 template<typename HashTranslator, typename T> |
| 625 inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyT
raits, Allocator>::FullLookupType HashTable<Key, Value, Extractor, HashFunctions
, Traits, KeyTraits, Allocator>::fullLookupForWriting(const T& key) | 644 inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyT
raits, Allocator>::FullLookupType HashTable<Key, Value, Extractor, HashFunctions
, Traits, KeyTraits, Allocator>::fullLookupForWriting(const T& key) |
| 626 { | 645 { |
| 627 ASSERT(m_table); | 646 ASSERT(m_table); |
| 647 registerModification(); |
| 628 | 648 |
| 629 size_t k = 0; | 649 size_t k = 0; |
| 630 ValueType* table = m_table; | 650 ValueType* table = m_table; |
| 631 size_t sizeMask = m_tableSizeMask; | 651 size_t sizeMask = m_tableSizeMask; |
| 632 unsigned h = HashTranslator::hash(key); | 652 unsigned h = HashTranslator::hash(key); |
| 633 size_t i = h & sizeMask; | 653 size_t i = h & sizeMask; |
| 634 | 654 |
| 635 #if DUMP_HASHTABLE_STATS | 655 #if DUMP_HASHTABLE_STATS |
| 636 atomicIncrement(&HashTableStats::numAccesses); | 656 atomicIncrement(&HashTableStats::numAccesses); |
| 637 int probeCount = 0; | 657 int probeCount = 0; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 724 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
| 705 inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait
s, Allocator>::initializeBucket(ValueType& bucket) | 725 inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTrait
s, Allocator>::initializeBucket(ValueType& bucket) |
| 706 { | 726 { |
| 707 HashTableBucketInitializer<Traits::emptyValueIsZero>::template initializ
e<Traits>(bucket); | 727 HashTableBucketInitializer<Traits::emptyValueIsZero>::template initializ
e<Traits>(bucket); |
| 708 } | 728 } |
| 709 | 729 |
| 710 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 730 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
| 711 template<typename HashTranslator, typename T, typename Extra> | 731 template<typename HashTranslator, typename T, typename Extra> |
| 712 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits,
Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, Ke
yTraits, Allocator>::add(const T& key, const Extra& extra) | 732 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits,
Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, Ke
yTraits, Allocator>::add(const T& key, const Extra& extra) |
| 713 { | 733 { |
| 734 registerModification(); |
| 714 if (!m_table) | 735 if (!m_table) |
| 715 expand(); | 736 expand(); |
| 716 | 737 |
| 717 ASSERT(m_table); | 738 ASSERT(m_table); |
| 718 | 739 |
| 719 size_t k = 0; | 740 size_t k = 0; |
| 720 ValueType* table = m_table; | 741 ValueType* table = m_table; |
| 721 size_t sizeMask = m_tableSizeMask; | 742 size_t sizeMask = m_tableSizeMask; |
| 722 unsigned h = HashTranslator::hash(key); | 743 unsigned h = HashTranslator::hash(key); |
| 723 size_t i = h & sizeMask; | 744 size_t i = h & sizeMask; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 if (shouldExpand()) | 807 if (shouldExpand()) |
| 787 entry = expand(entry); | 808 entry = expand(entry); |
| 788 | 809 |
| 789 return AddResult(entry, true); | 810 return AddResult(entry, true); |
| 790 } | 811 } |
| 791 | 812 |
| 792 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> | 813 template<typename Key, typename Value, typename Extractor, typename HashFunc
tions, typename Traits, typename KeyTraits, typename Allocator> |
| 793 template<typename HashTranslator, typename T, typename Extra> | 814 template<typename HashTranslator, typename T, typename Extra> |
| 794 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits,
Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, Ke
yTraits, Allocator>::addPassingHashCode(const T& key, const Extra& extra) | 815 typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits,
Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, Ke
yTraits, Allocator>::addPassingHashCode(const T& key, const Extra& extra) |
| 795 { | 816 { |
| 817 registerModification(); |
| 796 if (!m_table) | 818 if (!m_table) |
| 797 expand(); | 819 expand(); |
| 798 | 820 |
| 799 FullLookupType lookupResult = fullLookupForWriting<HashTranslator>(key); | 821 FullLookupType lookupResult = fullLookupForWriting<HashTranslator>(key); |
| 800 | 822 |
| 801 ValueType* entry = lookupResult.first.first; | 823 ValueType* entry = lookupResult.first.first; |
| 802 bool found = lookupResult.first.second; | 824 bool found = lookupResult.first.second; |
| 803 unsigned h = lookupResult.second; | 825 unsigned h = lookupResult.second; |
| 804 | 826 |
| 805 if (found) | 827 if (found) |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1228 inline bool operator!=(const HashTableIteratorAdapter<T, U>& a, const HashTa
bleConstIteratorAdapter<T, U>& b) | 1250 inline bool operator!=(const HashTableIteratorAdapter<T, U>& a, const HashTa
bleConstIteratorAdapter<T, U>& b) |
| 1229 { | 1251 { |
| 1230 return a.m_impl != b.m_impl; | 1252 return a.m_impl != b.m_impl; |
| 1231 } | 1253 } |
| 1232 | 1254 |
| 1233 } // namespace WTF | 1255 } // namespace WTF |
| 1234 | 1256 |
| 1235 #include "wtf/HashIterators.h" | 1257 #include "wtf/HashIterators.h" |
| 1236 | 1258 |
| 1237 #endif // WTF_HashTable_h | 1259 #endif // WTF_HashTable_h |
| OLD | NEW |