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


nao_openni
Author(s): Bener SUAY
autogenerated on Mon Jan 6 2014 11:27:51