summaryrefslogtreecommitdiffstats
path: root/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHash.h
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHash.h')
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHash.h1014
1 files changed, 1014 insertions, 0 deletions
diff --git a/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHash.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHash.h
new file mode 100644
index 00000000..7cc719f2
--- /dev/null
+++ b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHash.h
@@ -0,0 +1,1014 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_HASH_H
+#define _XN_HASH_H
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnList.h"
+
+//---------------------------------------------------------------------------
+// Defines
+//---------------------------------------------------------------------------
+#define XN_HASH_LAST_BIN 256
+#define XN_HASH_NUM_BINS (XN_HASH_LAST_BIN + 1)
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+/**
+* The key to the hash
+*/
+typedef XnValue XnKey;
+
+/**
+* The hash value - the output of the hash function
+*/
+typedef XnUInt8 XnHashValue;
+
+/**
+* Default Hash function
+*/
+static XnHashValue XnDefaultHashFunction(const XnKey& key)
+{
+ return (XnSizeT(key) & 0xff);
+}
+
+/**
+* Default Compare function
+*/
+static XnInt32 XnDefaultCompareFunction(const XnKey& key1, const XnKey& key2)
+{
+ return XnInt32(XnSizeT(key1)-XnSizeT(key2));
+}
+
+/**
+ * The hash - associative array
+ */
+class XnHash
+{
+public:
+ /**
+ * Iterator to the XnHash
+ */
+ class ConstIterator
+ {
+ public:
+ friend class XnHash;
+
+ /**
+ * Copy constructor
+ *
+ * @param other [in] instance to copy from
+ */
+ ConstIterator(const ConstIterator& other) :
+ m_pHash(other.m_pHash), m_nCurrentBin(other.m_nCurrentBin), m_Iterator(other.m_Iterator) {}
+
+ /**
+ * Support ++iterator, go to the next object in the hash
+ */
+ ConstIterator& operator++()
+ {
+ ++m_Iterator;
+
+ while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
+ m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
+ {
+ do
+ {
+ m_nCurrentBin++;
+ } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
+ m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin();
+ }
+ return *this;
+ }
+
+ /**
+ * Support iterator++, go to the next object in the hash, returning the old value
+ */
+ ConstIterator operator++(int)
+ {
+ XnHash::ConstIterator other(*this);
+ ++*this;
+ return other;
+ }
+
+ /**
+ * Support --iterator, go to the previous object in the hash
+ */
+ ConstIterator& operator--()
+ {
+ --m_Iterator;
+
+ while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
+ m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
+ {
+ do
+ {
+ if (m_nCurrentBin == 0)
+ {
+ m_nCurrentBin = XN_HASH_LAST_BIN;
+ m_Iterator = m_pHash->m_Bins[XN_HASH_LAST_BIN]->end();
+ return *this;
+ }
+ m_nCurrentBin--;
+ } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
+ m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->rbegin();
+ }
+ return *this;
+ }
+
+ /**
+ * Support iterator--, go to the previous object in the hash, returning the old value
+ */
+ ConstIterator operator--(int)
+ {
+ ConstIterator other(*this);
+ --*this;
+ return other;
+ }
+
+ /**
+ * Operator to check if 2 iterators point to the same object
+ *
+ * @param other [in] instance to compare with
+ */
+ XnBool operator==(const ConstIterator& other) const
+ {
+ return m_Iterator == other.m_Iterator;
+ }
+
+ /**
+ * Operator to check if 2 iterators point to different objects
+ *
+ * @param other [in] instance to compare with
+ */
+ XnBool operator!=(const ConstIterator& other) const
+ {
+ return m_Iterator != other.m_Iterator;
+ }
+
+ /**
+ * Get the key of the current object (const version)
+ */
+ const XnKey& Key() const
+ {
+ return ((XnNode*)(*m_Iterator))->Data();
+ }
+
+ /**
+ * Get the value of the current object (const version)
+ */
+ const XnValue& Value() const
+ {
+ return ((XnNode*)(*m_Iterator))->Next()->Data();
+ }
+
+ /**
+ * Get the entire current object (non-const version)
+ */
+ XnNode* GetNode()
+ {
+ return m_Iterator.GetNode();
+ }
+
+ /**
+ * Get the entire current object (const version)
+ */
+ const XnNode* GetNode() const
+ {
+ return m_Iterator.GetNode();
+ }
+
+ protected:
+ /**
+ * constructor to be used from inside the XnHash
+ *
+ * @param pHash [in] The hash to which the iterator belongs
+ * @param nBin [in] The bin of the current object
+ * @param listIterator [in] Iterator on the bin (each bin is a XnList)
+ */
+ ConstIterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) :
+ m_pHash(pHash), m_nCurrentBin(nBin), m_Iterator(listIterator)
+ {
+ // Find the first valid
+ while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
+ m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
+ {
+ do
+ {
+ m_nCurrentBin++;
+ } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
+ m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin();
+ }
+ }
+
+ /**
+ * constructor to be used from inside the XnHash. It points to the first value in the hash.
+ *
+ * @param pHash [in] The hash to which the iterator belongs
+ */
+ ConstIterator(const XnHash* pHash) :
+ m_pHash(pHash), m_nCurrentBin(0), m_Iterator(m_pHash->m_Bins[XN_HASH_LAST_BIN]->end()) {}
+
+ /** The hash to which the iterator belongs */
+ const XnHash* m_pHash;
+ /** The bin of the current object */
+ XnUInt16 m_nCurrentBin;
+ /** Iterator for the specific bin */
+ XnList::Iterator m_Iterator;
+ };
+
+ /**
+ * Iterator to the XnHash
+ */
+ class Iterator : public ConstIterator
+ {
+ public:
+ friend class XnHash;
+
+ /**
+ * Copy constructor
+ *
+ * @param other [in] instance to copy from
+ */
+ inline Iterator(const Iterator& other) : ConstIterator(other) {}
+
+ /**
+ * Support ++iterator, go to the next object in the list
+ */
+ inline Iterator& operator++()
+ {
+ ++(*(ConstIterator*)this);
+ return (*this);
+ }
+ /**
+ * Support iterator++, go to the next object in the list, returning the old value
+ */
+ inline Iterator operator++(int)
+ {
+ Iterator result = *this;
+ ++*this;
+ return (result);
+ }
+
+ /**
+ * Support --iterator, go to the next object in the list
+ */
+ inline Iterator& operator--()
+ {
+ --(*(ConstIterator*)this);
+ return (*this);
+ }
+ /**
+ * Support iterator--, go to the next object in the list, returning the old value
+ */
+ inline Iterator operator--(int)
+ {
+ Iterator result = *this;
+ --*this;
+ return (result);
+ }
+
+ /**
+ * Get the key of the current object (const version)
+ */
+ XnKey& Key() const { return (XnKey&)ConstIterator::Key(); }
+
+ /**
+ * Get the value of the current object (const version)
+ */
+ XnValue& Value() const { return (XnValue&)ConstIterator::Value(); }
+
+ protected:
+ /**
+ * constructor to be used from inside the XnHash
+ *
+ * @param pHash [in] The hash to which the iterator belongs
+ * @param nBin [in] The bin of the current object
+ * @param listIterator [in] Iterator on the bin (each bin is a XnList)
+ */
+ Iterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) :
+ ConstIterator(pHash, nBin, listIterator)
+ {}
+
+ /**
+ * constructor to be used from inside the XnHash. It points to the first value in the hash.
+ *
+ * @param pHash [in] The hash to which the iterator belongs
+ */
+ Iterator(const XnHash* pHash) : ConstIterator(pHash) {}
+
+ Iterator(const ConstIterator& other) : ConstIterator(other) {}
+ };
+
+ friend class ConstIterator;
+
+public:
+ /**
+ * Definition of a hash function - receive key, and outputs HashValue
+ */
+ typedef XnHashValue (*XnHashFunction)(const XnKey& key);
+ /**
+ * Definition of comparison function - receives 2 keys, returns 0 on equality
+ */
+ typedef XnInt32 (*XnCompareFunction)(const XnKey& key1, const XnKey& key2);
+
+ /**
+ * Constructor. Initializes internal representations.
+ */
+ XnHash()
+ {
+ m_nInitStatus = Init();
+ }
+
+ /**
+ * Destructor. Destroys internal representations.
+ */
+ virtual ~XnHash()
+ {
+ if (m_Bins != NULL)
+ {
+ for (int i = 0; i < XN_HASH_NUM_BINS; ++i)
+ {
+ XN_DELETE(m_Bins[i]);
+ }
+ XN_DELETE_ARR(m_Bins);
+ }
+ }
+
+ /**
+ * Returns the status of the initialization of the hash.
+ * @returns XN_STATUS_OK if the hash was initialized successfully, or an error code otherwise
+ * (e.g. if memory could not be allocated).
+ */
+ XnStatus GetInitStatus() const
+ {
+ return m_nInitStatus;
+ }
+
+ /**
+ * Set a new key-value entry. If key exists, will replace value.
+ *
+ * @param key [in] The key to which to associate the value
+ * @param value [in] The value to add to the XnHash
+ */
+ XnStatus Set(const XnKey& key, const XnValue& value)
+ {
+ XnHashValue HashValue = (*m_HashFunction)(key);
+
+ // Check if key already exists
+ if (m_Bins[HashValue] != NULL)
+ {
+ Iterator hiter(this);
+ if (Find(key, HashValue, hiter) == XN_STATUS_OK)
+ {
+ // Replace value
+ hiter.Value() = value;
+ return XN_STATUS_OK;
+ }
+ }
+ else
+ {
+ // First time trying to access this bin, create it.
+ m_Bins[HashValue] = XN_NEW(XnList);
+ if (m_Bins[HashValue] == NULL)
+ {
+ return XN_STATUS_ALLOC_FAILED;
+ }
+ if (HashValue < m_nMinBin)
+ m_nMinBin = HashValue;
+ }
+
+ // Get a new node for the key
+ XnNode* pKeyNode = XnNode::Allocate();
+ if (pKeyNode == NULL)
+ {
+ return XN_STATUS_ALLOC_FAILED;
+ }
+ pKeyNode->Data() = key;
+
+ // Get a new node for the value
+ XnNode* pValueNode = XnNode::Allocate();
+ if (pValueNode == NULL)
+ {
+ XnNode::Deallocate(pKeyNode);
+ return XN_STATUS_ALLOC_FAILED;
+ }
+ pValueNode->Data() = value;
+
+ // Concatenate the value node to the key node
+ pKeyNode->Next() = pValueNode;
+ pValueNode->Next() = NULL;
+
+ // Add the 2 nodes as the value to the key's list
+ XnStatus ListStatus = m_Bins[HashValue]->AddLast(XnValue(pKeyNode));
+ if (ListStatus != XN_STATUS_OK)
+ {
+ // Add failed. return the 2 nodes to the pool
+ XnNode::Deallocate(pKeyNode);
+ XnNode::Deallocate(pValueNode);
+ return ListStatus;
+ }
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Get the value associated with the supplied key
+ *
+ * @param key [in] The key of the entry
+ * @param value [out] The retrieved value
+ *
+ * @return XN_STATUS_NO_MATCH if no such key exists
+ */
+ XnStatus Get(const XnKey& key, XnValue& value) const
+ {
+ // Check if key exists
+ Iterator hiter(this);
+ XnStatus FindStatus = Find(key, hiter);
+ if (FindStatus != XN_STATUS_OK)
+ {
+ // Key doesn't exist!
+ return FindStatus;
+ }
+ value = hiter.Value();
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Remove a key-value entry from the XnHash
+ *
+ * @param key [in] The key of the entry
+ * @param value [out] The value that was in the removed entry
+
+ * @return XN_STATUS_NO_MATCH if no such key exists
+ */
+ XnStatus Remove(const XnKey& key, XnValue& value)
+ {
+ // find the entry to which the key belongs
+ Iterator hiter(this);
+
+ XnStatus FindStatus = Find(key, hiter);
+ if (FindStatus != XN_STATUS_OK)
+ {
+ // no such entry!
+ return FindStatus;
+ }
+
+ // Remove by iterator
+ value = hiter.Value();
+ return Remove(hiter);
+ }
+
+ /**
+ * Remove an entry from the XnHash by iterator
+ *
+ * @param iter [in] Iterator pointing to an entry in the hash
+ * @param key [out] The key that was in the removed entry
+ * @param value [out] The value that was in the removed entry
+ *
+ * @return XN_STATUS_ILLEGAL_POSITION if iterator is invalid
+ */
+ XnStatus Remove(ConstIterator iter, XnKey& key, XnValue& value)
+ {
+ if (iter == end())
+ {
+ // Can't remove invalid node
+ return XN_STATUS_ILLEGAL_POSITION;
+ }
+
+ // Get value and key, to return to the caller
+ value = iter.Value();
+ key = iter.Key();
+
+ return Remove(iter);
+ }
+
+ /**
+ * Remove an entry from the XnHash by iterator
+ *
+ * @param iter [in] Iterator pointing to an entry in the hash
+ *
+ * @return XN_STATUS_ILLEGAL_POSITION if iterator is invalid
+ */
+ virtual XnStatus Remove(ConstIterator iter)
+ {
+ if (iter == end())
+ {
+ // Can't remove invalid node
+ return XN_STATUS_ILLEGAL_POSITION;
+ }
+
+ XnNode* pNode = iter.GetNode();
+
+ XnNode* pKeyNode = (XnNode*)(pNode->Data());
+ XnNode* pValueNode = pKeyNode->Next();
+
+ // Return the nodes to the pool
+ XnNode::Deallocate(pKeyNode);
+ XnNode::Deallocate(pValueNode);
+
+ pNode->Previous()->Next() = pNode->Next();
+ pNode->Next()->Previous() = pNode->Previous();
+
+ XnNode::Deallocate(pNode);
+
+ return XN_STATUS_OK;
+ }
+
+
+ /**
+ * Remove all entries from the XnHash.
+ */
+ XnStatus Clear()
+ {
+ while (begin() != end())
+ Remove(begin());
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Checks if hash is empty.
+ */
+ XnBool IsEmpty() const
+ {
+ return (begin() == end());
+ }
+
+ /**
+ * Gets the number of entries in the hash.
+ */
+ XnUInt32 Size() const
+ {
+ XnUInt32 nSize = 0;
+ for (Iterator iter = begin(); iter != end(); ++iter, ++nSize)
+ ;
+
+ return nSize;
+ }
+
+ /**
+ * Get an iterator pointing to the entry to which the key belongs
+ *
+ * @param key [in] The key of the entry
+ * @param hiter [out] Iterator to the entry described by key
+ *
+ * @return XN_STATUS_NO_MATCH No such key in the XnHash
+ */
+ XnStatus Find(const XnKey& key, ConstIterator& hiter) const
+ {
+ return ConstFind(key, hiter);
+ }
+
+ /**
+ * Get an iterator pointing to the entry to which the key belongs
+ *
+ * @param key [in] The key of the entry
+ * @param hiter [out] Iterator to the entry described by key
+ *
+ * @return XN_STATUS_NO_MATCH No such key in the XnHash
+ */
+ XnStatus Find(const XnKey& key, Iterator& hiter)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ ConstIterator& it = hiter;
+ nRetVal = ConstFind(key, it);
+ XN_IS_STATUS_OK(nRetVal);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * Get an iterator to the beginning of the XnHash (non-const version)
+ */
+ Iterator begin()
+ {
+ return Iterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin());
+ }
+
+ /**
+ * Get an iterator to the beginning of the XnHash (const version)
+ */
+ ConstIterator begin() const
+ {
+ return ConstIterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin());
+ }
+
+ /**
+ * Get an iterator to the end of the XnHash (position is invalid) (non-const version)
+ */
+ Iterator end()
+ {
+ return Iterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end());
+ }
+
+ /**
+ * Get an iterator to the end of the XnHash (position is invalid) (const version)
+ */
+ ConstIterator end() const
+ {
+ return ConstIterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end());
+ }
+
+ /**
+ * Change the hash function. The XnHash must be empty for this to succeed.
+ *
+ * @param hashFunction [in] The new hash function
+ *
+ * @return XN_STATUS_IS_NOT_EMPTY if the XnHash isn't empty
+ */
+ XnStatus SetHashFunction(XnHashFunction hashFunction)
+ {
+ if (begin() != end())
+ {
+ return XN_STATUS_IS_NOT_EMPTY;
+ }
+ m_HashFunction = hashFunction;
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Change the comparison function. The XnHash must be empty for this to succeed.
+ *
+ * @param compareFunction [in] The new hash function
+ *
+ * @return XN_STATUS_IS_NOT_EMPTY if the XnHash isn't empty
+ */
+ XnStatus SetCompareFunction(XnCompareFunction compareFunction)
+ {
+ if (begin() != end())
+ {
+ return XN_STATUS_IS_NOT_EMPTY;
+ }
+ m_CompareFunction = compareFunction;
+ return XN_STATUS_OK;
+ }
+
+protected:
+
+ XnStatus Init()
+ {
+ m_Bins = XN_NEW_ARR(XnList*, XN_HASH_NUM_BINS);
+ XN_VALIDATE_ALLOC_PTR(m_Bins);
+
+ for (int i = 0; i < XN_HASH_NUM_BINS; i++)
+ {
+ m_Bins[i] = NULL;
+ }
+
+ m_Bins[XN_HASH_LAST_BIN] = XN_NEW(XnList); // We need this for an end() iterator
+ m_nMinBin = XN_HASH_LAST_BIN;
+
+ XN_VALIDATE_ALLOC_PTR(m_Bins[XN_HASH_LAST_BIN]);
+ m_CompareFunction = &XnDefaultCompareFunction;
+ m_HashFunction = &XnDefaultHashFunction;
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Get an iterator pointing to the entry to which the key belongs
+ *
+ * @param key [in] The key of the entry
+ * @param hashValue [in] The hash value of the key
+ * @param hiter [out] Iterator to the entry described by key
+ *
+ * @return XN_STATUS_NO_MATCH No such key in the XnHash
+ */
+ XnStatus Find(const XnKey& key, XnHashValue hashValue, ConstIterator& hiter) const
+ {
+ if (m_Bins[hashValue] != NULL)
+ {
+ hiter = ConstIterator(this, hashValue, m_Bins[hashValue]->begin());
+ for (XnList::ConstIterator iter = m_Bins[hashValue]->begin();
+ iter != m_Bins[hashValue]->end(); ++iter, ++hiter)
+ {
+ if ((*m_CompareFunction)(key, hiter.Key()) == 0)
+ return XN_STATUS_OK;
+ }
+ }
+
+ return XN_STATUS_NO_MATCH;
+ }
+
+
+ /** Each bin is a XnList */
+ XnList** m_Bins;
+
+ XnUInt16 m_nMinBin;
+
+ /* Status of initialization - could be an error if memory could not be allocated. */
+ XnStatus m_nInitStatus;
+
+ /** The current hash function */
+ XnHashFunction m_HashFunction;
+ /** The current comparison function */
+ XnCompareFunction m_CompareFunction;
+
+private:
+ XN_DISABLE_COPY_AND_ASSIGN(XnHash);
+
+ XnStatus ConstFind(const XnKey& key, ConstIterator& hiter) const
+ {
+ XnHashValue HashValue = (*m_HashFunction)(key);
+ return Find(key, HashValue, hiter);
+ }
+};
+
+/**
+* Declares a default Key Manager for type @a KeyType. It is given the name @a ClassName.
+* The manager uses the translator @a KeyTranslator, and is declared using the @a decl declspec.
+*/
+#define XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, ClassName, KeyTranslator) \
+ class decl ClassName \
+ { \
+ public: \
+ inline static XnHashValue Hash(KeyType const& key) \
+ { \
+ const XnKey _key = KeyTranslator::GetAsValue(key); \
+ return XnDefaultHashFunction(_key); \
+ } \
+ inline static XnInt32 Compare(KeyType const& key1, KeyType const& key2) \
+ { \
+ const XnKey _key1 = KeyTranslator::GetAsValue(key1); \
+ const XnKey _key2 = KeyTranslator::GetAsValue(key2); \
+ return XnDefaultCompareFunction(_key1, _key2); \
+ } \
+ };
+
+/**
+* Declares a default Key Manager for type @a KeyType. It is given the name @a ClassName.
+* The manager uses the translator @a KeyTranslator.
+*/
+#define XN_DECLARE_DEFAULT_KEY_MANAGER(KeyType, ClassName, KeyTranslator) \
+ XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(, KeyType, ClassName, KeyTranslator)
+
+/**
+* Declares a hash table from @a KeyType to @a ValueType named @a ClassName. The hash table uses
+* @a KeyTranslator and @a ValueTranslator for storing keys and values, and @a KeyManager for managing the keys.
+* It is declared using the @a decl declspec.
+*/
+#define XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) \
+ class decl ClassName : public XnHash \
+ { \
+ public: \
+ class decl ConstIterator : public XnHash::ConstIterator \
+ { \
+ public: \
+ friend class ClassName; \
+ inline ConstIterator(const ConstIterator& other) : XnHash::ConstIterator(other) {} \
+ inline ConstIterator& operator++() \
+ { \
+ ++(*(XnHash::ConstIterator*)this); \
+ return (*this); \
+ } \
+ inline ConstIterator operator++(int) \
+ { \
+ ConstIterator result = *this; \
+ ++*this; \
+ return result; \
+ } \
+ inline ConstIterator& operator--() \
+ { \
+ --(*(XnHash::ConstIterator*)this); \
+ return (*this); \
+ } \
+ inline ConstIterator operator--(int) \
+ { \
+ ConstIterator result = *this; \
+ --*this; \
+ return result; \
+ } \
+ inline KeyType const& Key() const \
+ { \
+ return KeyTranslator::GetFromValue(XnHash::ConstIterator::Key()); \
+ } \
+ inline ValueType const& Value() const \
+ { \
+ return ValueTranslator::GetFromValue(XnHash::ConstIterator::Value()); \
+ } \
+ protected: \
+ inline ConstIterator(const XnHash::ConstIterator& other) : \
+ XnHash::ConstIterator(other) {} \
+ }; \
+ class decl Iterator : public ConstIterator \
+ { \
+ public: \
+ friend class ClassName; \
+ inline Iterator(const Iterator& other) : ConstIterator(other) {} \
+ inline Iterator& operator++() \
+ { \
+ ++(*(ConstIterator*)this); \
+ return (*this); \
+ } \
+ inline Iterator operator++(int) \
+ { \
+ Iterator result = *this; \
+ ++*this; \
+ return result; \
+ } \
+ inline Iterator& operator--() \
+ { \
+ --(*(ConstIterator*)this); \
+ return (*this); \
+ } \
+ inline Iterator operator--(int) \
+ { \
+ Iterator result = *this; \
+ --*this; \
+ return result; \
+ } \
+ inline KeyType& Key() const \
+ { \
+ return (KeyType&)ConstIterator::Key(); \
+ } \
+ inline ValueType& Value() const \
+ { \
+ return (ValueType&)ConstIterator::Value(); \
+ } \
+ protected: \
+ inline Iterator(const XnHash::Iterator& other) : ConstIterator(other) {} \
+ }; \
+ public: \
+ ClassName() \
+ { \
+ SetHashFunction(Hash); \
+ SetCompareFunction(Compare); \
+ } \
+ virtual ~ClassName() \
+ { \
+ while (!IsEmpty()) \
+ Remove(begin()); \
+ } \
+ XnStatus Set(KeyType const& key, ValueType const& value) \
+ { \
+ Iterator oldIt = begin(); \
+ if (Find(key, oldIt) == XN_STATUS_OK) \
+ { \
+ oldIt.Value() = value; \
+ } \
+ else \
+ { \
+ XnKey _key = KeyTranslator::CreateValueCopy(key); \
+ XnValue _value = ValueTranslator::CreateValueCopy(value); \
+ XnStatus nRetVal = XnHash::Set(_key, _value); \
+ if (nRetVal != XN_STATUS_OK) \
+ { \
+ KeyTranslator::FreeValue(_key); \
+ ValueTranslator::FreeValue(_value); \
+ return (nRetVal); \
+ } \
+ } \
+ return XN_STATUS_OK; \
+ } \
+ XnStatus Get(KeyType const& key, ValueType& value) const \
+ { \
+ XnKey _key = KeyTranslator::GetAsValue(key); \
+ XnValue _value; \
+ XnStatus nRetVal = XnHash::Get(_key, _value); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ value = ValueTranslator::GetFromValue(_value); \
+ return XN_STATUS_OK; \
+ } \
+ XnStatus Get(KeyType const& key, ValueType*& pValue) const \
+ { \
+ XnKey _key = KeyTranslator::GetAsValue(key); \
+ XnValue _value; \
+ XnStatus nRetVal = XnHash::Get(_key, _value); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ pValue = &ValueTranslator::GetFromValue(_value); \
+ return XN_STATUS_OK; \
+ } \
+ XnStatus Remove(KeyType const& key) \
+ { \
+ ValueType dummy; \
+ return Remove(key, dummy); \
+ } \
+ XnStatus Remove(KeyType const& key, ValueType& value) \
+ { \
+ ConstIterator it = end(); \
+ XnStatus nRetVal = Find(key, it); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ value = it.Value(); \
+ return Remove(it); \
+ } \
+ inline XnStatus Remove(ConstIterator iter) \
+ { \
+ XnKey key = KeyTranslator::GetAsValue(iter.Key()); \
+ XnValue value = ValueTranslator::GetAsValue(iter.Value()); \
+ XnStatus nRetVal = XnHash::Remove(iter); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ KeyTranslator::FreeValue(key); \
+ ValueTranslator::FreeValue(value); \
+ return XN_STATUS_OK; \
+ } \
+ XnStatus Find(KeyType const& key, ConstIterator& hiter) const \
+ { \
+ XnKey _key = KeyTranslator::GetAsValue(key); \
+ XnHash::ConstIterator it = XnHash::end(); \
+ XnStatus nRetVal = XnHash::Find(_key, it); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ hiter = it; \
+ return XN_STATUS_OK; \
+ } \
+ XnStatus Find(KeyType const& key, Iterator& hiter) \
+ { \
+ XnKey _key = KeyTranslator::GetAsValue(key); \
+ XnHash::Iterator it = XnHash::end(); \
+ XnStatus nRetVal = XnHash::Find(_key, it); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ hiter = it; \
+ return XN_STATUS_OK; \
+ } \
+ inline Iterator begin() { return XnHash::begin(); } \
+ inline ConstIterator begin() const { return XnHash::begin(); } \
+ inline Iterator end() { return XnHash::end(); } \
+ inline ConstIterator end() const { return XnHash::end(); } \
+ protected: \
+ virtual XnStatus Remove(XnHash::ConstIterator iter) \
+ { \
+ return Remove(ConstIterator(iter)); \
+ } \
+ inline static XnHashValue Hash(const XnKey& key) \
+ { \
+ KeyType const& _key = KeyTranslator::GetFromValue(key); \
+ return KeyManager::Hash(_key); \
+ } \
+ inline static XnInt32 Compare(const XnKey& key1, const XnKey& key2) \
+ { \
+ KeyType const _key1 = KeyTranslator::GetFromValue(key1); \
+ KeyType const _key2 = KeyTranslator::GetFromValue(key2); \
+ return KeyManager::Compare(_key1, _key2); \
+ } \
+ private: \
+ XN_DISABLE_COPY_AND_ASSIGN(ClassName); \
+ };
+
+/**
+* Declares a hash table from @a KeyType to @a ValueType named @a ClassName. The hash table uses
+* @a KeyTranslator and @a ValueTranslator for storing keys and values, and @a KeyManager for managing the keys.
+*/
+#define XN_DECLARE_HASH(KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) \
+ XN_DECLARE_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager)
+
+#define _XN_DEFAULT_KEY_MANAGER_NAME(ClassName) _##ClassName##Manager
+
+/**
+* Declares a hash table from @a KeyType to @a ValueType named @a ClassName. The hash table uses
+* @a KeyTranslator and @a ValueTranslator for storing keys and values. It declares and uses a default manager.
+* It is declared using the @a decl declspec.
+*/
+#define XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) \
+ XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName), KeyTranslator) \
+ XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName))
+
+/**
+* Declares a hash table from @a KeyType to @a ValueType named @a ClassName. The hash table uses
+* @a KeyTranslator and @a ValueTranslator for storing keys and values. It declares and uses a default manager.
+*/
+#define XN_DECLARE_DEFAULT_MANAGER_HASH(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) \
+ XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator)
+
+#define _XN_DEFAULT_KEY_TRANSLATOR(ClassName) _##ClassName##KeyTranslator
+#define _XN_DEFAULT_VALUE_TRANSLATOR(ClassName) _##ClassName##ValueTranslator
+
+/**
+* Declares a hash table from @a KeyType to @a ValueType named @a ClassName. The hash table uses
+* default translators for storing keys and values. It declares and uses a default manager.
+* It is declared using the @a decl declspec.
+*/
+#define XN_DECLARE_DEFAULT_HASH_DECL(decl, KeyType, ValueType, ClassName) \
+ XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, KeyType, _XN_DEFAULT_KEY_TRANSLATOR(ClassName)) \
+ XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, ValueType, _XN_DEFAULT_VALUE_TRANSLATOR(ClassName)) \
+ XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, _XN_DEFAULT_KEY_TRANSLATOR(ClassName), _XN_DEFAULT_VALUE_TRANSLATOR(ClassName))
+
+/**
+* Declares a hash table from @a KeyType to @a ValueType named @a ClassName. The hash table uses
+* default translators for storing keys and values. It declares and uses a default manager.
+*/
+#define XN_DECLARE_DEFAULT_HASH(KeyType, ValueType, ClassName) \
+ XN_DECLARE_DEFAULT_HASH_DECL(, KeyType, ValueType, ClassName)
+
+#endif // _XN_HASH_H