• Main Page
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

XnHash.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002 *                                                                            *
00003 *  OpenNI 1.0 Alpha                                                          *
00004 *  Copyright (C) 2010 PrimeSense Ltd.                                        *
00005 *                                                                            *
00006 *  This file is part of OpenNI.                                              *
00007 *                                                                            *
00008 *  OpenNI is free software: you can redistribute it and/or modify            *
00009 *  it under the terms of the GNU Lesser General Public License as published  *
00010 *  by the Free Software Foundation, either version 3 of the License, or      *
00011 *  (at your option) any later version.                                       *
00012 *                                                                            *
00013 *  OpenNI is distributed in the hope that it will be useful,                 *
00014 *  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00015 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
00016 *  GNU Lesser General Public License for more details.                       *
00017 *                                                                            *
00018 *  You should have received a copy of the GNU Lesser General Public License  *
00019 *  along with OpenNI. If not, see <http://www.gnu.org/licenses/>.            *
00020 *                                                                            *
00021 *****************************************************************************/
00022 
00023 
00024 
00025 
00026 #ifndef _XN_HASH_H
00027 #define _XN_HASH_H
00028 
00029 //---------------------------------------------------------------------------
00030 // Includes
00031 //---------------------------------------------------------------------------
00032 #include "XnList.h"
00033 
00034 //---------------------------------------------------------------------------
00035 // Defines
00036 //---------------------------------------------------------------------------
00037 #define XN_HASH_LAST_BIN 256
00038 #define XN_HASH_NUM_BINS (XN_HASH_LAST_BIN + 1)
00039 //---------------------------------------------------------------------------
00040 // Types
00041 //---------------------------------------------------------------------------
00045 typedef XnValue XnKey;
00046 
00050 typedef XnUInt8 XnHashValue;
00051 
00055 static XnHashValue XnDefaultHashFunction(const XnKey& key)
00056 {
00057     return (XnSizeT(key) & 0xff);
00058 }
00059 
00063 static XnInt32 XnDefaultCompareFunction(const XnKey& key1, const XnKey& key2)
00064 {
00065     return XnSizeT(key1)-XnSizeT(key2);
00066 }
00067 
00071 class XnHash
00072 {
00073 public:
00077     class ConstIterator
00078     {
00079     public:
00080         friend class XnHash;
00081 
00087         ConstIterator(const ConstIterator& other) :
00088             m_pHash(other.m_pHash), m_nCurrentBin(other.m_nCurrentBin), m_Iterator(other.m_Iterator) {}
00089 
00093         ConstIterator& operator++()
00094         {
00095             ++m_Iterator;
00096 
00097             while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
00098                 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
00099             {
00100                 do
00101                 {
00102                     m_nCurrentBin++;
00103                 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
00104                 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin();
00105             }
00106             return *this;
00107         }
00108 
00112         ConstIterator operator++(int)
00113         {
00114             XnHash::ConstIterator other(*this);
00115             ++*this;
00116             return other;
00117         }
00118 
00122         ConstIterator& operator--()
00123         {
00124             --m_Iterator;
00125 
00126             while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
00127                 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
00128             {
00129                 do 
00130                 {
00131                     if (m_nCurrentBin == 0)
00132                     {
00133                         m_nCurrentBin = XN_HASH_LAST_BIN;
00134                         m_Iterator = m_pHash->m_Bins[XN_HASH_LAST_BIN]->end();
00135                         return *this;
00136                     }
00137                     m_nCurrentBin--;
00138                 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
00139                 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->rbegin();
00140             }
00141             return *this;
00142         }
00143 
00147         ConstIterator operator--(int)
00148         {
00149             ConstIterator other(*this);
00150             --*this;
00151             return other;
00152         }
00153 
00159         XnBool operator==(const ConstIterator& other) const
00160         {
00161             return m_Iterator == other.m_Iterator;
00162         }
00163 
00169         XnBool operator!=(const ConstIterator& other) const
00170         {
00171             return m_Iterator != other.m_Iterator;
00172         }
00173 
00177         const XnKey& Key() const
00178         {
00179             return ((XnNode*)(*m_Iterator))->Data();
00180         }
00181 
00185         const XnValue& Value() const
00186         {
00187             return ((XnNode*)(*m_Iterator))->Next()->Data();
00188         }
00189 
00193         XnNode* GetNode()
00194         {
00195             return m_Iterator.GetNode();
00196         }
00197 
00201         const XnNode* GetNode() const
00202         {
00203             return m_Iterator.GetNode();
00204         }
00205 
00206     protected:
00214         ConstIterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) :
00215              m_pHash(pHash), m_nCurrentBin(nBin), m_Iterator(listIterator)
00216              {
00217                  // Find the first valid
00218                  while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
00219                      m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
00220                  {
00221                      do
00222                      {
00223                          m_nCurrentBin++;
00224                      } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
00225                      m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin();
00226                  }
00227              }
00228 
00234         ConstIterator(const XnHash* pHash) : 
00235              m_pHash(pHash), m_nCurrentBin(0), m_Iterator(m_pHash->m_Bins[XN_HASH_LAST_BIN]->end()) {}
00236 
00238         const XnHash* m_pHash;
00240         XnUInt16 m_nCurrentBin;
00242         XnList::Iterator m_Iterator;
00243     };
00244 
00248     class Iterator : public ConstIterator
00249     {
00250     public:
00251         friend class XnHash;
00252 
00258         inline Iterator(const Iterator& other) : ConstIterator(other) {}
00259 
00263         inline Iterator& operator++() 
00264         { 
00265             ++(*(ConstIterator*)this);
00266             return (*this);
00267         }
00271         inline Iterator operator++(int) 
00272         { 
00273             Iterator result = *this;
00274             ++*this;
00275             return (result);
00276         }
00277         
00281         inline Iterator& operator--() 
00282         { 
00283             --(*(ConstIterator*)this); 
00284             return (*this);
00285         }
00289         inline Iterator operator--(int)
00290         { 
00291             Iterator result = *this;
00292             --*this;
00293             return (result);
00294         }
00295 
00299         XnKey& Key() const { return (XnKey&)ConstIterator::Key(); }
00300 
00304         XnValue& Value() const { return (XnValue&)ConstIterator::Value(); }
00305 
00306     protected:
00314         Iterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) :
00315             ConstIterator(pHash, nBin, listIterator)
00316         {}
00317 
00323         Iterator(const XnHash* pHash) : ConstIterator(pHash) {}
00324 
00325         Iterator(const ConstIterator& other) : ConstIterator(other) {}
00326     };
00327 
00328     friend class Iterator;
00329 
00330 public:
00334     typedef XnHashValue (*XnHashFunction)(const XnKey& key);
00338     typedef XnInt32 (*XnCompareFunction)(const XnKey& key1, const XnKey& key2);
00339 
00343     XnHash()
00344     {
00345         m_nInitStatus = Init();
00346     }
00347 
00351     XnHash(const XnHash& other)
00352     {
00353         m_nInitStatus = Init();
00354         if (m_nInitStatus == XN_STATUS_OK)
00355         {
00356             m_nMinBin = other.m_nMinBin;
00357             m_CompareFunction = other.m_CompareFunction;
00358             m_HashFunction = other.m_HashFunction;
00359             for (int i = 0; i < XN_HASH_NUM_BINS; i++)
00360             {
00361                 if (other.m_Bins[i] != NULL)
00362                 {
00363                     m_Bins[i] = XN_NEW(XnList);
00364                     if (m_Bins[i] == NULL)
00365                     {
00366                         m_nInitStatus = XN_STATUS_ALLOC_FAILED;
00367                         return;
00368                     }
00369                     *(m_Bins[i]) = *(other.m_Bins[i]);
00370                 }
00371             }
00372         }
00373     }
00374 
00378     virtual ~XnHash()
00379     {
00380         if (m_Bins != NULL)
00381         {
00382             for (int i = 0; i < XN_HASH_NUM_BINS; ++i)
00383             {
00384                 XN_DELETE(m_Bins[i]);
00385             }
00386             XN_DELETE_ARR(m_Bins);
00387         }
00388     }
00389 
00395     XnStatus GetInitStatus() const
00396     {
00397         return m_nInitStatus;
00398     }
00399 
00406     XnStatus Set(const XnKey& key, const XnValue& value)
00407     {
00408         XnHashValue HashValue = (*m_HashFunction)(key);
00409 
00410         // Check if key already exists
00411         if (m_Bins[HashValue] != NULL)
00412         {
00413             Iterator hiter(this);
00414             if (Find(key, HashValue, hiter) == XN_STATUS_OK)
00415             {
00416                 // Replace value
00417                 hiter.Value() = value;
00418                 return XN_STATUS_OK;
00419             }
00420         }
00421         else
00422         {
00423             // First time trying to access this bin, create it.
00424             m_Bins[HashValue] = XN_NEW(XnList);
00425             if (m_Bins[HashValue] == NULL)
00426             {
00427                 return XN_STATUS_ALLOC_FAILED;
00428             }
00429             if (HashValue < m_nMinBin)
00430                 m_nMinBin = HashValue;
00431         }
00432 
00433         // Get a new node for the key
00434         XnNode* pKeyNode = XnNode::Allocate();
00435         if (pKeyNode == NULL)
00436         {
00437             return XN_STATUS_ALLOC_FAILED;
00438         }
00439         pKeyNode->Data() = key;
00440 
00441         // Get a new node for the value
00442         XnNode* pValueNode = XnNode::Allocate();
00443         if (pValueNode == NULL)
00444         {
00445             XnNode::Deallocate(pKeyNode);
00446             return XN_STATUS_ALLOC_FAILED;
00447         }
00448         pValueNode->Data() = value;
00449 
00450         // Concatenate the value node to the key node
00451         pKeyNode->Next() = pValueNode;
00452         pValueNode->Next() = NULL;
00453 
00454         // Add the 2 nodes as the value to the key's list
00455         XnStatus ListStatus = m_Bins[HashValue]->AddLast(XnValue(pKeyNode));
00456         if (ListStatus != XN_STATUS_OK)
00457         {
00458             // Add failed. return the 2 nodes to the pool
00459             XnNode::Deallocate(pKeyNode);
00460             XnNode::Deallocate(pValueNode);
00461             return ListStatus;
00462         }
00463 
00464         return XN_STATUS_OK;
00465     }
00466 
00475     XnStatus Get(const XnKey& key, XnValue& value) const
00476     {
00477         // Check if key exists
00478         Iterator hiter(this);
00479         XnStatus FindStatus = Find(key, hiter);
00480         if (FindStatus != XN_STATUS_OK)
00481         {
00482             // Key doesn't exist!
00483             return FindStatus;
00484         }
00485         value = hiter.Value();
00486 
00487         return XN_STATUS_OK;
00488     }
00489 
00498     XnStatus Remove(const XnKey& key, XnValue& value)
00499     {
00500         // find the entry to which the key belongs
00501         Iterator hiter(this);
00502 
00503         XnStatus FindStatus = Find(key, hiter);
00504         if (FindStatus != XN_STATUS_OK)
00505         {
00506             // no such entry!
00507             return FindStatus;
00508         }
00509 
00510         // Remove by iterator
00511         value = hiter.Value();
00512         return Remove(hiter);
00513     }
00514 
00524     XnStatus Remove(ConstIterator iter, XnKey& key, XnValue& value)
00525     {
00526         if (iter == end())
00527         {
00528             //  Can't remove invalid node
00529             return XN_STATUS_ILLEGAL_POSITION;
00530         }
00531 
00532         // Get value and key, to return to the caller
00533         value = iter.Value();
00534         key = iter.Key();
00535 
00536         return Remove(iter);
00537     }
00538 
00546     virtual XnStatus Remove(ConstIterator iter)
00547     {
00548         if (iter == end())
00549         {
00550             //  Can't remove invalid node
00551             return XN_STATUS_ILLEGAL_POSITION;
00552         }
00553 
00554         XnNode* pNode = iter.GetNode();
00555 
00556         XnNode* pKeyNode = (XnNode*)(pNode->Data());
00557         XnNode* pValueNode = pKeyNode->Next();
00558 
00559         // Return the nodes to the pool
00560         XnNode::Deallocate(pKeyNode);
00561         XnNode::Deallocate(pValueNode);
00562 
00563         pNode->Previous()->Next() = pNode->Next();
00564         pNode->Next()->Previous() = pNode->Previous();
00565 
00566         XnNode::Deallocate(pNode);
00567 
00568         return XN_STATUS_OK;
00569     }
00570 
00571 
00575     XnStatus Clear()
00576     {
00577         while (begin() != end())
00578             Remove(begin());
00579 
00580         return XN_STATUS_OK;
00581     }
00582 
00586     XnBool IsEmpty() const
00587     {
00588         return (begin() == end());
00589     }
00590 
00594     XnUInt32 Size() const
00595     {
00596         XnUInt32 nSize = 0;
00597         for (Iterator iter = begin(); iter != end(); ++iter, ++nSize)
00598             ;
00599 
00600         return nSize;
00601     }
00602 
00611     XnStatus Find(const XnKey& key, ConstIterator& hiter) const
00612     {
00613         XnHashValue HashValue = (*m_HashFunction)(key);
00614         return Find(key, HashValue, hiter);
00615     }
00616 
00625     XnStatus Find(const XnKey& key, Iterator& hiter)
00626     {
00627         XnStatus nRetVal = XN_STATUS_OK;
00628 
00629         ConstIterator& it = hiter;
00630         nRetVal = Find(key, it);
00631         XN_IS_STATUS_OK(nRetVal);
00632 
00633         return (XN_STATUS_OK);
00634     }
00635 
00639     Iterator begin()
00640     {
00641         return Iterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin());
00642     }
00643 
00647     ConstIterator begin() const
00648     {
00649         return ConstIterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin());
00650     }
00651 
00655     Iterator end()
00656     {
00657         return Iterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end());
00658     }
00659 
00663     ConstIterator end() const
00664     {
00665         return ConstIterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end());
00666     }
00667 
00675     XnStatus SetHashFunction(XnHashFunction hashFunction)
00676     {
00677         if (begin() != end())
00678         {
00679             return XN_STATUS_IS_NOT_EMPTY;
00680         }
00681         m_HashFunction = hashFunction;
00682         return XN_STATUS_OK;
00683     }
00684 
00692     XnStatus SetCompareFunction(XnCompareFunction compareFunction)
00693     {
00694         if (begin() != end())
00695         {
00696             return XN_STATUS_IS_NOT_EMPTY;
00697         }
00698         m_CompareFunction = compareFunction;
00699         return XN_STATUS_OK;
00700     }
00701 
00702 protected:
00703 
00704     XnStatus Init()
00705     {
00706         m_Bins = XN_NEW_ARR(XnList*, XN_HASH_NUM_BINS);
00707         XN_VALIDATE_ALLOC_PTR(m_Bins);
00708 
00709         for (int i = 0; i < XN_HASH_NUM_BINS; i++)
00710         {
00711             m_Bins[i] = NULL;
00712         }
00713 
00714         m_Bins[XN_HASH_LAST_BIN] = XN_NEW(XnList); // We need this for  an end() iterator
00715         m_nMinBin = XN_HASH_LAST_BIN;
00716 
00717         XN_VALIDATE_ALLOC_PTR(m_Bins[XN_HASH_LAST_BIN]);
00718         m_CompareFunction = &XnDefaultCompareFunction;
00719         m_HashFunction = &XnDefaultHashFunction;
00720         return XN_STATUS_OK;
00721     }
00722 
00732     XnStatus Find(const XnKey& key, XnHashValue hashValue, ConstIterator& hiter) const
00733     {
00734         if (m_Bins[hashValue] != NULL)
00735         {
00736             hiter = ConstIterator(this, hashValue, m_Bins[hashValue]->begin());
00737             for (XnList::ConstIterator iter = m_Bins[hashValue]->begin();
00738                 iter != m_Bins[hashValue]->end(); ++iter, ++hiter)
00739             {
00740                 if ((*m_CompareFunction)(key, hiter.Key()) == 0)
00741                     return XN_STATUS_OK;
00742             }
00743         }
00744 
00745         return XN_STATUS_NO_MATCH;
00746     }
00747 
00748 
00750     XnList** m_Bins;
00751 
00752     XnUInt16 m_nMinBin;
00753 
00754     /* Status of initialization - could be an error if memory could not be allocated. */
00755     XnStatus m_nInitStatus;
00756 
00758     XnHashFunction m_HashFunction;
00760     XnCompareFunction m_CompareFunction;
00761 };
00762 
00767 #define XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, ClassName, KeyTranslator)    \
00768     class decl ClassName                                                                \
00769     {                                                                                   \
00770     public:                                                                             \
00771         inline static XnHashValue Hash(KeyType const& key)                              \
00772         {                                                                               \
00773             const XnKey _key = KeyTranslator::GetAsValue(key);                          \
00774             return XnDefaultHashFunction(_key);                                         \
00775         }                                                                               \
00776         inline static XnInt32 Compare(KeyType const& key1, KeyType const& key2)     \
00777         {                                                                               \
00778             const XnKey _key1 = KeyTranslator::GetAsValue(key1);                        \
00779             const XnKey _key2 = KeyTranslator::GetAsValue(key2);                        \
00780             return XnDefaultCompareFunction(_key1, _key2);                              \
00781         }                                                                               \
00782     };
00783 
00788 #define XN_DECLARE_DEFAULT_KEY_MANAGER(KeyType, ClassName, KeyTranslator)   \
00789     XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(, KeyType, ClassName, KeyTranslator)
00790 
00796 #define XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager)   \
00797     class decl ClassName : public XnHash                                                            \
00798     {                                                                                               \
00799     public:                                                                                         \
00800         class decl ConstIterator : public XnHash::ConstIterator                                     \
00801         {                                                                                           \
00802         public:                                                                                     \
00803             friend class ClassName;                                                                 \
00804             inline ConstIterator(const ConstIterator& other) : XnHash::ConstIterator(other) {}      \
00805             inline ConstIterator& operator++()                                                      \
00806             {                                                                                       \
00807                 ++(*(XnHash::ConstIterator*)this);                                                  \
00808                 return (*this);                                                                     \
00809             }                                                                                       \
00810             inline ConstIterator operator++(int)                                                    \
00811             {                                                                                       \
00812                 ConstIterator result = *this;                                                       \
00813                 ++*this;                                                                            \
00814                 return result;                                                                      \
00815             }                                                                                       \
00816             inline ConstIterator& operator--()                                                      \
00817             {                                                                                       \
00818                 --(*(XnHash::ConstIterator*)this);                                                  \
00819                 return (*this);                                                                     \
00820             }                                                                                       \
00821             inline ConstIterator operator--(int)                                                    \
00822             {                                                                                       \
00823                 ConstIterator result = *this;                                                       \
00824                 --*this;                                                                            \
00825                 return result;                                                                      \
00826             }                                                                                       \
00827             inline KeyType const& Key() const                                                       \
00828             {                                                                                       \
00829                 return KeyTranslator::GetFromValue(XnHash::ConstIterator::Key());                   \
00830             }                                                                                       \
00831             inline ValueType const& Value() const                                                   \
00832             {                                                                                       \
00833                 return ValueTranslator::GetFromValue(XnHash::ConstIterator::Value());               \
00834             }                                                                                       \
00835         protected:                                                                                  \
00836             inline ConstIterator(const XnHash::ConstIterator& other) :                              \
00837                 XnHash::ConstIterator(other) {}                                                     \
00838         };                                                                                          \
00839         class decl Iterator : public ConstIterator                                                  \
00840         {                                                                                           \
00841         public:                                                                                     \
00842             friend class ClassName;                                                                 \
00843             inline Iterator(const Iterator& other) : ConstIterator(other) {}                        \
00844             inline Iterator& operator++()                                                           \
00845             {                                                                                       \
00846                 ++(*(ConstIterator*)this);                                                          \
00847                 return (*this);                                                                     \
00848             }                                                                                       \
00849             inline Iterator operator++(int)                                                         \
00850             {                                                                                       \
00851                 Iterator result = *this;                                                            \
00852                 ++*this;                                                                            \
00853                 return result;                                                                      \
00854             }                                                                                       \
00855             inline Iterator& operator--()                                                           \
00856             {                                                                                       \
00857                 --(*(ConstIterator*)this);                                                          \
00858                 return (*this);                                                                     \
00859             }                                                                                       \
00860             inline Iterator operator--(int)                                                         \
00861             {                                                                                       \
00862                 Iterator result = *this;                                                            \
00863                 --*this;                                                                            \
00864                 return result;                                                                      \
00865             }                                                                                       \
00866             inline KeyType& Key() const                                                             \
00867             {                                                                                       \
00868                 return (KeyType&)ConstIterator::Key();                                              \
00869             }                                                                                       \
00870             inline ValueType& Value() const                                                         \
00871             {                                                                                       \
00872                 return (ValueType&)ConstIterator::Value();                                          \
00873             }                                                                                       \
00874         protected:                                                                                  \
00875             inline Iterator(const XnHash::Iterator& other) : ConstIterator(other) {}                \
00876         };                                                                                          \
00877     public:                                                                                         \
00878         ClassName()                                                                                 \
00879         {                                                                                           \
00880             SetHashFunction(Hash);                                                                  \
00881             SetCompareFunction(Compare);                                                            \
00882         }                                                                                           \
00883         ClassName(const ClassName& other)                                                           \
00884         {                                                                                           \
00885             SetHashFunction(Hash);                                                                  \
00886             SetCompareFunction(Compare);                                                            \
00887             *this = other;                                                                          \
00888         }                                                                                           \
00889         virtual ~ClassName()                                                                        \
00890         {                                                                                           \
00891             while (!IsEmpty())                                                                      \
00892                 Remove(begin());                                                                    \
00893         }                                                                                           \
00894         ClassName& operator=(const ClassName& other)                                                \
00895         {                                                                                           \
00896             Clear();                                                                                \
00897             for (ConstIterator it = other.begin(); it != other.end(); it++)                         \
00898             {                                                                                       \
00899                 m_nInitStatus = Set(it.Key(), it.Value());                                          \
00900                 if (m_nInitStatus != XN_STATUS_OK)                                                  \
00901                 {                                                                                   \
00902                     return *this;                                                                   \
00903                 }                                                                                   \
00904             }                                                                                       \
00905             return *this;                                                                           \
00906         }                                                                                           \
00907         XnStatus Set(KeyType const& key, ValueType const& value)                                    \
00908         {                                                                                           \
00909             Iterator oldIt = begin();                                                               \
00910             if (Find(key, oldIt) == XN_STATUS_OK)                                                   \
00911             {                                                                                       \
00912                 oldIt.Value() = value;                                                              \
00913             }                                                                                       \
00914             else                                                                                    \
00915             {                                                                                       \
00916                 XnKey _key = KeyTranslator::CreateValueCopy(key);                                   \
00917                 XnValue _value = ValueTranslator::CreateValueCopy(value);                           \
00918                 XnStatus nRetVal = XnHash::Set(_key, _value);                                       \
00919                 if (nRetVal != XN_STATUS_OK)                                                        \
00920                 {                                                                                   \
00921                     KeyTranslator::FreeValue(_key);                                                 \
00922                     ValueTranslator::FreeValue(_value);                                             \
00923                     return (nRetVal);                                                               \
00924                 }                                                                                   \
00925             }                                                                                       \
00926             return XN_STATUS_OK;                                                                    \
00927         }                                                                                           \
00928         XnStatus Get(KeyType const& key, ValueType& value) const                                    \
00929         {                                                                                           \
00930             XnKey _key = KeyTranslator::GetAsValue(key);                                            \
00931             XnValue _value;                                                                         \
00932             XnStatus nRetVal = XnHash::Get(_key, _value);                                           \
00933             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                          \
00934             value = ValueTranslator::GetFromValue(_value);                                          \
00935             return XN_STATUS_OK;                                                                    \
00936         }                                                                                           \
00937         XnStatus Get(KeyType const& key, ValueType*& pValue) const                                  \
00938         {                                                                                           \
00939             XnKey _key = KeyTranslator::GetAsValue(key);                                            \
00940             XnValue _value;                                                                         \
00941             XnStatus nRetVal = XnHash::Get(_key, _value);                                           \
00942             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                          \
00943             pValue = &ValueTranslator::GetFromValue(_value);                                        \
00944             return XN_STATUS_OK;                                                                    \
00945         }                                                                                           \
00946         XnStatus Remove(KeyType const& key)                                                         \
00947         {                                                                                           \
00948             ValueType dummy;                                                                        \
00949             return Remove(key, dummy);                                                              \
00950         }                                                                                           \
00951         XnStatus Remove(KeyType const& key, ValueType& value)                                       \
00952         {                                                                                           \
00953             ConstIterator it = end();                                                               \
00954             XnStatus nRetVal = Find(key, it);                                                       \
00955             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                          \
00956             value = it.Value();                                                                     \
00957             return Remove(it);                                                                      \
00958         }                                                                                           \
00959         inline XnStatus Remove(ConstIterator iter)                                                  \
00960         {                                                                                           \
00961             XnKey key = KeyTranslator::GetAsValue(iter.Key());                                      \
00962             XnValue value = ValueTranslator::GetAsValue(iter.Value());                              \
00963             XnStatus nRetVal = XnHash::Remove(iter);                                                \
00964             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                          \
00965             KeyTranslator::FreeValue(key);                                                          \
00966             ValueTranslator::FreeValue(value);                                                      \
00967             return XN_STATUS_OK;                                                                    \
00968         }                                                                                           \
00969         XnStatus Find(KeyType const& key, ConstIterator& hiter) const                               \
00970         {                                                                                           \
00971             XnKey _key = KeyTranslator::GetAsValue(key);                                            \
00972             XnHash::ConstIterator it = XnHash::end();                                               \
00973             XnStatus nRetVal = XnHash::Find(_key, it);                                              \
00974             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                          \
00975             hiter = it;                                                                             \
00976             return XN_STATUS_OK;                                                                    \
00977         }                                                                                           \
00978         XnStatus Find(KeyType const& key, Iterator& hiter)                                          \
00979         {                                                                                           \
00980             XnKey _key = KeyTranslator::GetAsValue(key);                                            \
00981             XnHash::Iterator it = XnHash::end();                                                    \
00982             XnStatus nRetVal = XnHash::Find(_key, it);                                              \
00983             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                          \
00984             hiter = it;                                                                             \
00985             return XN_STATUS_OK;                                                                    \
00986         }                                                                                           \
00987         inline Iterator begin() { return XnHash::begin(); }                                         \
00988         inline ConstIterator begin() const { return XnHash::begin(); }                              \
00989         inline Iterator end() { return XnHash::end(); }                                             \
00990         inline ConstIterator end() const { return XnHash::end(); }                                  \
00991     protected:                                                                                      \
00992         virtual XnStatus Remove(XnHash::ConstIterator iter)                                         \
00993         {                                                                                           \
00994             return Remove(ConstIterator(iter));                                                     \
00995         }                                                                                           \
00996         inline static XnHashValue Hash(const XnKey& key)                                            \
00997         {                                                                                           \
00998             KeyType const& _key = KeyTranslator::GetFromValue(key);                                 \
00999             return KeyManager::Hash(_key);                                                          \
01000         }                                                                                           \
01001         inline static XnInt32 Compare(const XnKey& key1, const XnKey& key2)                     \
01002         {                                                                                           \
01003             KeyType const _key1 = KeyTranslator::GetFromValue(key1);                                \
01004             KeyType const _key2 = KeyTranslator::GetFromValue(key2);                                \
01005             return KeyManager::Compare(_key1, _key2);                                               \
01006         }                                                                                           \
01007     };
01008 
01013 #define XN_DECLARE_HASH(KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager)  \
01014     XN_DECLARE_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager)
01015 
01016 #define _XN_DEFAULT_KEY_MANAGER_NAME(ClassName) _##ClassName##Manager
01017 
01023 #define XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator)   \
01024     XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName), KeyTranslator)      \
01025     XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName))
01026 
01031 #define XN_DECLARE_DEFAULT_MANAGER_HASH(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator)    \
01032     XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator)
01033 
01034 #define _XN_DEFAULT_KEY_TRANSLATOR(ClassName)   _##ClassName##KeyTranslator
01035 #define _XN_DEFAULT_VALUE_TRANSLATOR(ClassName) _##ClassName##ValueTranslator
01036 
01042 #define XN_DECLARE_DEFAULT_HASH_DECL(decl, KeyType, ValueType, ClassName)                                           \
01043     XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, KeyType, _XN_DEFAULT_KEY_TRANSLATOR(ClassName))                  \
01044     XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, ValueType, _XN_DEFAULT_VALUE_TRANSLATOR(ClassName))              \
01045     XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, _XN_DEFAULT_KEY_TRANSLATOR(ClassName), _XN_DEFAULT_VALUE_TRANSLATOR(ClassName))
01046 
01051 #define XN_DECLARE_DEFAULT_HASH(KeyType, ValueType, ClassName)      \
01052     XN_DECLARE_DEFAULT_HASH_DECL(, KeyType, ValueType, ClassName)
01053 
01054 #endif // _XN_HASH_H

Generated on Thu Feb 10 2011 for OpenNI 1.0.0 by  doxygen 1.7.1