![]() |
OpenNI 1.5.7
|
00001 /***************************************************************************** 00002 * * 00003 * OpenNI 1.x Alpha * 00004 * Copyright (C) 2012 PrimeSense Ltd. * 00005 * * 00006 * This file is part of OpenNI. * 00007 * * 00008 * Licensed under the Apache License, Version 2.0 (the "License"); * 00009 * you may not use this file except in compliance with the License. * 00010 * You may obtain a copy of the License at * 00011 * * 00012 * http://www.apache.org/licenses/LICENSE-2.0 * 00013 * * 00014 * Unless required by applicable law or agreed to in writing, software * 00015 * distributed under the License is distributed on an "AS IS" BASIS, * 00016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00017 * See the License for the specific language governing permissions and * 00018 * limitations under the License. * 00019 * * 00020 *****************************************************************************/ 00021 #ifndef _XN_HASH_H 00022 #define _XN_HASH_H 00023 00024 //--------------------------------------------------------------------------- 00025 // Includes 00026 //--------------------------------------------------------------------------- 00027 #include "XnList.h" 00028 00029 //--------------------------------------------------------------------------- 00030 // Defines 00031 //--------------------------------------------------------------------------- 00032 #define XN_HASH_LAST_BIN 256 00033 #define XN_HASH_NUM_BINS (XN_HASH_LAST_BIN + 1) 00034 //--------------------------------------------------------------------------- 00035 // Types 00036 //--------------------------------------------------------------------------- 00040 typedef XnValue XnKey; 00041 00045 typedef XnUInt8 XnHashValue; 00046 00050 static XnHashValue XnDefaultHashFunction(const XnKey& key) 00051 { 00052 return (XnSizeT(key) & 0xff); 00053 } 00054 00058 static XnInt32 XnDefaultCompareFunction(const XnKey& key1, const XnKey& key2) 00059 { 00060 return XnInt32(XnSizeT(key1)-XnSizeT(key2)); 00061 } 00062 00066 class XnHash 00067 { 00068 public: 00072 class ConstIterator 00073 { 00074 public: 00075 friend class XnHash; 00076 00082 ConstIterator(const ConstIterator& other) : 00083 m_pHash(other.m_pHash), m_nCurrentBin(other.m_nCurrentBin), m_Iterator(other.m_Iterator) {} 00084 00088 ConstIterator& operator++() 00089 { 00090 ++m_Iterator; 00091 00092 while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() && 00093 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end()) 00094 { 00095 do 00096 { 00097 m_nCurrentBin++; 00098 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL); 00099 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin(); 00100 } 00101 return *this; 00102 } 00103 00107 ConstIterator operator++(int) 00108 { 00109 XnHash::ConstIterator other(*this); 00110 ++*this; 00111 return other; 00112 } 00113 00117 ConstIterator& operator--() 00118 { 00119 --m_Iterator; 00120 00121 while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() && 00122 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end()) 00123 { 00124 do 00125 { 00126 if (m_nCurrentBin == 0) 00127 { 00128 m_nCurrentBin = XN_HASH_LAST_BIN; 00129 m_Iterator = m_pHash->m_Bins[XN_HASH_LAST_BIN]->end(); 00130 return *this; 00131 } 00132 m_nCurrentBin--; 00133 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL); 00134 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->rbegin(); 00135 } 00136 return *this; 00137 } 00138 00142 ConstIterator operator--(int) 00143 { 00144 ConstIterator other(*this); 00145 --*this; 00146 return other; 00147 } 00148 00154 XnBool operator==(const ConstIterator& other) const 00155 { 00156 return m_Iterator == other.m_Iterator; 00157 } 00158 00164 XnBool operator!=(const ConstIterator& other) const 00165 { 00166 return m_Iterator != other.m_Iterator; 00167 } 00168 00172 const XnKey& Key() const 00173 { 00174 return ((XnNode*)(*m_Iterator))->Data(); 00175 } 00176 00180 const XnValue& Value() const 00181 { 00182 return ((XnNode*)(*m_Iterator))->Next()->Data(); 00183 } 00184 00188 XnNode* GetNode() 00189 { 00190 return m_Iterator.GetNode(); 00191 } 00192 00196 const XnNode* GetNode() const 00197 { 00198 return m_Iterator.GetNode(); 00199 } 00200 00201 protected: 00209 ConstIterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) : 00210 m_pHash(pHash), m_nCurrentBin(nBin), m_Iterator(listIterator) 00211 { 00212 // Find the first valid 00213 while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() && 00214 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end()) 00215 { 00216 do 00217 { 00218 m_nCurrentBin++; 00219 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL); 00220 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin(); 00221 } 00222 } 00223 00229 ConstIterator(const XnHash* pHash) : 00230 m_pHash(pHash), m_nCurrentBin(0), m_Iterator(m_pHash->m_Bins[XN_HASH_LAST_BIN]->end()) {} 00231 00233 const XnHash* m_pHash; 00235 XnUInt16 m_nCurrentBin; 00237 XnList::Iterator m_Iterator; 00238 }; 00239 00243 class Iterator : public ConstIterator 00244 { 00245 public: 00246 friend class XnHash; 00247 00253 inline Iterator(const Iterator& other) : ConstIterator(other) {} 00254 00258 inline Iterator& operator++() 00259 { 00260 ++(*(ConstIterator*)this); 00261 return (*this); 00262 } 00266 inline Iterator operator++(int) 00267 { 00268 Iterator result = *this; 00269 ++*this; 00270 return (result); 00271 } 00272 00276 inline Iterator& operator--() 00277 { 00278 --(*(ConstIterator*)this); 00279 return (*this); 00280 } 00284 inline Iterator operator--(int) 00285 { 00286 Iterator result = *this; 00287 --*this; 00288 return (result); 00289 } 00290 00294 XnKey& Key() const { return (XnKey&)ConstIterator::Key(); } 00295 00299 XnValue& Value() const { return (XnValue&)ConstIterator::Value(); } 00300 00301 protected: 00309 Iterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) : 00310 ConstIterator(pHash, nBin, listIterator) 00311 {} 00312 00318 Iterator(const XnHash* pHash) : ConstIterator(pHash) {} 00319 00320 Iterator(const ConstIterator& other) : ConstIterator(other) {} 00321 }; 00322 00323 friend class ConstIterator; 00324 00325 public: 00329 typedef XnHashValue (*XnHashFunction)(const XnKey& key); 00333 typedef XnInt32 (*XnCompareFunction)(const XnKey& key1, const XnKey& key2); 00334 00338 XnHash() 00339 { 00340 m_nInitStatus = Init(); 00341 } 00342 00346 virtual ~XnHash() 00347 { 00348 if (m_Bins != NULL) 00349 { 00350 for (int i = 0; i < XN_HASH_NUM_BINS; ++i) 00351 { 00352 XN_DELETE(m_Bins[i]); 00353 } 00354 XN_DELETE_ARR(m_Bins); 00355 } 00356 } 00357 00363 XnStatus GetInitStatus() const 00364 { 00365 return m_nInitStatus; 00366 } 00367 00374 XnStatus Set(const XnKey& key, const XnValue& value) 00375 { 00376 XnHashValue HashValue = (*m_HashFunction)(key); 00377 00378 // Check if key already exists 00379 if (m_Bins[HashValue] != NULL) 00380 { 00381 Iterator hiter(this); 00382 if (Find(key, HashValue, hiter) == XN_STATUS_OK) 00383 { 00384 // Replace value 00385 hiter.Value() = value; 00386 return XN_STATUS_OK; 00387 } 00388 } 00389 else 00390 { 00391 // First time trying to access this bin, create it. 00392 m_Bins[HashValue] = XN_NEW(XnList); 00393 if (m_Bins[HashValue] == NULL) 00394 { 00395 return XN_STATUS_ALLOC_FAILED; 00396 } 00397 if (HashValue < m_nMinBin) 00398 m_nMinBin = HashValue; 00399 } 00400 00401 // Get a new node for the key 00402 XnNode* pKeyNode = XnNode::Allocate(); 00403 if (pKeyNode == NULL) 00404 { 00405 return XN_STATUS_ALLOC_FAILED; 00406 } 00407 pKeyNode->Data() = key; 00408 00409 // Get a new node for the value 00410 XnNode* pValueNode = XnNode::Allocate(); 00411 if (pValueNode == NULL) 00412 { 00413 XnNode::Deallocate(pKeyNode); 00414 return XN_STATUS_ALLOC_FAILED; 00415 } 00416 pValueNode->Data() = value; 00417 00418 // Concatenate the value node to the key node 00419 pKeyNode->Next() = pValueNode; 00420 pValueNode->Next() = NULL; 00421 00422 // Add the 2 nodes as the value to the key's list 00423 XnStatus ListStatus = m_Bins[HashValue]->AddLast(XnValue(pKeyNode)); 00424 if (ListStatus != XN_STATUS_OK) 00425 { 00426 // Add failed. return the 2 nodes to the pool 00427 XnNode::Deallocate(pKeyNode); 00428 XnNode::Deallocate(pValueNode); 00429 return ListStatus; 00430 } 00431 00432 return XN_STATUS_OK; 00433 } 00434 00443 XnStatus Get(const XnKey& key, XnValue& value) const 00444 { 00445 // Check if key exists 00446 Iterator hiter(this); 00447 XnStatus FindStatus = Find(key, hiter); 00448 if (FindStatus != XN_STATUS_OK) 00449 { 00450 // Key doesn't exist! 00451 return FindStatus; 00452 } 00453 value = hiter.Value(); 00454 00455 return XN_STATUS_OK; 00456 } 00457 00466 XnStatus Remove(const XnKey& key, XnValue& value) 00467 { 00468 // find the entry to which the key belongs 00469 Iterator hiter(this); 00470 00471 XnStatus FindStatus = Find(key, hiter); 00472 if (FindStatus != XN_STATUS_OK) 00473 { 00474 // no such entry! 00475 return FindStatus; 00476 } 00477 00478 // Remove by iterator 00479 value = hiter.Value(); 00480 return Remove(hiter); 00481 } 00482 00492 XnStatus Remove(ConstIterator iter, XnKey& key, XnValue& value) 00493 { 00494 if (iter == end()) 00495 { 00496 // Can't remove invalid node 00497 return XN_STATUS_ILLEGAL_POSITION; 00498 } 00499 00500 // Get value and key, to return to the caller 00501 value = iter.Value(); 00502 key = iter.Key(); 00503 00504 return Remove(iter); 00505 } 00506 00514 virtual XnStatus Remove(ConstIterator iter) 00515 { 00516 if (iter == end()) 00517 { 00518 // Can't remove invalid node 00519 return XN_STATUS_ILLEGAL_POSITION; 00520 } 00521 00522 XnNode* pNode = iter.GetNode(); 00523 00524 XnNode* pKeyNode = (XnNode*)(pNode->Data()); 00525 XnNode* pValueNode = pKeyNode->Next(); 00526 00527 // Return the nodes to the pool 00528 XnNode::Deallocate(pKeyNode); 00529 XnNode::Deallocate(pValueNode); 00530 00531 pNode->Previous()->Next() = pNode->Next(); 00532 pNode->Next()->Previous() = pNode->Previous(); 00533 00534 XnNode::Deallocate(pNode); 00535 00536 return XN_STATUS_OK; 00537 } 00538 00539 00543 XnStatus Clear() 00544 { 00545 while (begin() != end()) 00546 Remove(begin()); 00547 00548 return XN_STATUS_OK; 00549 } 00550 00554 XnBool IsEmpty() const 00555 { 00556 return (begin() == end()); 00557 } 00558 00562 XnUInt32 Size() const 00563 { 00564 XnUInt32 nSize = 0; 00565 for (Iterator iter = begin(); iter != end(); ++iter, ++nSize) 00566 ; 00567 00568 return nSize; 00569 } 00570 00579 XnStatus Find(const XnKey& key, ConstIterator& hiter) const 00580 { 00581 return ConstFind(key, hiter); 00582 } 00583 00592 XnStatus Find(const XnKey& key, Iterator& hiter) 00593 { 00594 XnStatus nRetVal = XN_STATUS_OK; 00595 00596 ConstIterator& it = hiter; 00597 nRetVal = ConstFind(key, it); 00598 XN_IS_STATUS_OK(nRetVal); 00599 00600 return (XN_STATUS_OK); 00601 } 00602 00606 Iterator begin() 00607 { 00608 return Iterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin()); 00609 } 00610 00614 ConstIterator begin() const 00615 { 00616 return ConstIterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin()); 00617 } 00618 00622 Iterator end() 00623 { 00624 return Iterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end()); 00625 } 00626 00630 ConstIterator end() const 00631 { 00632 return ConstIterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end()); 00633 } 00634 00642 XnStatus SetHashFunction(XnHashFunction hashFunction) 00643 { 00644 if (begin() != end()) 00645 { 00646 return XN_STATUS_IS_NOT_EMPTY; 00647 } 00648 m_HashFunction = hashFunction; 00649 return XN_STATUS_OK; 00650 } 00651 00659 XnStatus SetCompareFunction(XnCompareFunction compareFunction) 00660 { 00661 if (begin() != end()) 00662 { 00663 return XN_STATUS_IS_NOT_EMPTY; 00664 } 00665 m_CompareFunction = compareFunction; 00666 return XN_STATUS_OK; 00667 } 00668 00669 protected: 00670 00671 XnStatus Init() 00672 { 00673 m_Bins = XN_NEW_ARR(XnList*, XN_HASH_NUM_BINS); 00674 XN_VALIDATE_ALLOC_PTR(m_Bins); 00675 00676 for (int i = 0; i < XN_HASH_NUM_BINS; i++) 00677 { 00678 m_Bins[i] = NULL; 00679 } 00680 00681 m_Bins[XN_HASH_LAST_BIN] = XN_NEW(XnList); // We need this for an end() iterator 00682 m_nMinBin = XN_HASH_LAST_BIN; 00683 00684 XN_VALIDATE_ALLOC_PTR(m_Bins[XN_HASH_LAST_BIN]); 00685 m_CompareFunction = &XnDefaultCompareFunction; 00686 m_HashFunction = &XnDefaultHashFunction; 00687 return XN_STATUS_OK; 00688 } 00689 00699 XnStatus Find(const XnKey& key, XnHashValue hashValue, ConstIterator& hiter) const 00700 { 00701 if (m_Bins[hashValue] != NULL) 00702 { 00703 hiter = ConstIterator(this, hashValue, m_Bins[hashValue]->begin()); 00704 for (XnList::ConstIterator iter = m_Bins[hashValue]->begin(); 00705 iter != m_Bins[hashValue]->end(); ++iter, ++hiter) 00706 { 00707 if ((*m_CompareFunction)(key, hiter.Key()) == 0) 00708 return XN_STATUS_OK; 00709 } 00710 } 00711 00712 return XN_STATUS_NO_MATCH; 00713 } 00714 00715 00717 XnList** m_Bins; 00718 00719 XnUInt16 m_nMinBin; 00720 00721 /* Status of initialization - could be an error if memory could not be allocated. */ 00722 XnStatus m_nInitStatus; 00723 00725 XnHashFunction m_HashFunction; 00727 XnCompareFunction m_CompareFunction; 00728 00729 private: 00730 XN_DISABLE_COPY_AND_ASSIGN(XnHash); 00731 00732 XnStatus ConstFind(const XnKey& key, ConstIterator& hiter) const 00733 { 00734 XnHashValue HashValue = (*m_HashFunction)(key); 00735 return Find(key, HashValue, hiter); 00736 } 00737 }; 00738 00743 #define XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, ClassName, KeyTranslator) \ 00744 class decl ClassName \ 00745 { \ 00746 public: \ 00747 inline static XnHashValue Hash(KeyType const& key) \ 00748 { \ 00749 const XnKey _key = KeyTranslator::GetAsValue(key); \ 00750 return XnDefaultHashFunction(_key); \ 00751 } \ 00752 inline static XnInt32 Compare(KeyType const& key1, KeyType const& key2) \ 00753 { \ 00754 const XnKey _key1 = KeyTranslator::GetAsValue(key1); \ 00755 const XnKey _key2 = KeyTranslator::GetAsValue(key2); \ 00756 return XnDefaultCompareFunction(_key1, _key2); \ 00757 } \ 00758 }; 00759 00764 #define XN_DECLARE_DEFAULT_KEY_MANAGER(KeyType, ClassName, KeyTranslator) \ 00765 XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(, KeyType, ClassName, KeyTranslator) 00766 00772 #define XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) \ 00773 class decl ClassName : public XnHash \ 00774 { \ 00775 public: \ 00776 class decl ConstIterator : public XnHash::ConstIterator \ 00777 { \ 00778 public: \ 00779 friend class ClassName; \ 00780 inline ConstIterator(const ConstIterator& other) : XnHash::ConstIterator(other) {} \ 00781 inline ConstIterator& operator++() \ 00782 { \ 00783 ++(*(XnHash::ConstIterator*)this); \ 00784 return (*this); \ 00785 } \ 00786 inline ConstIterator operator++(int) \ 00787 { \ 00788 ConstIterator result = *this; \ 00789 ++*this; \ 00790 return result; \ 00791 } \ 00792 inline ConstIterator& operator--() \ 00793 { \ 00794 --(*(XnHash::ConstIterator*)this); \ 00795 return (*this); \ 00796 } \ 00797 inline ConstIterator operator--(int) \ 00798 { \ 00799 ConstIterator result = *this; \ 00800 --*this; \ 00801 return result; \ 00802 } \ 00803 inline KeyType const& Key() const \ 00804 { \ 00805 return KeyTranslator::GetFromValue(XnHash::ConstIterator::Key()); \ 00806 } \ 00807 inline ValueType const& Value() const \ 00808 { \ 00809 return ValueTranslator::GetFromValue(XnHash::ConstIterator::Value()); \ 00810 } \ 00811 protected: \ 00812 inline ConstIterator(const XnHash::ConstIterator& other) : \ 00813 XnHash::ConstIterator(other) {} \ 00814 }; \ 00815 class decl Iterator : public ConstIterator \ 00816 { \ 00817 public: \ 00818 friend class ClassName; \ 00819 inline Iterator(const Iterator& other) : ConstIterator(other) {} \ 00820 inline Iterator& operator++() \ 00821 { \ 00822 ++(*(ConstIterator*)this); \ 00823 return (*this); \ 00824 } \ 00825 inline Iterator operator++(int) \ 00826 { \ 00827 Iterator result = *this; \ 00828 ++*this; \ 00829 return result; \ 00830 } \ 00831 inline Iterator& operator--() \ 00832 { \ 00833 --(*(ConstIterator*)this); \ 00834 return (*this); \ 00835 } \ 00836 inline Iterator operator--(int) \ 00837 { \ 00838 Iterator result = *this; \ 00839 --*this; \ 00840 return result; \ 00841 } \ 00842 inline KeyType& Key() const \ 00843 { \ 00844 return (KeyType&)ConstIterator::Key(); \ 00845 } \ 00846 inline ValueType& Value() const \ 00847 { \ 00848 return (ValueType&)ConstIterator::Value(); \ 00849 } \ 00850 protected: \ 00851 inline Iterator(const XnHash::Iterator& other) : ConstIterator(other) {} \ 00852 }; \ 00853 public: \ 00854 ClassName() \ 00855 { \ 00856 SetHashFunction(Hash); \ 00857 SetCompareFunction(Compare); \ 00858 } \ 00859 virtual ~ClassName() \ 00860 { \ 00861 while (!IsEmpty()) \ 00862 Remove(begin()); \ 00863 } \ 00864 XnStatus Set(KeyType const& key, ValueType const& value) \ 00865 { \ 00866 Iterator oldIt = begin(); \ 00867 if (Find(key, oldIt) == XN_STATUS_OK) \ 00868 { \ 00869 oldIt.Value() = value; \ 00870 } \ 00871 else \ 00872 { \ 00873 XnKey _key = KeyTranslator::CreateValueCopy(key); \ 00874 XnValue _value = ValueTranslator::CreateValueCopy(value); \ 00875 XnStatus nRetVal = XnHash::Set(_key, _value); \ 00876 if (nRetVal != XN_STATUS_OK) \ 00877 { \ 00878 KeyTranslator::FreeValue(_key); \ 00879 ValueTranslator::FreeValue(_value); \ 00880 return (nRetVal); \ 00881 } \ 00882 } \ 00883 return XN_STATUS_OK; \ 00884 } \ 00885 XnStatus Get(KeyType const& key, ValueType& value) const \ 00886 { \ 00887 XnKey _key = KeyTranslator::GetAsValue(key); \ 00888 XnValue _value; \ 00889 XnStatus nRetVal = XnHash::Get(_key, _value); \ 00890 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00891 value = ValueTranslator::GetFromValue(_value); \ 00892 return XN_STATUS_OK; \ 00893 } \ 00894 XnStatus Get(KeyType const& key, ValueType*& pValue) const \ 00895 { \ 00896 XnKey _key = KeyTranslator::GetAsValue(key); \ 00897 XnValue _value; \ 00898 XnStatus nRetVal = XnHash::Get(_key, _value); \ 00899 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00900 pValue = &ValueTranslator::GetFromValue(_value); \ 00901 return XN_STATUS_OK; \ 00902 } \ 00903 XnStatus Remove(KeyType const& key) \ 00904 { \ 00905 ValueType dummy; \ 00906 return Remove(key, dummy); \ 00907 } \ 00908 XnStatus Remove(KeyType const& key, ValueType& value) \ 00909 { \ 00910 ConstIterator it = end(); \ 00911 XnStatus nRetVal = Find(key, it); \ 00912 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00913 value = it.Value(); \ 00914 return Remove(it); \ 00915 } \ 00916 inline XnStatus Remove(ConstIterator iter) \ 00917 { \ 00918 XnKey key = KeyTranslator::GetAsValue(iter.Key()); \ 00919 XnValue value = ValueTranslator::GetAsValue(iter.Value()); \ 00920 XnStatus nRetVal = XnHash::Remove(iter); \ 00921 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00922 KeyTranslator::FreeValue(key); \ 00923 ValueTranslator::FreeValue(value); \ 00924 return XN_STATUS_OK; \ 00925 } \ 00926 XnStatus Find(KeyType const& key, ConstIterator& hiter) const \ 00927 { \ 00928 XnKey _key = KeyTranslator::GetAsValue(key); \ 00929 XnHash::ConstIterator it = XnHash::end(); \ 00930 XnStatus nRetVal = XnHash::Find(_key, it); \ 00931 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00932 hiter = it; \ 00933 return XN_STATUS_OK; \ 00934 } \ 00935 XnStatus Find(KeyType const& key, Iterator& hiter) \ 00936 { \ 00937 XnKey _key = KeyTranslator::GetAsValue(key); \ 00938 XnHash::Iterator it = XnHash::end(); \ 00939 XnStatus nRetVal = XnHash::Find(_key, it); \ 00940 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00941 hiter = it; \ 00942 return XN_STATUS_OK; \ 00943 } \ 00944 inline Iterator begin() { return XnHash::begin(); } \ 00945 inline ConstIterator begin() const { return XnHash::begin(); } \ 00946 inline Iterator end() { return XnHash::end(); } \ 00947 inline ConstIterator end() const { return XnHash::end(); } \ 00948 protected: \ 00949 virtual XnStatus Remove(XnHash::ConstIterator iter) \ 00950 { \ 00951 return Remove(ConstIterator(iter)); \ 00952 } \ 00953 inline static XnHashValue Hash(const XnKey& key) \ 00954 { \ 00955 KeyType const& _key = KeyTranslator::GetFromValue(key); \ 00956 return KeyManager::Hash(_key); \ 00957 } \ 00958 inline static XnInt32 Compare(const XnKey& key1, const XnKey& key2) \ 00959 { \ 00960 KeyType const _key1 = KeyTranslator::GetFromValue(key1); \ 00961 KeyType const _key2 = KeyTranslator::GetFromValue(key2); \ 00962 return KeyManager::Compare(_key1, _key2); \ 00963 } \ 00964 private: \ 00965 XN_DISABLE_COPY_AND_ASSIGN(ClassName); \ 00966 }; 00967 00972 #define XN_DECLARE_HASH(KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) \ 00973 XN_DECLARE_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) 00974 00975 #define _XN_DEFAULT_KEY_MANAGER_NAME(ClassName) _##ClassName##Manager 00976 00982 #define XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) \ 00983 XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName), KeyTranslator) \ 00984 XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName)) 00985 00990 #define XN_DECLARE_DEFAULT_MANAGER_HASH(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) \ 00991 XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) 00992 00993 #define _XN_DEFAULT_KEY_TRANSLATOR(ClassName) _##ClassName##KeyTranslator 00994 #define _XN_DEFAULT_VALUE_TRANSLATOR(ClassName) _##ClassName##ValueTranslator 00995 01001 #define XN_DECLARE_DEFAULT_HASH_DECL(decl, KeyType, ValueType, ClassName) \ 01002 XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, KeyType, _XN_DEFAULT_KEY_TRANSLATOR(ClassName)) \ 01003 XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, ValueType, _XN_DEFAULT_VALUE_TRANSLATOR(ClassName)) \ 01004 XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, _XN_DEFAULT_KEY_TRANSLATOR(ClassName), _XN_DEFAULT_VALUE_TRANSLATOR(ClassName)) 01005 01010 #define XN_DECLARE_DEFAULT_HASH(KeyType, ValueType, ClassName) \ 01011 XN_DECLARE_DEFAULT_HASH_DECL(, KeyType, ValueType, ClassName) 01012 01013 #endif // _XN_HASH_H