OpenNI 1.5.4
|
XnHash.h
Go to the documentation of this file.
00001 /**************************************************************************** 00002 * * 00003 * OpenNI 1.x 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 virtual ~XnHash() 00348 { 00349 if (m_Bins != NULL) 00350 { 00351 for (int i = 0; i < XN_HASH_NUM_BINS; ++i) 00352 { 00353 XN_DELETE(m_Bins[i]); 00354 } 00355 XN_DELETE_ARR(m_Bins); 00356 } 00357 } 00358 00364 XnStatus GetInitStatus() const 00365 { 00366 return m_nInitStatus; 00367 } 00368 00375 XnStatus Set(const XnKey& key, const XnValue& value) 00376 { 00377 XnHashValue HashValue = (*m_HashFunction)(key); 00378 00379 // Check if key already exists 00380 if (m_Bins[HashValue] != NULL) 00381 { 00382 Iterator hiter(this); 00383 if (Find(key, HashValue, hiter) == XN_STATUS_OK) 00384 { 00385 // Replace value 00386 hiter.Value() = value; 00387 return XN_STATUS_OK; 00388 } 00389 } 00390 else 00391 { 00392 // First time trying to access this bin, create it. 00393 m_Bins[HashValue] = XN_NEW(XnList); 00394 if (m_Bins[HashValue] == NULL) 00395 { 00396 return XN_STATUS_ALLOC_FAILED; 00397 } 00398 if (HashValue < m_nMinBin) 00399 m_nMinBin = HashValue; 00400 } 00401 00402 // Get a new node for the key 00403 XnNode* pKeyNode = XnNode::Allocate(); 00404 if (pKeyNode == NULL) 00405 { 00406 return XN_STATUS_ALLOC_FAILED; 00407 } 00408 pKeyNode->Data() = key; 00409 00410 // Get a new node for the value 00411 XnNode* pValueNode = XnNode::Allocate(); 00412 if (pValueNode == NULL) 00413 { 00414 XnNode::Deallocate(pKeyNode); 00415 return XN_STATUS_ALLOC_FAILED; 00416 } 00417 pValueNode->Data() = value; 00418 00419 // Concatenate the value node to the key node 00420 pKeyNode->Next() = pValueNode; 00421 pValueNode->Next() = NULL; 00422 00423 // Add the 2 nodes as the value to the key's list 00424 XnStatus ListStatus = m_Bins[HashValue]->AddLast(XnValue(pKeyNode)); 00425 if (ListStatus != XN_STATUS_OK) 00426 { 00427 // Add failed. return the 2 nodes to the pool 00428 XnNode::Deallocate(pKeyNode); 00429 XnNode::Deallocate(pValueNode); 00430 return ListStatus; 00431 } 00432 00433 return XN_STATUS_OK; 00434 } 00435 00444 XnStatus Get(const XnKey& key, XnValue& value) const 00445 { 00446 // Check if key exists 00447 Iterator hiter(this); 00448 XnStatus FindStatus = Find(key, hiter); 00449 if (FindStatus != XN_STATUS_OK) 00450 { 00451 // Key doesn't exist! 00452 return FindStatus; 00453 } 00454 value = hiter.Value(); 00455 00456 return XN_STATUS_OK; 00457 } 00458 00467 XnStatus Remove(const XnKey& key, XnValue& value) 00468 { 00469 // find the entry to which the key belongs 00470 Iterator hiter(this); 00471 00472 XnStatus FindStatus = Find(key, hiter); 00473 if (FindStatus != XN_STATUS_OK) 00474 { 00475 // no such entry! 00476 return FindStatus; 00477 } 00478 00479 // Remove by iterator 00480 value = hiter.Value(); 00481 return Remove(hiter); 00482 } 00483 00493 XnStatus Remove(ConstIterator iter, XnKey& key, XnValue& value) 00494 { 00495 if (iter == end()) 00496 { 00497 // Can't remove invalid node 00498 return XN_STATUS_ILLEGAL_POSITION; 00499 } 00500 00501 // Get value and key, to return to the caller 00502 value = iter.Value(); 00503 key = iter.Key(); 00504 00505 return Remove(iter); 00506 } 00507 00515 virtual XnStatus Remove(ConstIterator iter) 00516 { 00517 if (iter == end()) 00518 { 00519 // Can't remove invalid node 00520 return XN_STATUS_ILLEGAL_POSITION; 00521 } 00522 00523 XnNode* pNode = iter.GetNode(); 00524 00525 XnNode* pKeyNode = (XnNode*)(pNode->Data()); 00526 XnNode* pValueNode = pKeyNode->Next(); 00527 00528 // Return the nodes to the pool 00529 XnNode::Deallocate(pKeyNode); 00530 XnNode::Deallocate(pValueNode); 00531 00532 pNode->Previous()->Next() = pNode->Next(); 00533 pNode->Next()->Previous() = pNode->Previous(); 00534 00535 XnNode::Deallocate(pNode); 00536 00537 return XN_STATUS_OK; 00538 } 00539 00540 00544 XnStatus Clear() 00545 { 00546 while (begin() != end()) 00547 Remove(begin()); 00548 00549 return XN_STATUS_OK; 00550 } 00551 00555 XnBool IsEmpty() const 00556 { 00557 return (begin() == end()); 00558 } 00559 00563 XnUInt32 Size() const 00564 { 00565 XnUInt32 nSize = 0; 00566 for (Iterator iter = begin(); iter != end(); ++iter, ++nSize) 00567 ; 00568 00569 return nSize; 00570 } 00571 00580 XnStatus Find(const XnKey& key, ConstIterator& hiter) const 00581 { 00582 return ConstFind(key, hiter); 00583 } 00584 00593 XnStatus Find(const XnKey& key, Iterator& hiter) 00594 { 00595 XnStatus nRetVal = XN_STATUS_OK; 00596 00597 ConstIterator& it = hiter; 00598 nRetVal = ConstFind(key, it); 00599 XN_IS_STATUS_OK(nRetVal); 00600 00601 return (XN_STATUS_OK); 00602 } 00603 00607 Iterator begin() 00608 { 00609 return Iterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin()); 00610 } 00611 00615 ConstIterator begin() const 00616 { 00617 return ConstIterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin()); 00618 } 00619 00623 Iterator end() 00624 { 00625 return Iterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end()); 00626 } 00627 00631 ConstIterator end() const 00632 { 00633 return ConstIterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end()); 00634 } 00635 00643 XnStatus SetHashFunction(XnHashFunction hashFunction) 00644 { 00645 if (begin() != end()) 00646 { 00647 return XN_STATUS_IS_NOT_EMPTY; 00648 } 00649 m_HashFunction = hashFunction; 00650 return XN_STATUS_OK; 00651 } 00652 00660 XnStatus SetCompareFunction(XnCompareFunction compareFunction) 00661 { 00662 if (begin() != end()) 00663 { 00664 return XN_STATUS_IS_NOT_EMPTY; 00665 } 00666 m_CompareFunction = compareFunction; 00667 return XN_STATUS_OK; 00668 } 00669 00670 protected: 00671 00672 XnStatus Init() 00673 { 00674 m_Bins = XN_NEW_ARR(XnList*, XN_HASH_NUM_BINS); 00675 XN_VALIDATE_ALLOC_PTR(m_Bins); 00676 00677 for (int i = 0; i < XN_HASH_NUM_BINS; i++) 00678 { 00679 m_Bins[i] = NULL; 00680 } 00681 00682 m_Bins[XN_HASH_LAST_BIN] = XN_NEW(XnList); // We need this for an end() iterator 00683 m_nMinBin = XN_HASH_LAST_BIN; 00684 00685 XN_VALIDATE_ALLOC_PTR(m_Bins[XN_HASH_LAST_BIN]); 00686 m_CompareFunction = &XnDefaultCompareFunction; 00687 m_HashFunction = &XnDefaultHashFunction; 00688 return XN_STATUS_OK; 00689 } 00690 00700 XnStatus Find(const XnKey& key, XnHashValue hashValue, ConstIterator& hiter) const 00701 { 00702 if (m_Bins[hashValue] != NULL) 00703 { 00704 hiter = ConstIterator(this, hashValue, m_Bins[hashValue]->begin()); 00705 for (XnList::ConstIterator iter = m_Bins[hashValue]->begin(); 00706 iter != m_Bins[hashValue]->end(); ++iter, ++hiter) 00707 { 00708 if ((*m_CompareFunction)(key, hiter.Key()) == 0) 00709 return XN_STATUS_OK; 00710 } 00711 } 00712 00713 return XN_STATUS_NO_MATCH; 00714 } 00715 00716 00718 XnList** m_Bins; 00719 00720 XnUInt16 m_nMinBin; 00721 00722 /* Status of initialization - could be an error if memory could not be allocated. */ 00723 XnStatus m_nInitStatus; 00724 00726 XnHashFunction m_HashFunction; 00728 XnCompareFunction m_CompareFunction; 00729 00730 private: 00731 XN_DISABLE_COPY_AND_ASSIGN(XnHash); 00732 00733 XnStatus ConstFind(const XnKey& key, ConstIterator& hiter) const 00734 { 00735 XnHashValue HashValue = (*m_HashFunction)(key); 00736 return Find(key, HashValue, hiter); 00737 } 00738 }; 00739 00744 #define XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, ClassName, KeyTranslator) \ 00745 class decl ClassName \ 00746 { \ 00747 public: \ 00748 inline static XnHashValue Hash(KeyType const& key) \ 00749 { \ 00750 const XnKey _key = KeyTranslator::GetAsValue(key); \ 00751 return XnDefaultHashFunction(_key); \ 00752 } \ 00753 inline static XnInt32 Compare(KeyType const& key1, KeyType const& key2) \ 00754 { \ 00755 const XnKey _key1 = KeyTranslator::GetAsValue(key1); \ 00756 const XnKey _key2 = KeyTranslator::GetAsValue(key2); \ 00757 return XnDefaultCompareFunction(_key1, _key2); \ 00758 } \ 00759 }; 00760 00765 #define XN_DECLARE_DEFAULT_KEY_MANAGER(KeyType, ClassName, KeyTranslator) \ 00766 XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(, KeyType, ClassName, KeyTranslator) 00767 00773 #define XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) \ 00774 class decl ClassName : public XnHash \ 00775 { \ 00776 public: \ 00777 class decl ConstIterator : public XnHash::ConstIterator \ 00778 { \ 00779 public: \ 00780 friend class ClassName; \ 00781 inline ConstIterator(const ConstIterator& other) : XnHash::ConstIterator(other) {} \ 00782 inline ConstIterator& operator++() \ 00783 { \ 00784 ++(*(XnHash::ConstIterator*)this); \ 00785 return (*this); \ 00786 } \ 00787 inline ConstIterator operator++(int) \ 00788 { \ 00789 ConstIterator result = *this; \ 00790 ++*this; \ 00791 return result; \ 00792 } \ 00793 inline ConstIterator& operator--() \ 00794 { \ 00795 --(*(XnHash::ConstIterator*)this); \ 00796 return (*this); \ 00797 } \ 00798 inline ConstIterator operator--(int) \ 00799 { \ 00800 ConstIterator result = *this; \ 00801 --*this; \ 00802 return result; \ 00803 } \ 00804 inline KeyType const& Key() const \ 00805 { \ 00806 return KeyTranslator::GetFromValue(XnHash::ConstIterator::Key()); \ 00807 } \ 00808 inline ValueType const& Value() const \ 00809 { \ 00810 return ValueTranslator::GetFromValue(XnHash::ConstIterator::Value()); \ 00811 } \ 00812 protected: \ 00813 inline ConstIterator(const XnHash::ConstIterator& other) : \ 00814 XnHash::ConstIterator(other) {} \ 00815 }; \ 00816 class decl Iterator : public ConstIterator \ 00817 { \ 00818 public: \ 00819 friend class ClassName; \ 00820 inline Iterator(const Iterator& other) : ConstIterator(other) {} \ 00821 inline Iterator& operator++() \ 00822 { \ 00823 ++(*(ConstIterator*)this); \ 00824 return (*this); \ 00825 } \ 00826 inline Iterator operator++(int) \ 00827 { \ 00828 Iterator result = *this; \ 00829 ++*this; \ 00830 return result; \ 00831 } \ 00832 inline Iterator& operator--() \ 00833 { \ 00834 --(*(ConstIterator*)this); \ 00835 return (*this); \ 00836 } \ 00837 inline Iterator operator--(int) \ 00838 { \ 00839 Iterator result = *this; \ 00840 --*this; \ 00841 return result; \ 00842 } \ 00843 inline KeyType& Key() const \ 00844 { \ 00845 return (KeyType&)ConstIterator::Key(); \ 00846 } \ 00847 inline ValueType& Value() const \ 00848 { \ 00849 return (ValueType&)ConstIterator::Value(); \ 00850 } \ 00851 protected: \ 00852 inline Iterator(const XnHash::Iterator& other) : ConstIterator(other) {} \ 00853 }; \ 00854 public: \ 00855 ClassName() \ 00856 { \ 00857 SetHashFunction(Hash); \ 00858 SetCompareFunction(Compare); \ 00859 } \ 00860 virtual ~ClassName() \ 00861 { \ 00862 while (!IsEmpty()) \ 00863 Remove(begin()); \ 00864 } \ 00865 XnStatus Set(KeyType const& key, ValueType const& value) \ 00866 { \ 00867 Iterator oldIt = begin(); \ 00868 if (Find(key, oldIt) == XN_STATUS_OK) \ 00869 { \ 00870 oldIt.Value() = value; \ 00871 } \ 00872 else \ 00873 { \ 00874 XnKey _key = KeyTranslator::CreateValueCopy(key); \ 00875 XnValue _value = ValueTranslator::CreateValueCopy(value); \ 00876 XnStatus nRetVal = XnHash::Set(_key, _value); \ 00877 if (nRetVal != XN_STATUS_OK) \ 00878 { \ 00879 KeyTranslator::FreeValue(_key); \ 00880 ValueTranslator::FreeValue(_value); \ 00881 return (nRetVal); \ 00882 } \ 00883 } \ 00884 return XN_STATUS_OK; \ 00885 } \ 00886 XnStatus Get(KeyType const& key, ValueType& value) const \ 00887 { \ 00888 XnKey _key = KeyTranslator::GetAsValue(key); \ 00889 XnValue _value; \ 00890 XnStatus nRetVal = XnHash::Get(_key, _value); \ 00891 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00892 value = ValueTranslator::GetFromValue(_value); \ 00893 return XN_STATUS_OK; \ 00894 } \ 00895 XnStatus Get(KeyType const& key, ValueType*& pValue) const \ 00896 { \ 00897 XnKey _key = KeyTranslator::GetAsValue(key); \ 00898 XnValue _value; \ 00899 XnStatus nRetVal = XnHash::Get(_key, _value); \ 00900 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00901 pValue = &ValueTranslator::GetFromValue(_value); \ 00902 return XN_STATUS_OK; \ 00903 } \ 00904 XnStatus Remove(KeyType const& key) \ 00905 { \ 00906 ValueType dummy; \ 00907 return Remove(key, dummy); \ 00908 } \ 00909 XnStatus Remove(KeyType const& key, ValueType& value) \ 00910 { \ 00911 ConstIterator it = end(); \ 00912 XnStatus nRetVal = Find(key, it); \ 00913 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00914 value = it.Value(); \ 00915 return Remove(it); \ 00916 } \ 00917 inline XnStatus Remove(ConstIterator iter) \ 00918 { \ 00919 XnKey key = KeyTranslator::GetAsValue(iter.Key()); \ 00920 XnValue value = ValueTranslator::GetAsValue(iter.Value()); \ 00921 XnStatus nRetVal = XnHash::Remove(iter); \ 00922 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00923 KeyTranslator::FreeValue(key); \ 00924 ValueTranslator::FreeValue(value); \ 00925 return XN_STATUS_OK; \ 00926 } \ 00927 XnStatus Find(KeyType const& key, ConstIterator& hiter) const \ 00928 { \ 00929 XnKey _key = KeyTranslator::GetAsValue(key); \ 00930 XnHash::ConstIterator it = XnHash::end(); \ 00931 XnStatus nRetVal = XnHash::Find(_key, it); \ 00932 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00933 hiter = it; \ 00934 return XN_STATUS_OK; \ 00935 } \ 00936 XnStatus Find(KeyType const& key, Iterator& hiter) \ 00937 { \ 00938 XnKey _key = KeyTranslator::GetAsValue(key); \ 00939 XnHash::Iterator it = XnHash::end(); \ 00940 XnStatus nRetVal = XnHash::Find(_key, it); \ 00941 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00942 hiter = it; \ 00943 return XN_STATUS_OK; \ 00944 } \ 00945 inline Iterator begin() { return XnHash::begin(); } \ 00946 inline ConstIterator begin() const { return XnHash::begin(); } \ 00947 inline Iterator end() { return XnHash::end(); } \ 00948 inline ConstIterator end() const { return XnHash::end(); } \ 00949 protected: \ 00950 virtual XnStatus Remove(XnHash::ConstIterator iter) \ 00951 { \ 00952 return Remove(ConstIterator(iter)); \ 00953 } \ 00954 inline static XnHashValue Hash(const XnKey& key) \ 00955 { \ 00956 KeyType const& _key = KeyTranslator::GetFromValue(key); \ 00957 return KeyManager::Hash(_key); \ 00958 } \ 00959 inline static XnInt32 Compare(const XnKey& key1, const XnKey& key2) \ 00960 { \ 00961 KeyType const _key1 = KeyTranslator::GetFromValue(key1); \ 00962 KeyType const _key2 = KeyTranslator::GetFromValue(key2); \ 00963 return KeyManager::Compare(_key1, _key2); \ 00964 } \ 00965 private: \ 00966 XN_DISABLE_COPY_AND_ASSIGN(ClassName); \ 00967 }; 00968 00973 #define XN_DECLARE_HASH(KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) \ 00974 XN_DECLARE_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) 00975 00976 #define _XN_DEFAULT_KEY_MANAGER_NAME(ClassName) _##ClassName##Manager 00977 00983 #define XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) \ 00984 XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName), KeyTranslator) \ 00985 XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName)) 00986 00991 #define XN_DECLARE_DEFAULT_MANAGER_HASH(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) \ 00992 XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) 00993 00994 #define _XN_DEFAULT_KEY_TRANSLATOR(ClassName) _##ClassName##KeyTranslator 00995 #define _XN_DEFAULT_VALUE_TRANSLATOR(ClassName) _##ClassName##ValueTranslator 00996 01002 #define XN_DECLARE_DEFAULT_HASH_DECL(decl, KeyType, ValueType, ClassName) \ 01003 XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, KeyType, _XN_DEFAULT_KEY_TRANSLATOR(ClassName)) \ 01004 XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, ValueType, _XN_DEFAULT_VALUE_TRANSLATOR(ClassName)) \ 01005 XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, _XN_DEFAULT_KEY_TRANSLATOR(ClassName), _XN_DEFAULT_VALUE_TRANSLATOR(ClassName)) 01006 01011 #define XN_DECLARE_DEFAULT_HASH(KeyType, ValueType, ClassName) \ 01012 XN_DECLARE_DEFAULT_HASH_DECL(, KeyType, ValueType, ClassName) 01013 01014 #endif // _XN_HASH_H
Generated on Wed May 16 2012 10:16:05 for OpenNI 1.5.4 by 1.7.5.1