OpenNI 1.3.2
|
00001 /**************************************************************************** 00002 * * 00003 * OpenNI 1.1 Alpha * 00004 * Copyright (C) 2011 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 #ifndef _XN_HASH_H 00023 #define _XN_HASH_H 00024 00025 //--------------------------------------------------------------------------- 00026 // Includes 00027 //--------------------------------------------------------------------------- 00028 #include "XnList.h" 00029 00030 //--------------------------------------------------------------------------- 00031 // Defines 00032 //--------------------------------------------------------------------------- 00033 #define XN_HASH_LAST_BIN 256 00034 #define XN_HASH_NUM_BINS (XN_HASH_LAST_BIN + 1) 00035 //--------------------------------------------------------------------------- 00036 // Types 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 // Find the first valid 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 // Check if key already exists 00407 if (m_Bins[HashValue] != NULL) 00408 { 00409 Iterator hiter(this); 00410 if (Find(key, HashValue, hiter) == XN_STATUS_OK) 00411 { 00412 // Replace value 00413 hiter.Value() = value; 00414 return XN_STATUS_OK; 00415 } 00416 } 00417 else 00418 { 00419 // First time trying to access this bin, create it. 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 // Get a new node for the key 00430 XnNode* pKeyNode = XnNode::Allocate(); 00431 if (pKeyNode == NULL) 00432 { 00433 return XN_STATUS_ALLOC_FAILED; 00434 } 00435 pKeyNode->Data() = key; 00436 00437 // Get a new node for the value 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 // Concatenate the value node to the key node 00447 pKeyNode->Next() = pValueNode; 00448 pValueNode->Next() = NULL; 00449 00450 // Add the 2 nodes as the value to the key's list 00451 XnStatus ListStatus = m_Bins[HashValue]->AddLast(XnValue(pKeyNode)); 00452 if (ListStatus != XN_STATUS_OK) 00453 { 00454 // Add failed. return the 2 nodes to the pool 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 // Check if key exists 00474 Iterator hiter(this); 00475 XnStatus FindStatus = Find(key, hiter); 00476 if (FindStatus != XN_STATUS_OK) 00477 { 00478 // Key doesn't exist! 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 // find the entry to which the key belongs 00497 Iterator hiter(this); 00498 00499 XnStatus FindStatus = Find(key, hiter); 00500 if (FindStatus != XN_STATUS_OK) 00501 { 00502 // no such entry! 00503 return FindStatus; 00504 } 00505 00506 // Remove by iterator 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 // Can't remove invalid node 00525 return XN_STATUS_ILLEGAL_POSITION; 00526 } 00527 00528 // Get value and key, to return to the caller 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 // Can't remove invalid node 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 // Return the nodes to the pool 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); // We need this for an end() iterator 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 /* Status of initialization - could be an error if memory could not be allocated. */ 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