00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _XN_HASH_H
00023 #define _XN_HASH_H
00024
00025
00026
00027
00028 #include "XnList.h"
00029
00030
00031
00032
00033 #define XN_HASH_LAST_BIN 256
00034 #define XN_HASH_NUM_BINS (XN_HASH_LAST_BIN + 1)
00035
00036
00037
00041 typedef XnValue XnKey;
00042
00046 typedef XnUInt8 XnHashValue;
00047
00051 static XnHashValue XnDefaultHashFunction(const XnKey& key)
00052 {
00053 return (XnSizeT(key) & 0xff);
00054 }
00055
00059 static XnInt32 XnDefaultCompareFunction(const XnKey& key1, const XnKey& key2)
00060 {
00061 return XnInt32(XnSizeT(key1)-XnSizeT(key2));
00062 }
00063
00067 class XnHash
00068 {
00069 public:
00073 class ConstIterator
00074 {
00075 public:
00076 friend class XnHash;
00077
00083 ConstIterator(const ConstIterator& other) :
00084 m_pHash(other.m_pHash), m_nCurrentBin(other.m_nCurrentBin), m_Iterator(other.m_Iterator) {}
00085
00089 ConstIterator& operator++()
00090 {
00091 ++m_Iterator;
00092
00093 while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
00094 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
00095 {
00096 do
00097 {
00098 m_nCurrentBin++;
00099 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
00100 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin();
00101 }
00102 return *this;
00103 }
00104
00108 ConstIterator operator++(int)
00109 {
00110 XnHash::ConstIterator other(*this);
00111 ++*this;
00112 return other;
00113 }
00114
00118 ConstIterator& operator--()
00119 {
00120 --m_Iterator;
00121
00122 while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
00123 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
00124 {
00125 do
00126 {
00127 if (m_nCurrentBin == 0)
00128 {
00129 m_nCurrentBin = XN_HASH_LAST_BIN;
00130 m_Iterator = m_pHash->m_Bins[XN_HASH_LAST_BIN]->end();
00131 return *this;
00132 }
00133 m_nCurrentBin--;
00134 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
00135 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->rbegin();
00136 }
00137 return *this;
00138 }
00139
00143 ConstIterator operator--(int)
00144 {
00145 ConstIterator other(*this);
00146 --*this;
00147 return other;
00148 }
00149
00155 XnBool operator==(const ConstIterator& other) const
00156 {
00157 return m_Iterator == other.m_Iterator;
00158 }
00159
00165 XnBool operator!=(const ConstIterator& other) const
00166 {
00167 return m_Iterator != other.m_Iterator;
00168 }
00169
00173 const XnKey& Key() const
00174 {
00175 return ((XnNode*)(*m_Iterator))->Data();
00176 }
00177
00181 const XnValue& Value() const
00182 {
00183 return ((XnNode*)(*m_Iterator))->Next()->Data();
00184 }
00185
00189 XnNode* GetNode()
00190 {
00191 return m_Iterator.GetNode();
00192 }
00193
00197 const XnNode* GetNode() const
00198 {
00199 return m_Iterator.GetNode();
00200 }
00201
00202 protected:
00210 ConstIterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) :
00211 m_pHash(pHash), m_nCurrentBin(nBin), m_Iterator(listIterator)
00212 {
00213
00214 while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
00215 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
00216 {
00217 do
00218 {
00219 m_nCurrentBin++;
00220 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
00221 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin();
00222 }
00223 }
00224
00230 ConstIterator(const XnHash* pHash) :
00231 m_pHash(pHash), m_nCurrentBin(0), m_Iterator(m_pHash->m_Bins[XN_HASH_LAST_BIN]->end()) {}
00232
00234 const XnHash* m_pHash;
00236 XnUInt16 m_nCurrentBin;
00238 XnList::Iterator m_Iterator;
00239 };
00240
00244 class Iterator : public ConstIterator
00245 {
00246 public:
00247 friend class XnHash;
00248
00254 inline Iterator(const Iterator& other) : ConstIterator(other) {}
00255
00259 inline Iterator& operator++()
00260 {
00261 ++(*(ConstIterator*)this);
00262 return (*this);
00263 }
00267 inline Iterator operator++(int)
00268 {
00269 Iterator result = *this;
00270 ++*this;
00271 return (result);
00272 }
00273
00277 inline Iterator& operator--()
00278 {
00279 --(*(ConstIterator*)this);
00280 return (*this);
00281 }
00285 inline Iterator operator--(int)
00286 {
00287 Iterator result = *this;
00288 --*this;
00289 return (result);
00290 }
00291
00295 XnKey& Key() const { return (XnKey&)ConstIterator::Key(); }
00296
00300 XnValue& Value() const { return (XnValue&)ConstIterator::Value(); }
00301
00302 protected:
00310 Iterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) :
00311 ConstIterator(pHash, nBin, listIterator)
00312 {}
00313
00319 Iterator(const XnHash* pHash) : ConstIterator(pHash) {}
00320
00321 Iterator(const ConstIterator& other) : ConstIterator(other) {}
00322 };
00323
00324 friend class ConstIterator;
00325
00326 public:
00330 typedef XnHashValue (*XnHashFunction)(const XnKey& key);
00334 typedef XnInt32 (*XnCompareFunction)(const XnKey& key1, const XnKey& key2);
00335
00339 XnHash()
00340 {
00341 m_nInitStatus = Init();
00342 }
00343
00347 XnHash(const XnHash& other)
00348 {
00349 m_nInitStatus = Init();
00350 if (m_nInitStatus == XN_STATUS_OK)
00351 {
00352 m_nMinBin = other.m_nMinBin;
00353 m_CompareFunction = other.m_CompareFunction;
00354 m_HashFunction = other.m_HashFunction;
00355 for (int i = 0; i < XN_HASH_NUM_BINS; i++)
00356 {
00357 if (other.m_Bins[i] != NULL)
00358 {
00359 m_Bins[i] = XN_NEW(XnList);
00360 if (m_Bins[i] == NULL)
00361 {
00362 m_nInitStatus = XN_STATUS_ALLOC_FAILED;
00363 return;
00364 }
00365 *(m_Bins[i]) = *(other.m_Bins[i]);
00366 }
00367 }
00368 }
00369 }
00370
00374 virtual ~XnHash()
00375 {
00376 if (m_Bins != NULL)
00377 {
00378 for (int i = 0; i < XN_HASH_NUM_BINS; ++i)
00379 {
00380 XN_DELETE(m_Bins[i]);
00381 }
00382 XN_DELETE_ARR(m_Bins);
00383 }
00384 }
00385
00391 XnStatus GetInitStatus() const
00392 {
00393 return m_nInitStatus;
00394 }
00395
00402 XnStatus Set(const XnKey& key, const XnValue& value)
00403 {
00404 XnHashValue HashValue = (*m_HashFunction)(key);
00405
00406
00407 if (m_Bins[HashValue] != NULL)
00408 {
00409 Iterator hiter(this);
00410 if (Find(key, HashValue, hiter) == XN_STATUS_OK)
00411 {
00412
00413 hiter.Value() = value;
00414 return XN_STATUS_OK;
00415 }
00416 }
00417 else
00418 {
00419
00420 m_Bins[HashValue] = XN_NEW(XnList);
00421 if (m_Bins[HashValue] == NULL)
00422 {
00423 return XN_STATUS_ALLOC_FAILED;
00424 }
00425 if (HashValue < m_nMinBin)
00426 m_nMinBin = HashValue;
00427 }
00428
00429
00430 XnNode* pKeyNode = XnNode::Allocate();
00431 if (pKeyNode == NULL)
00432 {
00433 return XN_STATUS_ALLOC_FAILED;
00434 }
00435 pKeyNode->Data() = key;
00436
00437
00438 XnNode* pValueNode = XnNode::Allocate();
00439 if (pValueNode == NULL)
00440 {
00441 XnNode::Deallocate(pKeyNode);
00442 return XN_STATUS_ALLOC_FAILED;
00443 }
00444 pValueNode->Data() = value;
00445
00446
00447 pKeyNode->Next() = pValueNode;
00448 pValueNode->Next() = NULL;
00449
00450
00451 XnStatus ListStatus = m_Bins[HashValue]->AddLast(XnValue(pKeyNode));
00452 if (ListStatus != XN_STATUS_OK)
00453 {
00454
00455 XnNode::Deallocate(pKeyNode);
00456 XnNode::Deallocate(pValueNode);
00457 return ListStatus;
00458 }
00459
00460 return XN_STATUS_OK;
00461 }
00462
00471 XnStatus Get(const XnKey& key, XnValue& value) const
00472 {
00473
00474 Iterator hiter(this);
00475 XnStatus FindStatus = Find(key, hiter);
00476 if (FindStatus != XN_STATUS_OK)
00477 {
00478
00479 return FindStatus;
00480 }
00481 value = hiter.Value();
00482
00483 return XN_STATUS_OK;
00484 }
00485
00494 XnStatus Remove(const XnKey& key, XnValue& value)
00495 {
00496
00497 Iterator hiter(this);
00498
00499 XnStatus FindStatus = Find(key, hiter);
00500 if (FindStatus != XN_STATUS_OK)
00501 {
00502
00503 return FindStatus;
00504 }
00505
00506
00507 value = hiter.Value();
00508 return Remove(hiter);
00509 }
00510
00520 XnStatus Remove(ConstIterator iter, XnKey& key, XnValue& value)
00521 {
00522 if (iter == end())
00523 {
00524
00525 return XN_STATUS_ILLEGAL_POSITION;
00526 }
00527
00528
00529 value = iter.Value();
00530 key = iter.Key();
00531
00532 return Remove(iter);
00533 }
00534
00542 virtual XnStatus Remove(ConstIterator iter)
00543 {
00544 if (iter == end())
00545 {
00546
00547 return XN_STATUS_ILLEGAL_POSITION;
00548 }
00549
00550 XnNode* pNode = iter.GetNode();
00551
00552 XnNode* pKeyNode = (XnNode*)(pNode->Data());
00553 XnNode* pValueNode = pKeyNode->Next();
00554
00555
00556 XnNode::Deallocate(pKeyNode);
00557 XnNode::Deallocate(pValueNode);
00558
00559 pNode->Previous()->Next() = pNode->Next();
00560 pNode->Next()->Previous() = pNode->Previous();
00561
00562 XnNode::Deallocate(pNode);
00563
00564 return XN_STATUS_OK;
00565 }
00566
00567
00571 XnStatus Clear()
00572 {
00573 while (begin() != end())
00574 Remove(begin());
00575
00576 return XN_STATUS_OK;
00577 }
00578
00582 XnBool IsEmpty() const
00583 {
00584 return (begin() == end());
00585 }
00586
00590 XnUInt32 Size() const
00591 {
00592 XnUInt32 nSize = 0;
00593 for (Iterator iter = begin(); iter != end(); ++iter, ++nSize)
00594 ;
00595
00596 return nSize;
00597 }
00598
00607 XnStatus Find(const XnKey& key, ConstIterator& hiter) const
00608 {
00609 return ConstFind(key, hiter);
00610 }
00611
00620 XnStatus Find(const XnKey& key, Iterator& hiter)
00621 {
00622 XnStatus nRetVal = XN_STATUS_OK;
00623
00624 ConstIterator& it = hiter;
00625 nRetVal = ConstFind(key, it);
00626 XN_IS_STATUS_OK(nRetVal);
00627
00628 return (XN_STATUS_OK);
00629 }
00630
00634 Iterator begin()
00635 {
00636 return Iterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin());
00637 }
00638
00642 ConstIterator begin() const
00643 {
00644 return ConstIterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin());
00645 }
00646
00650 Iterator end()
00651 {
00652 return Iterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end());
00653 }
00654
00658 ConstIterator end() const
00659 {
00660 return ConstIterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end());
00661 }
00662
00670 XnStatus SetHashFunction(XnHashFunction hashFunction)
00671 {
00672 if (begin() != end())
00673 {
00674 return XN_STATUS_IS_NOT_EMPTY;
00675 }
00676 m_HashFunction = hashFunction;
00677 return XN_STATUS_OK;
00678 }
00679
00687 XnStatus SetCompareFunction(XnCompareFunction compareFunction)
00688 {
00689 if (begin() != end())
00690 {
00691 return XN_STATUS_IS_NOT_EMPTY;
00692 }
00693 m_CompareFunction = compareFunction;
00694 return XN_STATUS_OK;
00695 }
00696
00697 protected:
00698
00699 XnStatus Init()
00700 {
00701 m_Bins = XN_NEW_ARR(XnList*, XN_HASH_NUM_BINS);
00702 XN_VALIDATE_ALLOC_PTR(m_Bins);
00703
00704 for (int i = 0; i < XN_HASH_NUM_BINS; i++)
00705 {
00706 m_Bins[i] = NULL;
00707 }
00708
00709 m_Bins[XN_HASH_LAST_BIN] = XN_NEW(XnList);
00710 m_nMinBin = XN_HASH_LAST_BIN;
00711
00712 XN_VALIDATE_ALLOC_PTR(m_Bins[XN_HASH_LAST_BIN]);
00713 m_CompareFunction = &XnDefaultCompareFunction;
00714 m_HashFunction = &XnDefaultHashFunction;
00715 return XN_STATUS_OK;
00716 }
00717
00727 XnStatus Find(const XnKey& key, XnHashValue hashValue, ConstIterator& hiter) const
00728 {
00729 if (m_Bins[hashValue] != NULL)
00730 {
00731 hiter = ConstIterator(this, hashValue, m_Bins[hashValue]->begin());
00732 for (XnList::ConstIterator iter = m_Bins[hashValue]->begin();
00733 iter != m_Bins[hashValue]->end(); ++iter, ++hiter)
00734 {
00735 if ((*m_CompareFunction)(key, hiter.Key()) == 0)
00736 return XN_STATUS_OK;
00737 }
00738 }
00739
00740 return XN_STATUS_NO_MATCH;
00741 }
00742
00743
00745 XnList** m_Bins;
00746
00747 XnUInt16 m_nMinBin;
00748
00749
00750 XnStatus m_nInitStatus;
00751
00753 XnHashFunction m_HashFunction;
00755 XnCompareFunction m_CompareFunction;
00756
00757 private:
00758 XnStatus ConstFind(const XnKey& key, ConstIterator& hiter) const
00759 {
00760 XnHashValue HashValue = (*m_HashFunction)(key);
00761 return Find(key, HashValue, hiter);
00762 }
00763 };
00764
00769 #define XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, ClassName, KeyTranslator) \
00770 class decl ClassName \
00771 { \
00772 public: \
00773 inline static XnHashValue Hash(KeyType const& key) \
00774 { \
00775 const XnKey _key = KeyTranslator::GetAsValue(key); \
00776 return XnDefaultHashFunction(_key); \
00777 } \
00778 inline static XnInt32 Compare(KeyType const& key1, KeyType const& key2) \
00779 { \
00780 const XnKey _key1 = KeyTranslator::GetAsValue(key1); \
00781 const XnKey _key2 = KeyTranslator::GetAsValue(key2); \
00782 return XnDefaultCompareFunction(_key1, _key2); \
00783 } \
00784 };
00785
00790 #define XN_DECLARE_DEFAULT_KEY_MANAGER(KeyType, ClassName, KeyTranslator) \
00791 XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(, KeyType, ClassName, KeyTranslator)
00792
00798 #define XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) \
00799 class decl ClassName : public XnHash \
00800 { \
00801 public: \
00802 class decl ConstIterator : public XnHash::ConstIterator \
00803 { \
00804 public: \
00805 friend class ClassName; \
00806 inline ConstIterator(const ConstIterator& other) : XnHash::ConstIterator(other) {} \
00807 inline ConstIterator& operator++() \
00808 { \
00809 ++(*(XnHash::ConstIterator*)this); \
00810 return (*this); \
00811 } \
00812 inline ConstIterator operator++(int) \
00813 { \
00814 ConstIterator result = *this; \
00815 ++*this; \
00816 return result; \
00817 } \
00818 inline ConstIterator& operator--() \
00819 { \
00820 --(*(XnHash::ConstIterator*)this); \
00821 return (*this); \
00822 } \
00823 inline ConstIterator operator--(int) \
00824 { \
00825 ConstIterator result = *this; \
00826 --*this; \
00827 return result; \
00828 } \
00829 inline KeyType const& Key() const \
00830 { \
00831 return KeyTranslator::GetFromValue(XnHash::ConstIterator::Key()); \
00832 } \
00833 inline ValueType const& Value() const \
00834 { \
00835 return ValueTranslator::GetFromValue(XnHash::ConstIterator::Value()); \
00836 } \
00837 protected: \
00838 inline ConstIterator(const XnHash::ConstIterator& other) : \
00839 XnHash::ConstIterator(other) {} \
00840 }; \
00841 class decl Iterator : public ConstIterator \
00842 { \
00843 public: \
00844 friend class ClassName; \
00845 inline Iterator(const Iterator& other) : ConstIterator(other) {} \
00846 inline Iterator& operator++() \
00847 { \
00848 ++(*(ConstIterator*)this); \
00849 return (*this); \
00850 } \
00851 inline Iterator operator++(int) \
00852 { \
00853 Iterator result = *this; \
00854 ++*this; \
00855 return result; \
00856 } \
00857 inline Iterator& operator--() \
00858 { \
00859 --(*(ConstIterator*)this); \
00860 return (*this); \
00861 } \
00862 inline Iterator operator--(int) \
00863 { \
00864 Iterator result = *this; \
00865 --*this; \
00866 return result; \
00867 } \
00868 inline KeyType& Key() const \
00869 { \
00870 return (KeyType&)ConstIterator::Key(); \
00871 } \
00872 inline ValueType& Value() const \
00873 { \
00874 return (ValueType&)ConstIterator::Value(); \
00875 } \
00876 protected: \
00877 inline Iterator(const XnHash::Iterator& other) : ConstIterator(other) {} \
00878 }; \
00879 public: \
00880 ClassName() \
00881 { \
00882 SetHashFunction(Hash); \
00883 SetCompareFunction(Compare); \
00884 } \
00885 ClassName(const ClassName& other) \
00886 { \
00887 SetHashFunction(Hash); \
00888 SetCompareFunction(Compare); \
00889 *this = other; \
00890 } \
00891 virtual ~ClassName() \
00892 { \
00893 while (!IsEmpty()) \
00894 Remove(begin()); \
00895 } \
00896 ClassName& operator=(const ClassName& other) \
00897 { \
00898 Clear(); \
00899 for (ConstIterator it = other.begin(); it != other.end(); it++) \
00900 { \
00901 m_nInitStatus = Set(it.Key(), it.Value()); \
00902 if (m_nInitStatus != XN_STATUS_OK) \
00903 { \
00904 return *this; \
00905 } \
00906 } \
00907 return *this; \
00908 } \
00909 XnStatus Set(KeyType const& key, ValueType const& value) \
00910 { \
00911 Iterator oldIt = begin(); \
00912 if (Find(key, oldIt) == XN_STATUS_OK) \
00913 { \
00914 oldIt.Value() = value; \
00915 } \
00916 else \
00917 { \
00918 XnKey _key = KeyTranslator::CreateValueCopy(key); \
00919 XnValue _value = ValueTranslator::CreateValueCopy(value); \
00920 XnStatus nRetVal = XnHash::Set(_key, _value); \
00921 if (nRetVal != XN_STATUS_OK) \
00922 { \
00923 KeyTranslator::FreeValue(_key); \
00924 ValueTranslator::FreeValue(_value); \
00925 return (nRetVal); \
00926 } \
00927 } \
00928 return XN_STATUS_OK; \
00929 } \
00930 XnStatus Get(KeyType const& key, ValueType& value) const \
00931 { \
00932 XnKey _key = KeyTranslator::GetAsValue(key); \
00933 XnValue _value; \
00934 XnStatus nRetVal = XnHash::Get(_key, _value); \
00935 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00936 value = ValueTranslator::GetFromValue(_value); \
00937 return XN_STATUS_OK; \
00938 } \
00939 XnStatus Get(KeyType const& key, ValueType*& pValue) const \
00940 { \
00941 XnKey _key = KeyTranslator::GetAsValue(key); \
00942 XnValue _value; \
00943 XnStatus nRetVal = XnHash::Get(_key, _value); \
00944 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00945 pValue = &ValueTranslator::GetFromValue(_value); \
00946 return XN_STATUS_OK; \
00947 } \
00948 XnStatus Remove(KeyType const& key) \
00949 { \
00950 ValueType dummy; \
00951 return Remove(key, dummy); \
00952 } \
00953 XnStatus Remove(KeyType const& key, ValueType& value) \
00954 { \
00955 ConstIterator it = end(); \
00956 XnStatus nRetVal = Find(key, it); \
00957 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00958 value = it.Value(); \
00959 return Remove(it); \
00960 } \
00961 inline XnStatus Remove(ConstIterator iter) \
00962 { \
00963 XnKey key = KeyTranslator::GetAsValue(iter.Key()); \
00964 XnValue value = ValueTranslator::GetAsValue(iter.Value()); \
00965 XnStatus nRetVal = XnHash::Remove(iter); \
00966 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00967 KeyTranslator::FreeValue(key); \
00968 ValueTranslator::FreeValue(value); \
00969 return XN_STATUS_OK; \
00970 } \
00971 XnStatus Find(KeyType const& key, ConstIterator& hiter) const \
00972 { \
00973 XnKey _key = KeyTranslator::GetAsValue(key); \
00974 XnHash::ConstIterator it = XnHash::end(); \
00975 XnStatus nRetVal = XnHash::Find(_key, it); \
00976 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00977 hiter = it; \
00978 return XN_STATUS_OK; \
00979 } \
00980 XnStatus Find(KeyType const& key, Iterator& hiter) \
00981 { \
00982 XnKey _key = KeyTranslator::GetAsValue(key); \
00983 XnHash::Iterator it = XnHash::end(); \
00984 XnStatus nRetVal = XnHash::Find(_key, it); \
00985 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00986 hiter = it; \
00987 return XN_STATUS_OK; \
00988 } \
00989 inline Iterator begin() { return XnHash::begin(); } \
00990 inline ConstIterator begin() const { return XnHash::begin(); } \
00991 inline Iterator end() { return XnHash::end(); } \
00992 inline ConstIterator end() const { return XnHash::end(); } \
00993 protected: \
00994 virtual XnStatus Remove(XnHash::ConstIterator iter) \
00995 { \
00996 return Remove(ConstIterator(iter)); \
00997 } \
00998 inline static XnHashValue Hash(const XnKey& key) \
00999 { \
01000 KeyType const& _key = KeyTranslator::GetFromValue(key); \
01001 return KeyManager::Hash(_key); \
01002 } \
01003 inline static XnInt32 Compare(const XnKey& key1, const XnKey& key2) \
01004 { \
01005 KeyType const _key1 = KeyTranslator::GetFromValue(key1); \
01006 KeyType const _key2 = KeyTranslator::GetFromValue(key2); \
01007 return KeyManager::Compare(_key1, _key2); \
01008 } \
01009 };
01010
01015 #define XN_DECLARE_HASH(KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) \
01016 XN_DECLARE_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager)
01017
01018 #define _XN_DEFAULT_KEY_MANAGER_NAME(ClassName) _##ClassName##Manager
01019
01025 #define XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) \
01026 XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName), KeyTranslator) \
01027 XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName))
01028
01033 #define XN_DECLARE_DEFAULT_MANAGER_HASH(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) \
01034 XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator)
01035
01036 #define _XN_DEFAULT_KEY_TRANSLATOR(ClassName) _##ClassName##KeyTranslator
01037 #define _XN_DEFAULT_VALUE_TRANSLATOR(ClassName) _##ClassName##ValueTranslator
01038
01044 #define XN_DECLARE_DEFAULT_HASH_DECL(decl, KeyType, ValueType, ClassName) \
01045 XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, KeyType, _XN_DEFAULT_KEY_TRANSLATOR(ClassName)) \
01046 XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, ValueType, _XN_DEFAULT_VALUE_TRANSLATOR(ClassName)) \
01047 XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, _XN_DEFAULT_KEY_TRANSLATOR(ClassName), _XN_DEFAULT_VALUE_TRANSLATOR(ClassName))
01048
01053 #define XN_DECLARE_DEFAULT_HASH(KeyType, ValueType, ClassName) \
01054 XN_DECLARE_DEFAULT_HASH_DECL(, KeyType, ValueType, ClassName)
01055
01056 #endif // _XN_HASH_H