OpenNI 1.5.7
XnHash.h
Go to the documentation of this file.
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