00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _XN_HASH_H
00027 #define _XN_HASH_H
00028
00029
00030
00031
00032 #include "XnList.h"
00033
00034
00035
00036
00037 #define XN_HASH_LAST_BIN 256
00038 #define XN_HASH_NUM_BINS (XN_HASH_LAST_BIN + 1)
00039
00040
00041
00045 typedef XnValue XnKey;
00046
00050 typedef XnUInt8 XnHashValue;
00051
00055 static XnHashValue XnDefaultHashFunction(const XnKey& key)
00056 {
00057 return (XnSizeT(key) & 0xff);
00058 }
00059
00063 static XnInt32 XnDefaultCompareFunction(const XnKey& key1, const XnKey& key2)
00064 {
00065 return XnSizeT(key1)-XnSizeT(key2);
00066 }
00067
00071 class XnHash
00072 {
00073 public:
00077 class ConstIterator
00078 {
00079 public:
00080 friend class XnHash;
00081
00087 ConstIterator(const ConstIterator& other) :
00088 m_pHash(other.m_pHash), m_nCurrentBin(other.m_nCurrentBin), m_Iterator(other.m_Iterator) {}
00089
00093 ConstIterator& operator++()
00094 {
00095 ++m_Iterator;
00096
00097 while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
00098 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
00099 {
00100 do
00101 {
00102 m_nCurrentBin++;
00103 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
00104 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin();
00105 }
00106 return *this;
00107 }
00108
00112 ConstIterator operator++(int)
00113 {
00114 XnHash::ConstIterator other(*this);
00115 ++*this;
00116 return other;
00117 }
00118
00122 ConstIterator& operator--()
00123 {
00124 --m_Iterator;
00125
00126 while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
00127 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
00128 {
00129 do
00130 {
00131 if (m_nCurrentBin == 0)
00132 {
00133 m_nCurrentBin = XN_HASH_LAST_BIN;
00134 m_Iterator = m_pHash->m_Bins[XN_HASH_LAST_BIN]->end();
00135 return *this;
00136 }
00137 m_nCurrentBin--;
00138 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
00139 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->rbegin();
00140 }
00141 return *this;
00142 }
00143
00147 ConstIterator operator--(int)
00148 {
00149 ConstIterator other(*this);
00150 --*this;
00151 return other;
00152 }
00153
00159 XnBool operator==(const ConstIterator& other) const
00160 {
00161 return m_Iterator == other.m_Iterator;
00162 }
00163
00169 XnBool operator!=(const ConstIterator& other) const
00170 {
00171 return m_Iterator != other.m_Iterator;
00172 }
00173
00177 const XnKey& Key() const
00178 {
00179 return ((XnNode*)(*m_Iterator))->Data();
00180 }
00181
00185 const XnValue& Value() const
00186 {
00187 return ((XnNode*)(*m_Iterator))->Next()->Data();
00188 }
00189
00193 XnNode* GetNode()
00194 {
00195 return m_Iterator.GetNode();
00196 }
00197
00201 const XnNode* GetNode() const
00202 {
00203 return m_Iterator.GetNode();
00204 }
00205
00206 protected:
00214 ConstIterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) :
00215 m_pHash(pHash), m_nCurrentBin(nBin), m_Iterator(listIterator)
00216 {
00217
00218 while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
00219 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
00220 {
00221 do
00222 {
00223 m_nCurrentBin++;
00224 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
00225 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin();
00226 }
00227 }
00228
00234 ConstIterator(const XnHash* pHash) :
00235 m_pHash(pHash), m_nCurrentBin(0), m_Iterator(m_pHash->m_Bins[XN_HASH_LAST_BIN]->end()) {}
00236
00238 const XnHash* m_pHash;
00240 XnUInt16 m_nCurrentBin;
00242 XnList::Iterator m_Iterator;
00243 };
00244
00248 class Iterator : public ConstIterator
00249 {
00250 public:
00251 friend class XnHash;
00252
00258 inline Iterator(const Iterator& other) : ConstIterator(other) {}
00259
00263 inline Iterator& operator++()
00264 {
00265 ++(*(ConstIterator*)this);
00266 return (*this);
00267 }
00271 inline Iterator operator++(int)
00272 {
00273 Iterator result = *this;
00274 ++*this;
00275 return (result);
00276 }
00277
00281 inline Iterator& operator--()
00282 {
00283 --(*(ConstIterator*)this);
00284 return (*this);
00285 }
00289 inline Iterator operator--(int)
00290 {
00291 Iterator result = *this;
00292 --*this;
00293 return (result);
00294 }
00295
00299 XnKey& Key() const { return (XnKey&)ConstIterator::Key(); }
00300
00304 XnValue& Value() const { return (XnValue&)ConstIterator::Value(); }
00305
00306 protected:
00314 Iterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) :
00315 ConstIterator(pHash, nBin, listIterator)
00316 {}
00317
00323 Iterator(const XnHash* pHash) : ConstIterator(pHash) {}
00324
00325 Iterator(const ConstIterator& other) : ConstIterator(other) {}
00326 };
00327
00328 friend class Iterator;
00329
00330 public:
00334 typedef XnHashValue (*XnHashFunction)(const XnKey& key);
00338 typedef XnInt32 (*XnCompareFunction)(const XnKey& key1, const XnKey& key2);
00339
00343 XnHash()
00344 {
00345 m_nInitStatus = Init();
00346 }
00347
00351 XnHash(const XnHash& other)
00352 {
00353 m_nInitStatus = Init();
00354 if (m_nInitStatus == XN_STATUS_OK)
00355 {
00356 m_nMinBin = other.m_nMinBin;
00357 m_CompareFunction = other.m_CompareFunction;
00358 m_HashFunction = other.m_HashFunction;
00359 for (int i = 0; i < XN_HASH_NUM_BINS; i++)
00360 {
00361 if (other.m_Bins[i] != NULL)
00362 {
00363 m_Bins[i] = XN_NEW(XnList);
00364 if (m_Bins[i] == NULL)
00365 {
00366 m_nInitStatus = XN_STATUS_ALLOC_FAILED;
00367 return;
00368 }
00369 *(m_Bins[i]) = *(other.m_Bins[i]);
00370 }
00371 }
00372 }
00373 }
00374
00378 virtual ~XnHash()
00379 {
00380 if (m_Bins != NULL)
00381 {
00382 for (int i = 0; i < XN_HASH_NUM_BINS; ++i)
00383 {
00384 XN_DELETE(m_Bins[i]);
00385 }
00386 XN_DELETE_ARR(m_Bins);
00387 }
00388 }
00389
00395 XnStatus GetInitStatus() const
00396 {
00397 return m_nInitStatus;
00398 }
00399
00406 XnStatus Set(const XnKey& key, const XnValue& value)
00407 {
00408 XnHashValue HashValue = (*m_HashFunction)(key);
00409
00410
00411 if (m_Bins[HashValue] != NULL)
00412 {
00413 Iterator hiter(this);
00414 if (Find(key, HashValue, hiter) == XN_STATUS_OK)
00415 {
00416
00417 hiter.Value() = value;
00418 return XN_STATUS_OK;
00419 }
00420 }
00421 else
00422 {
00423
00424 m_Bins[HashValue] = XN_NEW(XnList);
00425 if (m_Bins[HashValue] == NULL)
00426 {
00427 return XN_STATUS_ALLOC_FAILED;
00428 }
00429 if (HashValue < m_nMinBin)
00430 m_nMinBin = HashValue;
00431 }
00432
00433
00434 XnNode* pKeyNode = XnNode::Allocate();
00435 if (pKeyNode == NULL)
00436 {
00437 return XN_STATUS_ALLOC_FAILED;
00438 }
00439 pKeyNode->Data() = key;
00440
00441
00442 XnNode* pValueNode = XnNode::Allocate();
00443 if (pValueNode == NULL)
00444 {
00445 XnNode::Deallocate(pKeyNode);
00446 return XN_STATUS_ALLOC_FAILED;
00447 }
00448 pValueNode->Data() = value;
00449
00450
00451 pKeyNode->Next() = pValueNode;
00452 pValueNode->Next() = NULL;
00453
00454
00455 XnStatus ListStatus = m_Bins[HashValue]->AddLast(XnValue(pKeyNode));
00456 if (ListStatus != XN_STATUS_OK)
00457 {
00458
00459 XnNode::Deallocate(pKeyNode);
00460 XnNode::Deallocate(pValueNode);
00461 return ListStatus;
00462 }
00463
00464 return XN_STATUS_OK;
00465 }
00466
00475 XnStatus Get(const XnKey& key, XnValue& value) const
00476 {
00477
00478 Iterator hiter(this);
00479 XnStatus FindStatus = Find(key, hiter);
00480 if (FindStatus != XN_STATUS_OK)
00481 {
00482
00483 return FindStatus;
00484 }
00485 value = hiter.Value();
00486
00487 return XN_STATUS_OK;
00488 }
00489
00498 XnStatus Remove(const XnKey& key, XnValue& value)
00499 {
00500
00501 Iterator hiter(this);
00502
00503 XnStatus FindStatus = Find(key, hiter);
00504 if (FindStatus != XN_STATUS_OK)
00505 {
00506
00507 return FindStatus;
00508 }
00509
00510
00511 value = hiter.Value();
00512 return Remove(hiter);
00513 }
00514
00524 XnStatus Remove(ConstIterator iter, XnKey& key, XnValue& value)
00525 {
00526 if (iter == end())
00527 {
00528
00529 return XN_STATUS_ILLEGAL_POSITION;
00530 }
00531
00532
00533 value = iter.Value();
00534 key = iter.Key();
00535
00536 return Remove(iter);
00537 }
00538
00546 virtual XnStatus Remove(ConstIterator iter)
00547 {
00548 if (iter == end())
00549 {
00550
00551 return XN_STATUS_ILLEGAL_POSITION;
00552 }
00553
00554 XnNode* pNode = iter.GetNode();
00555
00556 XnNode* pKeyNode = (XnNode*)(pNode->Data());
00557 XnNode* pValueNode = pKeyNode->Next();
00558
00559
00560 XnNode::Deallocate(pKeyNode);
00561 XnNode::Deallocate(pValueNode);
00562
00563 pNode->Previous()->Next() = pNode->Next();
00564 pNode->Next()->Previous() = pNode->Previous();
00565
00566 XnNode::Deallocate(pNode);
00567
00568 return XN_STATUS_OK;
00569 }
00570
00571
00575 XnStatus Clear()
00576 {
00577 while (begin() != end())
00578 Remove(begin());
00579
00580 return XN_STATUS_OK;
00581 }
00582
00586 XnBool IsEmpty() const
00587 {
00588 return (begin() == end());
00589 }
00590
00594 XnUInt32 Size() const
00595 {
00596 XnUInt32 nSize = 0;
00597 for (Iterator iter = begin(); iter != end(); ++iter, ++nSize)
00598 ;
00599
00600 return nSize;
00601 }
00602
00611 XnStatus Find(const XnKey& key, ConstIterator& hiter) const
00612 {
00613 XnHashValue HashValue = (*m_HashFunction)(key);
00614 return Find(key, HashValue, hiter);
00615 }
00616
00625 XnStatus Find(const XnKey& key, Iterator& hiter)
00626 {
00627 XnStatus nRetVal = XN_STATUS_OK;
00628
00629 ConstIterator& it = hiter;
00630 nRetVal = Find(key, it);
00631 XN_IS_STATUS_OK(nRetVal);
00632
00633 return (XN_STATUS_OK);
00634 }
00635
00639 Iterator begin()
00640 {
00641 return Iterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin());
00642 }
00643
00647 ConstIterator begin() const
00648 {
00649 return ConstIterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin());
00650 }
00651
00655 Iterator end()
00656 {
00657 return Iterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end());
00658 }
00659
00663 ConstIterator end() const
00664 {
00665 return ConstIterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end());
00666 }
00667
00675 XnStatus SetHashFunction(XnHashFunction hashFunction)
00676 {
00677 if (begin() != end())
00678 {
00679 return XN_STATUS_IS_NOT_EMPTY;
00680 }
00681 m_HashFunction = hashFunction;
00682 return XN_STATUS_OK;
00683 }
00684
00692 XnStatus SetCompareFunction(XnCompareFunction compareFunction)
00693 {
00694 if (begin() != end())
00695 {
00696 return XN_STATUS_IS_NOT_EMPTY;
00697 }
00698 m_CompareFunction = compareFunction;
00699 return XN_STATUS_OK;
00700 }
00701
00702 protected:
00703
00704 XnStatus Init()
00705 {
00706 m_Bins = XN_NEW_ARR(XnList*, XN_HASH_NUM_BINS);
00707 XN_VALIDATE_ALLOC_PTR(m_Bins);
00708
00709 for (int i = 0; i < XN_HASH_NUM_BINS; i++)
00710 {
00711 m_Bins[i] = NULL;
00712 }
00713
00714 m_Bins[XN_HASH_LAST_BIN] = XN_NEW(XnList);
00715 m_nMinBin = XN_HASH_LAST_BIN;
00716
00717 XN_VALIDATE_ALLOC_PTR(m_Bins[XN_HASH_LAST_BIN]);
00718 m_CompareFunction = &XnDefaultCompareFunction;
00719 m_HashFunction = &XnDefaultHashFunction;
00720 return XN_STATUS_OK;
00721 }
00722
00732 XnStatus Find(const XnKey& key, XnHashValue hashValue, ConstIterator& hiter) const
00733 {
00734 if (m_Bins[hashValue] != NULL)
00735 {
00736 hiter = ConstIterator(this, hashValue, m_Bins[hashValue]->begin());
00737 for (XnList::ConstIterator iter = m_Bins[hashValue]->begin();
00738 iter != m_Bins[hashValue]->end(); ++iter, ++hiter)
00739 {
00740 if ((*m_CompareFunction)(key, hiter.Key()) == 0)
00741 return XN_STATUS_OK;
00742 }
00743 }
00744
00745 return XN_STATUS_NO_MATCH;
00746 }
00747
00748
00750 XnList** m_Bins;
00751
00752 XnUInt16 m_nMinBin;
00753
00754
00755 XnStatus m_nInitStatus;
00756
00758 XnHashFunction m_HashFunction;
00760 XnCompareFunction m_CompareFunction;
00761 };
00762
00767 #define XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, ClassName, KeyTranslator) \
00768 class decl ClassName \
00769 { \
00770 public: \
00771 inline static XnHashValue Hash(KeyType const& key) \
00772 { \
00773 const XnKey _key = KeyTranslator::GetAsValue(key); \
00774 return XnDefaultHashFunction(_key); \
00775 } \
00776 inline static XnInt32 Compare(KeyType const& key1, KeyType const& key2) \
00777 { \
00778 const XnKey _key1 = KeyTranslator::GetAsValue(key1); \
00779 const XnKey _key2 = KeyTranslator::GetAsValue(key2); \
00780 return XnDefaultCompareFunction(_key1, _key2); \
00781 } \
00782 };
00783
00788 #define XN_DECLARE_DEFAULT_KEY_MANAGER(KeyType, ClassName, KeyTranslator) \
00789 XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(, KeyType, ClassName, KeyTranslator)
00790
00796 #define XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) \
00797 class decl ClassName : public XnHash \
00798 { \
00799 public: \
00800 class decl ConstIterator : public XnHash::ConstIterator \
00801 { \
00802 public: \
00803 friend class ClassName; \
00804 inline ConstIterator(const ConstIterator& other) : XnHash::ConstIterator(other) {} \
00805 inline ConstIterator& operator++() \
00806 { \
00807 ++(*(XnHash::ConstIterator*)this); \
00808 return (*this); \
00809 } \
00810 inline ConstIterator operator++(int) \
00811 { \
00812 ConstIterator result = *this; \
00813 ++*this; \
00814 return result; \
00815 } \
00816 inline ConstIterator& operator--() \
00817 { \
00818 --(*(XnHash::ConstIterator*)this); \
00819 return (*this); \
00820 } \
00821 inline ConstIterator operator--(int) \
00822 { \
00823 ConstIterator result = *this; \
00824 --*this; \
00825 return result; \
00826 } \
00827 inline KeyType const& Key() const \
00828 { \
00829 return KeyTranslator::GetFromValue(XnHash::ConstIterator::Key()); \
00830 } \
00831 inline ValueType const& Value() const \
00832 { \
00833 return ValueTranslator::GetFromValue(XnHash::ConstIterator::Value()); \
00834 } \
00835 protected: \
00836 inline ConstIterator(const XnHash::ConstIterator& other) : \
00837 XnHash::ConstIterator(other) {} \
00838 }; \
00839 class decl Iterator : public ConstIterator \
00840 { \
00841 public: \
00842 friend class ClassName; \
00843 inline Iterator(const Iterator& other) : ConstIterator(other) {} \
00844 inline Iterator& operator++() \
00845 { \
00846 ++(*(ConstIterator*)this); \
00847 return (*this); \
00848 } \
00849 inline Iterator operator++(int) \
00850 { \
00851 Iterator result = *this; \
00852 ++*this; \
00853 return result; \
00854 } \
00855 inline Iterator& operator--() \
00856 { \
00857 --(*(ConstIterator*)this); \
00858 return (*this); \
00859 } \
00860 inline Iterator operator--(int) \
00861 { \
00862 Iterator result = *this; \
00863 --*this; \
00864 return result; \
00865 } \
00866 inline KeyType& Key() const \
00867 { \
00868 return (KeyType&)ConstIterator::Key(); \
00869 } \
00870 inline ValueType& Value() const \
00871 { \
00872 return (ValueType&)ConstIterator::Value(); \
00873 } \
00874 protected: \
00875 inline Iterator(const XnHash::Iterator& other) : ConstIterator(other) {} \
00876 }; \
00877 public: \
00878 ClassName() \
00879 { \
00880 SetHashFunction(Hash); \
00881 SetCompareFunction(Compare); \
00882 } \
00883 ClassName(const ClassName& other) \
00884 { \
00885 SetHashFunction(Hash); \
00886 SetCompareFunction(Compare); \
00887 *this = other; \
00888 } \
00889 virtual ~ClassName() \
00890 { \
00891 while (!IsEmpty()) \
00892 Remove(begin()); \
00893 } \
00894 ClassName& operator=(const ClassName& other) \
00895 { \
00896 Clear(); \
00897 for (ConstIterator it = other.begin(); it != other.end(); it++) \
00898 { \
00899 m_nInitStatus = Set(it.Key(), it.Value()); \
00900 if (m_nInitStatus != XN_STATUS_OK) \
00901 { \
00902 return *this; \
00903 } \
00904 } \
00905 return *this; \
00906 } \
00907 XnStatus Set(KeyType const& key, ValueType const& value) \
00908 { \
00909 Iterator oldIt = begin(); \
00910 if (Find(key, oldIt) == XN_STATUS_OK) \
00911 { \
00912 oldIt.Value() = value; \
00913 } \
00914 else \
00915 { \
00916 XnKey _key = KeyTranslator::CreateValueCopy(key); \
00917 XnValue _value = ValueTranslator::CreateValueCopy(value); \
00918 XnStatus nRetVal = XnHash::Set(_key, _value); \
00919 if (nRetVal != XN_STATUS_OK) \
00920 { \
00921 KeyTranslator::FreeValue(_key); \
00922 ValueTranslator::FreeValue(_value); \
00923 return (nRetVal); \
00924 } \
00925 } \
00926 return XN_STATUS_OK; \
00927 } \
00928 XnStatus Get(KeyType const& key, ValueType& value) const \
00929 { \
00930 XnKey _key = KeyTranslator::GetAsValue(key); \
00931 XnValue _value; \
00932 XnStatus nRetVal = XnHash::Get(_key, _value); \
00933 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00934 value = ValueTranslator::GetFromValue(_value); \
00935 return XN_STATUS_OK; \
00936 } \
00937 XnStatus Get(KeyType const& key, ValueType*& pValue) const \
00938 { \
00939 XnKey _key = KeyTranslator::GetAsValue(key); \
00940 XnValue _value; \
00941 XnStatus nRetVal = XnHash::Get(_key, _value); \
00942 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00943 pValue = &ValueTranslator::GetFromValue(_value); \
00944 return XN_STATUS_OK; \
00945 } \
00946 XnStatus Remove(KeyType const& key) \
00947 { \
00948 ValueType dummy; \
00949 return Remove(key, dummy); \
00950 } \
00951 XnStatus Remove(KeyType const& key, ValueType& value) \
00952 { \
00953 ConstIterator it = end(); \
00954 XnStatus nRetVal = Find(key, it); \
00955 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00956 value = it.Value(); \
00957 return Remove(it); \
00958 } \
00959 inline XnStatus Remove(ConstIterator iter) \
00960 { \
00961 XnKey key = KeyTranslator::GetAsValue(iter.Key()); \
00962 XnValue value = ValueTranslator::GetAsValue(iter.Value()); \
00963 XnStatus nRetVal = XnHash::Remove(iter); \
00964 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00965 KeyTranslator::FreeValue(key); \
00966 ValueTranslator::FreeValue(value); \
00967 return XN_STATUS_OK; \
00968 } \
00969 XnStatus Find(KeyType const& key, ConstIterator& hiter) const \
00970 { \
00971 XnKey _key = KeyTranslator::GetAsValue(key); \
00972 XnHash::ConstIterator it = XnHash::end(); \
00973 XnStatus nRetVal = XnHash::Find(_key, it); \
00974 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00975 hiter = it; \
00976 return XN_STATUS_OK; \
00977 } \
00978 XnStatus Find(KeyType const& key, Iterator& hiter) \
00979 { \
00980 XnKey _key = KeyTranslator::GetAsValue(key); \
00981 XnHash::Iterator it = XnHash::end(); \
00982 XnStatus nRetVal = XnHash::Find(_key, it); \
00983 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00984 hiter = it; \
00985 return XN_STATUS_OK; \
00986 } \
00987 inline Iterator begin() { return XnHash::begin(); } \
00988 inline ConstIterator begin() const { return XnHash::begin(); } \
00989 inline Iterator end() { return XnHash::end(); } \
00990 inline ConstIterator end() const { return XnHash::end(); } \
00991 protected: \
00992 virtual XnStatus Remove(XnHash::ConstIterator iter) \
00993 { \
00994 return Remove(ConstIterator(iter)); \
00995 } \
00996 inline static XnHashValue Hash(const XnKey& key) \
00997 { \
00998 KeyType const& _key = KeyTranslator::GetFromValue(key); \
00999 return KeyManager::Hash(_key); \
01000 } \
01001 inline static XnInt32 Compare(const XnKey& key1, const XnKey& key2) \
01002 { \
01003 KeyType const _key1 = KeyTranslator::GetFromValue(key1); \
01004 KeyType const _key2 = KeyTranslator::GetFromValue(key2); \
01005 return KeyManager::Compare(_key1, _key2); \
01006 } \
01007 };
01008
01013 #define XN_DECLARE_HASH(KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) \
01014 XN_DECLARE_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager)
01015
01016 #define _XN_DEFAULT_KEY_MANAGER_NAME(ClassName) _##ClassName##Manager
01017
01023 #define XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) \
01024 XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName), KeyTranslator) \
01025 XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName))
01026
01031 #define XN_DECLARE_DEFAULT_MANAGER_HASH(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) \
01032 XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator)
01033
01034 #define _XN_DEFAULT_KEY_TRANSLATOR(ClassName) _##ClassName##KeyTranslator
01035 #define _XN_DEFAULT_VALUE_TRANSLATOR(ClassName) _##ClassName##ValueTranslator
01036
01042 #define XN_DECLARE_DEFAULT_HASH_DECL(decl, KeyType, ValueType, ClassName) \
01043 XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, KeyType, _XN_DEFAULT_KEY_TRANSLATOR(ClassName)) \
01044 XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, ValueType, _XN_DEFAULT_VALUE_TRANSLATOR(ClassName)) \
01045 XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, _XN_DEFAULT_KEY_TRANSLATOR(ClassName), _XN_DEFAULT_VALUE_TRANSLATOR(ClassName))
01046
01051 #define XN_DECLARE_DEFAULT_HASH(KeyType, ValueType, ClassName) \
01052 XN_DECLARE_DEFAULT_HASH_DECL(, KeyType, ValueType, ClassName)
01053
01054 #endif // _XN_HASH_H