OpenNI 1.0.0
|
00001 /***************************************************************************** 00002 * * 00003 * OpenNI 1.0 Alpha * 00004 * Copyright (C) 2010 PrimeSense Ltd. * 00005 * * 00006 * This file is part of OpenNI. * 00007 * * 00008 * OpenNI is free software: you can redistribute it and/or modify * 00009 * it under the terms of the GNU Lesser General Public License as published * 00010 * by the Free Software Foundation, either version 3 of the License, or * 00011 * (at your option) any later version. * 00012 * * 00013 * OpenNI is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00016 * GNU Lesser General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU Lesser General Public License * 00019 * along with OpenNI. If not, see <http://www.gnu.org/licenses/>. * 00020 * * 00021 *****************************************************************************/ 00022 00023 00024 00025 00026 #ifndef _XN_HASH_H 00027 #define _XN_HASH_H 00028 00029 //--------------------------------------------------------------------------- 00030 // Includes 00031 //--------------------------------------------------------------------------- 00032 #include "XnList.h" 00033 00034 //--------------------------------------------------------------------------- 00035 // Defines 00036 //--------------------------------------------------------------------------- 00037 #define XN_HASH_LAST_BIN 256 00038 #define XN_HASH_NUM_BINS (XN_HASH_LAST_BIN + 1) 00039 //--------------------------------------------------------------------------- 00040 // Types 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 // Find the first valid 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 // Check if key already exists 00411 if (m_Bins[HashValue] != NULL) 00412 { 00413 Iterator hiter(this); 00414 if (Find(key, HashValue, hiter) == XN_STATUS_OK) 00415 { 00416 // Replace value 00417 hiter.Value() = value; 00418 return XN_STATUS_OK; 00419 } 00420 } 00421 else 00422 { 00423 // First time trying to access this bin, create it. 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 // Get a new node for the key 00434 XnNode* pKeyNode = XnNode::Allocate(); 00435 if (pKeyNode == NULL) 00436 { 00437 return XN_STATUS_ALLOC_FAILED; 00438 } 00439 pKeyNode->Data() = key; 00440 00441 // Get a new node for the value 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 // Concatenate the value node to the key node 00451 pKeyNode->Next() = pValueNode; 00452 pValueNode->Next() = NULL; 00453 00454 // Add the 2 nodes as the value to the key's list 00455 XnStatus ListStatus = m_Bins[HashValue]->AddLast(XnValue(pKeyNode)); 00456 if (ListStatus != XN_STATUS_OK) 00457 { 00458 // Add failed. return the 2 nodes to the pool 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 // Check if key exists 00478 Iterator hiter(this); 00479 XnStatus FindStatus = Find(key, hiter); 00480 if (FindStatus != XN_STATUS_OK) 00481 { 00482 // Key doesn't exist! 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 // find the entry to which the key belongs 00501 Iterator hiter(this); 00502 00503 XnStatus FindStatus = Find(key, hiter); 00504 if (FindStatus != XN_STATUS_OK) 00505 { 00506 // no such entry! 00507 return FindStatus; 00508 } 00509 00510 // Remove by iterator 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 // Can't remove invalid node 00529 return XN_STATUS_ILLEGAL_POSITION; 00530 } 00531 00532 // Get value and key, to return to the caller 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 // Can't remove invalid node 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 // Return the nodes to the pool 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); // We need this for an end() iterator 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 /* Status of initialization - could be an error if memory could not be allocated. */ 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