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

XnHash.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 *                                                                           *
00003 *  OpenNI 1.1 Alpha                                                         *
00004 *  Copyright (C) 2011 PrimeSense Ltd.                                       *
00005 *                                                                           *
00006 *  This file is part of OpenNI.                                             *
00007 *                                                                           *
00008 *  OpenNI is free software: you can redistribute it and/or modify           *
00009 *  it under the terms of the GNU Lesser General Public License as published *
00010 *  by the Free Software Foundation, either version 3 of the License, or     *
00011 *  (at your option) any later version.                                      *
00012 *                                                                           *
00013 *  OpenNI is distributed in the hope that it will be useful,                *
00014 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00015 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the             *
00016 *  GNU Lesser General Public License for more details.                      *
00017 *                                                                           *
00018 *  You should have received a copy of the GNU Lesser General Public License *
00019 *  along with OpenNI. If not, see <http://www.gnu.org/licenses/>.           *
00020 *                                                                           *
00021 ****************************************************************************/
00022 #ifndef _XN_HASH_H
00023 #define _XN_HASH_H
00024 
00025 //---------------------------------------------------------------------------
00026 // Includes
00027 //---------------------------------------------------------------------------
00028 #include "XnList.h"
00029 
00030 //---------------------------------------------------------------------------
00031 // Defines
00032 //---------------------------------------------------------------------------
00033 #define XN_HASH_LAST_BIN 256
00034 #define XN_HASH_NUM_BINS (XN_HASH_LAST_BIN + 1)
00035 //---------------------------------------------------------------------------
00036 // Types
00037 //---------------------------------------------------------------------------
00041 typedef XnValue XnKey;
00042 
00046 typedef XnUInt8 XnHashValue;
00047 
00051 static XnHashValue XnDefaultHashFunction(const XnKey& key)
00052 {
00053     return (XnSizeT(key) & 0xff);
00054 }
00055 
00059 static XnInt32 XnDefaultCompareFunction(const XnKey& key1, const XnKey& key2)
00060 {
00061     return XnInt32(XnSizeT(key1)-XnSizeT(key2));
00062 }
00063 
00067 class XnHash
00068 {
00069 public:
00073     class ConstIterator
00074     {
00075     public:
00076         friend class XnHash;
00077 
00083         ConstIterator(const ConstIterator& other) :
00084             m_pHash(other.m_pHash), m_nCurrentBin(other.m_nCurrentBin), m_Iterator(other.m_Iterator) {}
00085 
00089         ConstIterator& operator++()
00090         {
00091             ++m_Iterator;
00092 
00093             while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
00094                 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
00095             {
00096                 do
00097                 {
00098                     m_nCurrentBin++;
00099                 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
00100                 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin();
00101             }
00102             return *this;
00103         }
00104 
00108         ConstIterator operator++(int)
00109         {
00110             XnHash::ConstIterator other(*this);
00111             ++*this;
00112             return other;
00113         }
00114 
00118         ConstIterator& operator--()
00119         {
00120             --m_Iterator;
00121 
00122             while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
00123                 m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
00124             {
00125                 do 
00126                 {
00127                     if (m_nCurrentBin == 0)
00128                     {
00129                         m_nCurrentBin = XN_HASH_LAST_BIN;
00130                         m_Iterator = m_pHash->m_Bins[XN_HASH_LAST_BIN]->end();
00131                         return *this;
00132                     }
00133                     m_nCurrentBin--;
00134                 } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
00135                 m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->rbegin();
00136             }
00137             return *this;
00138         }
00139 
00143         ConstIterator operator--(int)
00144         {
00145             ConstIterator other(*this);
00146             --*this;
00147             return other;
00148         }
00149 
00155         XnBool operator==(const ConstIterator& other) const
00156         {
00157             return m_Iterator == other.m_Iterator;
00158         }
00159 
00165         XnBool operator!=(const ConstIterator& other) const
00166         {
00167             return m_Iterator != other.m_Iterator;
00168         }
00169 
00173         const XnKey& Key() const
00174         {
00175             return ((XnNode*)(*m_Iterator))->Data();
00176         }
00177 
00181         const XnValue& Value() const
00182         {
00183             return ((XnNode*)(*m_Iterator))->Next()->Data();
00184         }
00185 
00189         XnNode* GetNode()
00190         {
00191             return m_Iterator.GetNode();
00192         }
00193 
00197         const XnNode* GetNode() const
00198         {
00199             return m_Iterator.GetNode();
00200         }
00201 
00202     protected:
00210         ConstIterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) :
00211              m_pHash(pHash), m_nCurrentBin(nBin), m_Iterator(listIterator)
00212              {
00213                  // Find the first valid
00214                  while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
00215                      m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
00216                  {
00217                      do
00218                      {
00219                          m_nCurrentBin++;
00220                      } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
00221                      m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin();
00222                  }
00223              }
00224 
00230         ConstIterator(const XnHash* pHash) : 
00231              m_pHash(pHash), m_nCurrentBin(0), m_Iterator(m_pHash->m_Bins[XN_HASH_LAST_BIN]->end()) {}
00232 
00234         const XnHash* m_pHash;
00236         XnUInt16 m_nCurrentBin;
00238         XnList::Iterator m_Iterator;
00239     };
00240 
00244     class Iterator : public ConstIterator
00245     {
00246     public:
00247         friend class XnHash;
00248 
00254         inline Iterator(const Iterator& other) : ConstIterator(other) {}
00255 
00259         inline Iterator& operator++() 
00260         { 
00261             ++(*(ConstIterator*)this);
00262             return (*this);
00263         }
00267         inline Iterator operator++(int) 
00268         { 
00269             Iterator result = *this;
00270             ++*this;
00271             return (result);
00272         }
00273         
00277         inline Iterator& operator--() 
00278         { 
00279             --(*(ConstIterator*)this); 
00280             return (*this);
00281         }
00285         inline Iterator operator--(int)
00286         { 
00287             Iterator result = *this;
00288             --*this;
00289             return (result);
00290         }
00291 
00295         XnKey& Key() const { return (XnKey&)ConstIterator::Key(); }
00296 
00300         XnValue& Value() const { return (XnValue&)ConstIterator::Value(); }
00301 
00302     protected:
00310         Iterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) :
00311             ConstIterator(pHash, nBin, listIterator)
00312         {}
00313 
00319         Iterator(const XnHash* pHash) : ConstIterator(pHash) {}
00320 
00321         Iterator(const ConstIterator& other) : ConstIterator(other) {}
00322     };
00323 
00324     friend class ConstIterator;
00325 
00326 public:
00330     typedef XnHashValue (*XnHashFunction)(const XnKey& key);
00334     typedef XnInt32 (*XnCompareFunction)(const XnKey& key1, const XnKey& key2);
00335 
00339     XnHash()
00340     {
00341         m_nInitStatus = Init();
00342     }
00343 
00347     XnHash(const XnHash& other)
00348     {
00349         m_nInitStatus = Init();
00350         if (m_nInitStatus == XN_STATUS_OK)
00351         {
00352             m_nMinBin = other.m_nMinBin;
00353             m_CompareFunction = other.m_CompareFunction;
00354             m_HashFunction = other.m_HashFunction;
00355             for (int i = 0; i < XN_HASH_NUM_BINS; i++)
00356             {
00357                 if (other.m_Bins[i] != NULL)
00358                 {
00359                     m_Bins[i] = XN_NEW(XnList);
00360                     if (m_Bins[i] == NULL)
00361                     {
00362                         m_nInitStatus = XN_STATUS_ALLOC_FAILED;
00363                         return;
00364                     }
00365                     *(m_Bins[i]) = *(other.m_Bins[i]);
00366                 }
00367             }
00368         }
00369     }
00370 
00374     virtual ~XnHash()
00375     {
00376         if (m_Bins != NULL)
00377         {
00378             for (int i = 0; i < XN_HASH_NUM_BINS; ++i)
00379             {
00380                 XN_DELETE(m_Bins[i]);
00381             }
00382             XN_DELETE_ARR(m_Bins);
00383         }
00384     }
00385 
00391     XnStatus GetInitStatus() const
00392     {
00393         return m_nInitStatus;
00394     }
00395 
00402     XnStatus Set(const XnKey& key, const XnValue& value)
00403     {
00404         XnHashValue HashValue = (*m_HashFunction)(key);
00405 
00406         // Check if key already exists
00407         if (m_Bins[HashValue] != NULL)
00408         {
00409             Iterator hiter(this);
00410             if (Find(key, HashValue, hiter) == XN_STATUS_OK)
00411             {
00412                 // Replace value
00413                 hiter.Value() = value;
00414                 return XN_STATUS_OK;
00415             }
00416         }
00417         else
00418         {
00419             // First time trying to access this bin, create it.
00420             m_Bins[HashValue] = XN_NEW(XnList);
00421             if (m_Bins[HashValue] == NULL)
00422             {
00423                 return XN_STATUS_ALLOC_FAILED;
00424             }
00425             if (HashValue < m_nMinBin)
00426                 m_nMinBin = HashValue;
00427         }
00428 
00429         // Get a new node for the key
00430         XnNode* pKeyNode = XnNode::Allocate();
00431         if (pKeyNode == NULL)
00432         {
00433             return XN_STATUS_ALLOC_FAILED;
00434         }
00435         pKeyNode->Data() = key;
00436 
00437         // Get a new node for the value
00438         XnNode* pValueNode = XnNode::Allocate();
00439         if (pValueNode == NULL)
00440         {
00441             XnNode::Deallocate(pKeyNode);
00442             return XN_STATUS_ALLOC_FAILED;
00443         }
00444         pValueNode->Data() = value;
00445 
00446         // Concatenate the value node to the key node
00447         pKeyNode->Next() = pValueNode;
00448         pValueNode->Next() = NULL;
00449 
00450         // Add the 2 nodes as the value to the key's list
00451         XnStatus ListStatus = m_Bins[HashValue]->AddLast(XnValue(pKeyNode));
00452         if (ListStatus != XN_STATUS_OK)
00453         {
00454             // Add failed. return the 2 nodes to the pool
00455             XnNode::Deallocate(pKeyNode);
00456             XnNode::Deallocate(pValueNode);
00457             return ListStatus;
00458         }
00459 
00460         return XN_STATUS_OK;
00461     }
00462 
00471     XnStatus Get(const XnKey& key, XnValue& value) const
00472     {
00473         // Check if key exists
00474         Iterator hiter(this);
00475         XnStatus FindStatus = Find(key, hiter);
00476         if (FindStatus != XN_STATUS_OK)
00477         {
00478             // Key doesn't exist!
00479             return FindStatus;
00480         }
00481         value = hiter.Value();
00482 
00483         return XN_STATUS_OK;
00484     }
00485 
00494     XnStatus Remove(const XnKey& key, XnValue& value)
00495     {
00496         // find the entry to which the key belongs
00497         Iterator hiter(this);
00498 
00499         XnStatus FindStatus = Find(key, hiter);
00500         if (FindStatus != XN_STATUS_OK)
00501         {
00502             // no such entry!
00503             return FindStatus;
00504         }
00505 
00506         // Remove by iterator
00507         value = hiter.Value();
00508         return Remove(hiter);
00509     }
00510 
00520     XnStatus Remove(ConstIterator iter, XnKey& key, XnValue& value)
00521     {
00522         if (iter == end())
00523         {
00524             //  Can't remove invalid node
00525             return XN_STATUS_ILLEGAL_POSITION;
00526         }
00527 
00528         // Get value and key, to return to the caller
00529         value = iter.Value();
00530         key = iter.Key();
00531 
00532         return Remove(iter);
00533     }
00534 
00542     virtual XnStatus Remove(ConstIterator iter)
00543     {
00544         if (iter == end())
00545         {
00546             //  Can't remove invalid node
00547             return XN_STATUS_ILLEGAL_POSITION;
00548         }
00549 
00550         XnNode* pNode = iter.GetNode();
00551 
00552         XnNode* pKeyNode = (XnNode*)(pNode->Data());
00553         XnNode* pValueNode = pKeyNode->Next();
00554 
00555         // Return the nodes to the pool
00556         XnNode::Deallocate(pKeyNode);
00557         XnNode::Deallocate(pValueNode);
00558 
00559         pNode->Previous()->Next() = pNode->Next();
00560         pNode->Next()->Previous() = pNode->Previous();
00561 
00562         XnNode::Deallocate(pNode);
00563 
00564         return XN_STATUS_OK;
00565     }
00566 
00567 
00571     XnStatus Clear()
00572     {
00573         while (begin() != end())
00574             Remove(begin());
00575 
00576         return XN_STATUS_OK;
00577     }
00578 
00582     XnBool IsEmpty() const
00583     {
00584         return (begin() == end());
00585     }
00586 
00590     XnUInt32 Size() const
00591     {
00592         XnUInt32 nSize = 0;
00593         for (Iterator iter = begin(); iter != end(); ++iter, ++nSize)
00594             ;
00595 
00596         return nSize;
00597     }
00598 
00607     XnStatus Find(const XnKey& key, ConstIterator& hiter) const
00608     {
00609         return ConstFind(key, hiter);
00610     }
00611 
00620     XnStatus Find(const XnKey& key, Iterator& hiter)
00621     {
00622         XnStatus nRetVal = XN_STATUS_OK;
00623 
00624         ConstIterator& it = hiter;
00625         nRetVal = ConstFind(key, it);
00626         XN_IS_STATUS_OK(nRetVal);
00627 
00628         return (XN_STATUS_OK);
00629     }
00630 
00634     Iterator begin()
00635     {
00636         return Iterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin());
00637     }
00638 
00642     ConstIterator begin() const
00643     {
00644         return ConstIterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin());
00645     }
00646 
00650     Iterator end()
00651     {
00652         return Iterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end());
00653     }
00654 
00658     ConstIterator end() const
00659     {
00660         return ConstIterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end());
00661     }
00662 
00670     XnStatus SetHashFunction(XnHashFunction hashFunction)
00671     {
00672         if (begin() != end())
00673         {
00674             return XN_STATUS_IS_NOT_EMPTY;
00675         }
00676         m_HashFunction = hashFunction;
00677         return XN_STATUS_OK;
00678     }
00679 
00687     XnStatus SetCompareFunction(XnCompareFunction compareFunction)
00688     {
00689         if (begin() != end())
00690         {
00691             return XN_STATUS_IS_NOT_EMPTY;
00692         }
00693         m_CompareFunction = compareFunction;
00694         return XN_STATUS_OK;
00695     }
00696 
00697 protected:
00698 
00699     XnStatus Init()
00700     {
00701         m_Bins = XN_NEW_ARR(XnList*, XN_HASH_NUM_BINS);
00702         XN_VALIDATE_ALLOC_PTR(m_Bins);
00703 
00704         for (int i = 0; i < XN_HASH_NUM_BINS; i++)
00705         {
00706             m_Bins[i] = NULL;
00707         }
00708 
00709         m_Bins[XN_HASH_LAST_BIN] = XN_NEW(XnList); // We need this for  an end() iterator
00710         m_nMinBin = XN_HASH_LAST_BIN;
00711 
00712         XN_VALIDATE_ALLOC_PTR(m_Bins[XN_HASH_LAST_BIN]);
00713         m_CompareFunction = &XnDefaultCompareFunction;
00714         m_HashFunction = &XnDefaultHashFunction;
00715         return XN_STATUS_OK;
00716     }
00717 
00727     XnStatus Find(const XnKey& key, XnHashValue hashValue, ConstIterator& hiter) const
00728     {
00729         if (m_Bins[hashValue] != NULL)
00730         {
00731             hiter = ConstIterator(this, hashValue, m_Bins[hashValue]->begin());
00732             for (XnList::ConstIterator iter = m_Bins[hashValue]->begin();
00733                 iter != m_Bins[hashValue]->end(); ++iter, ++hiter)
00734             {
00735                 if ((*m_CompareFunction)(key, hiter.Key()) == 0)
00736                     return XN_STATUS_OK;
00737             }
00738         }
00739 
00740         return XN_STATUS_NO_MATCH;
00741     }
00742 
00743 
00745     XnList** m_Bins;
00746 
00747     XnUInt16 m_nMinBin;
00748 
00749     /* Status of initialization - could be an error if memory could not be allocated. */
00750     XnStatus m_nInitStatus;
00751 
00753     XnHashFunction m_HashFunction;
00755     XnCompareFunction m_CompareFunction;
00756 
00757 private:
00758     XnStatus ConstFind(const XnKey& key, ConstIterator& hiter) const
00759     {
00760         XnHashValue HashValue = (*m_HashFunction)(key);
00761         return Find(key, HashValue, hiter);
00762     }
00763 };
00764 
00769 #define XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, ClassName, KeyTranslator)    \
00770     class decl ClassName                                                                \
00771     {                                                                                   \
00772     public:                                                                             \
00773         inline static XnHashValue Hash(KeyType const& key)                              \
00774         {                                                                               \
00775             const XnKey _key = KeyTranslator::GetAsValue(key);                          \
00776             return XnDefaultHashFunction(_key);                                         \
00777         }                                                                               \
00778         inline static XnInt32 Compare(KeyType const& key1, KeyType const& key2)     \
00779         {                                                                               \
00780             const XnKey _key1 = KeyTranslator::GetAsValue(key1);                        \
00781             const XnKey _key2 = KeyTranslator::GetAsValue(key2);                        \
00782             return XnDefaultCompareFunction(_key1, _key2);                              \
00783         }                                                                               \
00784     };
00785 
00790 #define XN_DECLARE_DEFAULT_KEY_MANAGER(KeyType, ClassName, KeyTranslator)   \
00791     XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(, KeyType, ClassName, KeyTranslator)
00792 
00798 #define XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager)   \
00799     class decl ClassName : public XnHash                                                            \
00800     {                                                                                               \
00801     public:                                                                                         \
00802         class decl ConstIterator : public XnHash::ConstIterator                                     \
00803         {                                                                                           \
00804         public:                                                                                     \
00805             friend class ClassName;                                                                 \
00806             inline ConstIterator(const ConstIterator& other) : XnHash::ConstIterator(other) {}      \
00807             inline ConstIterator& operator++()                                                      \
00808             {                                                                                       \
00809                 ++(*(XnHash::ConstIterator*)this);                                                  \
00810                 return (*this);                                                                     \
00811             }                                                                                       \
00812             inline ConstIterator operator++(int)                                                    \
00813             {                                                                                       \
00814                 ConstIterator result = *this;                                                       \
00815                 ++*this;                                                                            \
00816                 return result;                                                                      \
00817             }                                                                                       \
00818             inline ConstIterator& operator--()                                                      \
00819             {                                                                                       \
00820                 --(*(XnHash::ConstIterator*)this);                                                  \
00821                 return (*this);                                                                     \
00822             }                                                                                       \
00823             inline ConstIterator operator--(int)                                                    \
00824             {                                                                                       \
00825                 ConstIterator result = *this;                                                       \
00826                 --*this;                                                                            \
00827                 return result;                                                                      \
00828             }                                                                                       \
00829             inline KeyType const& Key() const                                                       \
00830             {                                                                                       \
00831                 return KeyTranslator::GetFromValue(XnHash::ConstIterator::Key());                   \
00832             }                                                                                       \
00833             inline ValueType const& Value() const                                                   \
00834             {                                                                                       \
00835                 return ValueTranslator::GetFromValue(XnHash::ConstIterator::Value());               \
00836             }                                                                                       \
00837         protected:                                                                                  \
00838             inline ConstIterator(const XnHash::ConstIterator& other) :                              \
00839                 XnHash::ConstIterator(other) {}                                                     \
00840         };                                                                                          \
00841         class decl Iterator : public ConstIterator                                                  \
00842         {                                                                                           \
00843         public:                                                                                     \
00844             friend class ClassName;                                                                 \
00845             inline Iterator(const Iterator& other) : ConstIterator(other) {}                        \
00846             inline Iterator& operator++()                                                           \
00847             {                                                                                       \
00848                 ++(*(ConstIterator*)this);                                                          \
00849                 return (*this);                                                                     \
00850             }                                                                                       \
00851             inline Iterator operator++(int)                                                         \
00852             {                                                                                       \
00853                 Iterator result = *this;                                                            \
00854                 ++*this;                                                                            \
00855                 return result;                                                                      \
00856             }                                                                                       \
00857             inline Iterator& operator--()                                                           \
00858             {                                                                                       \
00859                 --(*(ConstIterator*)this);                                                          \
00860                 return (*this);                                                                     \
00861             }                                                                                       \
00862             inline Iterator operator--(int)                                                         \
00863             {                                                                                       \
00864                 Iterator result = *this;                                                            \
00865                 --*this;                                                                            \
00866                 return result;                                                                      \
00867             }                                                                                       \
00868             inline KeyType& Key() const                                                             \
00869             {                                                                                       \
00870                 return (KeyType&)ConstIterator::Key();                                              \
00871             }                                                                                       \
00872             inline ValueType& Value() const                                                         \
00873             {                                                                                       \
00874                 return (ValueType&)ConstIterator::Value();                                          \
00875             }                                                                                       \
00876         protected:                                                                                  \
00877             inline Iterator(const XnHash::Iterator& other) : ConstIterator(other) {}                \
00878         };                                                                                          \
00879     public:                                                                                         \
00880         ClassName()                                                                                 \
00881         {                                                                                           \
00882             SetHashFunction(Hash);                                                                  \
00883             SetCompareFunction(Compare);                                                            \
00884         }                                                                                           \
00885         ClassName(const ClassName& other)                                                           \
00886         {                                                                                           \
00887             SetHashFunction(Hash);                                                                  \
00888             SetCompareFunction(Compare);                                                            \
00889             *this = other;                                                                          \
00890         }                                                                                           \
00891         virtual ~ClassName()                                                                        \
00892         {                                                                                           \
00893             while (!IsEmpty())                                                                      \
00894                 Remove(begin());                                                                    \
00895         }                                                                                           \
00896         ClassName& operator=(const ClassName& other)                                                \
00897         {                                                                                           \
00898             Clear();                                                                                \
00899             for (ConstIterator it = other.begin(); it != other.end(); it++)                         \
00900             {                                                                                       \
00901                 m_nInitStatus = Set(it.Key(), it.Value());                                          \
00902                 if (m_nInitStatus != XN_STATUS_OK)                                                  \
00903                 {                                                                                   \
00904                     return *this;                                                                   \
00905                 }                                                                                   \
00906             }                                                                                       \
00907             return *this;                                                                           \
00908         }                                                                                           \
00909         XnStatus Set(KeyType const& key, ValueType const& value)                                    \
00910         {                                                                                           \
00911             Iterator oldIt = begin();                                                               \
00912             if (Find(key, oldIt) == XN_STATUS_OK)                                                   \
00913             {                                                                                       \
00914                 oldIt.Value() = value;                                                              \
00915             }                                                                                       \
00916             else                                                                                    \
00917             {                                                                                       \
00918                 XnKey _key = KeyTranslator::CreateValueCopy(key);                                   \
00919                 XnValue _value = ValueTranslator::CreateValueCopy(value);                           \
00920                 XnStatus nRetVal = XnHash::Set(_key, _value);                                       \
00921                 if (nRetVal != XN_STATUS_OK)                                                        \
00922                 {                                                                                   \
00923                     KeyTranslator::FreeValue(_key);                                                 \
00924                     ValueTranslator::FreeValue(_value);                                             \
00925                     return (nRetVal);                                                               \
00926                 }                                                                                   \
00927             }                                                                                       \
00928             return XN_STATUS_OK;                                                                    \
00929         }                                                                                           \
00930         XnStatus Get(KeyType const& key, ValueType& value) const                                    \
00931         {                                                                                           \
00932             XnKey _key = KeyTranslator::GetAsValue(key);                                            \
00933             XnValue _value;                                                                         \
00934             XnStatus nRetVal = XnHash::Get(_key, _value);                                           \
00935             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                          \
00936             value = ValueTranslator::GetFromValue(_value);                                          \
00937             return XN_STATUS_OK;                                                                    \
00938         }                                                                                           \
00939         XnStatus Get(KeyType const& key, ValueType*& pValue) const                                  \
00940         {                                                                                           \
00941             XnKey _key = KeyTranslator::GetAsValue(key);                                            \
00942             XnValue _value;                                                                         \
00943             XnStatus nRetVal = XnHash::Get(_key, _value);                                           \
00944             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                          \
00945             pValue = &ValueTranslator::GetFromValue(_value);                                        \
00946             return XN_STATUS_OK;                                                                    \
00947         }                                                                                           \
00948         XnStatus Remove(KeyType const& key)                                                         \
00949         {                                                                                           \
00950             ValueType dummy;                                                                        \
00951             return Remove(key, dummy);                                                              \
00952         }                                                                                           \
00953         XnStatus Remove(KeyType const& key, ValueType& value)                                       \
00954         {                                                                                           \
00955             ConstIterator it = end();                                                               \
00956             XnStatus nRetVal = Find(key, it);                                                       \
00957             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                          \
00958             value = it.Value();                                                                     \
00959             return Remove(it);                                                                      \
00960         }                                                                                           \
00961         inline XnStatus Remove(ConstIterator iter)                                                  \
00962         {                                                                                           \
00963             XnKey key = KeyTranslator::GetAsValue(iter.Key());                                      \
00964             XnValue value = ValueTranslator::GetAsValue(iter.Value());                              \
00965             XnStatus nRetVal = XnHash::Remove(iter);                                                \
00966             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                          \
00967             KeyTranslator::FreeValue(key);                                                          \
00968             ValueTranslator::FreeValue(value);                                                      \
00969             return XN_STATUS_OK;                                                                    \
00970         }                                                                                           \
00971         XnStatus Find(KeyType const& key, ConstIterator& hiter) const                               \
00972         {                                                                                           \
00973             XnKey _key = KeyTranslator::GetAsValue(key);                                            \
00974             XnHash::ConstIterator it = XnHash::end();                                               \
00975             XnStatus nRetVal = XnHash::Find(_key, it);                                              \
00976             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                          \
00977             hiter = it;                                                                             \
00978             return XN_STATUS_OK;                                                                    \
00979         }                                                                                           \
00980         XnStatus Find(KeyType const& key, Iterator& hiter)                                          \
00981         {                                                                                           \
00982             XnKey _key = KeyTranslator::GetAsValue(key);                                            \
00983             XnHash::Iterator it = XnHash::end();                                                    \
00984             XnStatus nRetVal = XnHash::Find(_key, it);                                              \
00985             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                          \
00986             hiter = it;                                                                             \
00987             return XN_STATUS_OK;                                                                    \
00988         }                                                                                           \
00989         inline Iterator begin() { return XnHash::begin(); }                                         \
00990         inline ConstIterator begin() const { return XnHash::begin(); }                              \
00991         inline Iterator end() { return XnHash::end(); }                                             \
00992         inline ConstIterator end() const { return XnHash::end(); }                                  \
00993     protected:                                                                                      \
00994         virtual XnStatus Remove(XnHash::ConstIterator iter)                                         \
00995         {                                                                                           \
00996             return Remove(ConstIterator(iter));                                                     \
00997         }                                                                                           \
00998         inline static XnHashValue Hash(const XnKey& key)                                            \
00999         {                                                                                           \
01000             KeyType const& _key = KeyTranslator::GetFromValue(key);                                 \
01001             return KeyManager::Hash(_key);                                                          \
01002         }                                                                                           \
01003         inline static XnInt32 Compare(const XnKey& key1, const XnKey& key2)                     \
01004         {                                                                                           \
01005             KeyType const _key1 = KeyTranslator::GetFromValue(key1);                                \
01006             KeyType const _key2 = KeyTranslator::GetFromValue(key2);                                \
01007             return KeyManager::Compare(_key1, _key2);                                               \
01008         }                                                                                           \
01009     };
01010 
01015 #define XN_DECLARE_HASH(KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager)  \
01016     XN_DECLARE_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager)
01017 
01018 #define _XN_DEFAULT_KEY_MANAGER_NAME(ClassName) _##ClassName##Manager
01019 
01025 #define XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator)   \
01026     XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName), KeyTranslator)      \
01027     XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName))
01028 
01033 #define XN_DECLARE_DEFAULT_MANAGER_HASH(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator)    \
01034     XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator)
01035 
01036 #define _XN_DEFAULT_KEY_TRANSLATOR(ClassName)   _##ClassName##KeyTranslator
01037 #define _XN_DEFAULT_VALUE_TRANSLATOR(ClassName) _##ClassName##ValueTranslator
01038 
01044 #define XN_DECLARE_DEFAULT_HASH_DECL(decl, KeyType, ValueType, ClassName)                                           \
01045     XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, KeyType, _XN_DEFAULT_KEY_TRANSLATOR(ClassName))                  \
01046     XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, ValueType, _XN_DEFAULT_VALUE_TRANSLATOR(ClassName))              \
01047     XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, _XN_DEFAULT_KEY_TRANSLATOR(ClassName), _XN_DEFAULT_VALUE_TRANSLATOR(ClassName))
01048 
01053 #define XN_DECLARE_DEFAULT_HASH(KeyType, ValueType, ClassName)      \
01054     XN_DECLARE_DEFAULT_HASH_DECL(, KeyType, ValueType, ClassName)
01055 
01056 #endif // _XN_HASH_H

Generated on Sat Nov 10 2012 07:13:52 for OpenNI 1.3.2 by  doxygen 1.7.1