aboutsummaryrefslogtreecommitdiff
path: root/APEX_1.4/shared/general/HACD/include/dgTree.h
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /APEX_1.4/shared/general/HACD/include/dgTree.h
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'APEX_1.4/shared/general/HACD/include/dgTree.h')
-rw-r--r--APEX_1.4/shared/general/HACD/include/dgTree.h814
1 files changed, 814 insertions, 0 deletions
diff --git a/APEX_1.4/shared/general/HACD/include/dgTree.h b/APEX_1.4/shared/general/HACD/include/dgTree.h
new file mode 100644
index 00000000..234a2fbf
--- /dev/null
+++ b/APEX_1.4/shared/general/HACD/include/dgTree.h
@@ -0,0 +1,814 @@
+/* Copyright (c) <2003-2011> <Julio Jerez, Newton Game Dynamics>
+*
+* This software is provided 'as-is', without any express or implied
+* warranty. In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef __dgTree__
+#define __dgTree__
+
+#include "dgTypes.h"
+
+// Note: this is a low level class for dgTree use only
+// unpredictable result will happen if you attempt to manipulate
+// any member of this class
+class dgRedBackNode : public UANS::UserAllocated
+{
+ public:
+ enum REDBLACK_COLOR
+ {
+ RED = true,
+ BLACK = false
+ };
+
+ dgRedBackNode()
+ {
+ }
+
+ virtual ~dgRedBackNode ()
+ {
+ }
+
+ void RemoveAllLow ();
+ void RotateLeft(dgRedBackNode** const head);
+ void RotateRight(dgRedBackNode** const head);
+ void RemoveFixup (dgRedBackNode* const node, dgRedBackNode* * const head);
+
+ dgRedBackNode* GetLeft() const;
+ dgRedBackNode* GetRight() const;
+ dgRedBackNode* GetParent() const;
+
+ dgRedBackNode (dgRedBackNode* const parent);
+ inline void Initdata (dgRedBackNode* const parent);
+ inline void SetColor (REDBLACK_COLOR color);
+ REDBLACK_COLOR GetColor () const;
+ uint32_t IsInTree () const;
+ inline void SetInTreeFlag (uint32_t flag);
+
+ void RemoveAll ();
+ dgRedBackNode* Prev() const;
+ dgRedBackNode* Next() const;
+ dgRedBackNode* Minimum() const;
+ dgRedBackNode* Maximum() const;
+ void Remove (dgRedBackNode** const head);
+ void Unlink (dgRedBackNode** const head);
+ void InsertFixup(dgRedBackNode** const head);
+
+ dgRedBackNode* m_left;
+ dgRedBackNode* m_right;
+ dgRedBackNode* m_parent;
+ uint32_t m_color : 1;
+ uint32_t m_inTree : 1;
+// uint32_t m_pad[2];
+};
+
+template<class OBJECT, class KEY>
+class dgTree
+{
+ public:
+ class dgTreeNode: public dgRedBackNode
+ {
+ dgTreeNode (
+ const OBJECT &info,
+ const KEY &key,
+ dgTreeNode* parentNode)
+ :dgRedBackNode(parentNode), m_info (info), m_key (key)
+ {
+// HACD_ASSERT ((uint64_t (&m_info) & 0x0f) == 0);
+ }
+
+ ~dgTreeNode ()
+ {
+ }
+
+ dgTreeNode* GetLeft () const
+ {
+ return (dgTreeNode* )dgRedBackNode::m_left;
+ }
+
+ dgTreeNode* GetRight () const
+ {
+ return (dgTreeNode* )dgRedBackNode::m_right;
+ }
+
+ dgTreeNode* GetParent ()
+ {
+ return (dgTreeNode* )dgRedBackNode::m_parent;
+ }
+
+ void SetLeft (dgTreeNode* const node)
+ {
+ dgRedBackNode::m_left = node;
+ }
+
+ void SetRight (dgTreeNode* const node)
+ {
+ dgRedBackNode::m_right = node;
+ }
+
+ void SetParent (dgTreeNode* const node)
+ {
+ dgRedBackNode::m_parent = node;
+ }
+
+ public:
+ const KEY& GetKey() const
+ {
+ return m_key;
+ }
+
+ OBJECT& GetInfo()
+ {
+ return m_info;
+ }
+
+ private:
+ OBJECT m_info;
+ KEY m_key;
+ friend class dgTree<OBJECT, KEY>;
+
+ };
+
+ class Iterator
+ {
+
+ public:
+ Iterator(const dgTree<OBJECT,KEY> &me)
+ {
+ m_ptr = NULL;
+ m_tree = &me;
+ }
+
+ ~Iterator()
+ {
+ }
+
+ void Begin()
+ {
+ m_ptr = m_tree->Minimum();
+ }
+
+ void End()
+ {
+ m_ptr = m_tree->Maximum();
+ }
+
+ void Set (dgTreeNode* const node)
+ {
+ m_ptr = node;
+ }
+
+ operator int32_t() const
+ {
+ return m_ptr != NULL;
+ }
+
+ void operator++ ()
+ {
+ HACD_ASSERT (m_ptr);
+ m_ptr = m_ptr->Next();
+ }
+
+ void operator++ (int32_t)
+ {
+ HACD_ASSERT (m_ptr);
+ m_ptr = m_ptr->Next();
+ }
+
+ void operator-- ()
+ {
+ HACD_ASSERT (m_ptr);
+ m_ptr = m_ptr->Prev();
+ }
+
+ void operator-- (int32_t)
+ {
+ HACD_ASSERT (m_ptr);
+ m_ptr = m_ptr->Prev();
+ }
+
+ OBJECT &operator* () const
+ {
+ return ((dgTreeNode*)m_ptr)->GetInfo();
+ }
+
+ dgTreeNode* GetNode() const
+ {
+ return (dgTreeNode*)m_ptr;
+ }
+
+ KEY GetKey () const
+ {
+ dgTreeNode* const tmp = (dgTreeNode*)m_ptr;
+ return tmp ? tmp->GetKey() : KEY(0);
+ }
+
+ private:
+ dgRedBackNode* m_ptr;
+ const dgTree* m_tree;
+
+ };
+
+
+ // ***********************************************************
+ // member functions
+ // ***********************************************************
+ public:
+
+// dgTree ();
+ dgTree (void);
+ virtual ~dgTree ();
+
+
+ operator int32_t() const;
+ int32_t GetCount() const;
+
+ dgTreeNode* GetRoot () const;
+ dgTreeNode* Minimum () const;
+ dgTreeNode* Maximum () const;
+
+ dgTreeNode* Find (KEY key) const;
+ dgTreeNode* FindGreater (KEY key) const;
+ dgTreeNode* FindGreaterEqual (KEY key) const;
+ dgTreeNode* FindLessEqual (KEY key) const;
+
+ dgTreeNode* GetNodeFromInfo (OBJECT &info) const;
+
+ dgTreeNode* Insert (const OBJECT &element, KEY key, bool& elementWasInTree);
+ dgTreeNode* Insert (const OBJECT &element, KEY key);
+ dgTreeNode* Insert (dgTreeNode* const node, KEY key);
+
+ dgTreeNode* Replace (OBJECT &element, KEY key);
+ dgTreeNode* ReplaceKey (KEY oldKey, KEY newKey);
+ dgTreeNode* ReplaceKey (dgTreeNode* const node, KEY key);
+
+ void Remove (KEY key);
+ void Remove (dgTreeNode* const node);
+ void RemoveAll ();
+
+ void Unlink (dgTreeNode* const node);
+ void SwapInfo (dgTree& tree);
+
+ bool SanityCheck () const;
+
+ // ***********************************************************
+ // member variables
+ // ***********************************************************
+ private:
+ int32_t m_count;
+ dgTreeNode* m_head;
+
+ int32_t CompareKeys (const KEY &key0, const KEY &key1) const;
+ bool SanityCheck (dgTreeNode* const ptr, int32_t height) const;
+
+ friend class dgTreeNode;
+};
+
+
+inline dgRedBackNode::dgRedBackNode (dgRedBackNode* const parent)
+{
+ Initdata (parent);
+}
+
+inline void dgRedBackNode::Initdata (dgRedBackNode* const parent)
+{
+ SetColor (RED);
+ SetInTreeFlag (true);
+ m_left = NULL;
+ m_right = NULL;
+ m_parent = parent;
+}
+
+inline void dgRedBackNode::SetColor (dgRedBackNode::REDBLACK_COLOR color)
+{
+ m_color = color;
+}
+
+
+
+inline dgRedBackNode::REDBLACK_COLOR dgRedBackNode::GetColor () const
+{
+ return REDBLACK_COLOR (m_color);
+}
+
+
+inline void dgRedBackNode::SetInTreeFlag (uint32_t flag)
+{
+ m_inTree = flag;
+}
+
+inline uint32_t dgRedBackNode::IsInTree () const
+{
+ return m_inTree;
+}
+
+/*
+template<class OBJECT, class KEY>
+dgTree<OBJECT, KEY>::dgTree ()
+{
+ m_count = 0;
+ m_head = NULL;
+}
+*/
+
+template<class OBJECT, class KEY>
+dgTree<OBJECT, KEY>::dgTree (void)
+{
+ m_count = 0;
+ m_head = NULL;
+}
+
+
+template<class OBJECT, class KEY>
+dgTree<OBJECT, KEY>::~dgTree ()
+{
+ RemoveAll();
+}
+
+template<class OBJECT, class KEY>
+dgTree<OBJECT, KEY>::operator int32_t() const
+{
+ return m_head != NULL;
+}
+
+template<class OBJECT, class KEY>
+int32_t dgTree<OBJECT, KEY>::GetCount() const
+{
+ return m_count;
+}
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::Minimum () const
+{
+ return m_head ? (dgTreeNode* )m_head->Minimum() : NULL;
+}
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::Maximum () const
+{
+ return m_head ? (dgTreeNode* )m_head->Maximum() : NULL;
+}
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::GetRoot () const
+{
+ return m_head;
+}
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::Find (KEY key) const
+{
+ if (m_head == NULL) {
+ return NULL;
+ }
+
+ dgTreeNode* ptr = m_head;
+ while (ptr != NULL) {
+ if (key < ptr->m_key) {
+ HACD_ASSERT (CompareKeys (ptr->m_key, key) == -1) ;
+ ptr = ptr->GetLeft();
+ } else if (key > ptr->m_key) {
+ HACD_ASSERT (CompareKeys (ptr->m_key, key) == 1) ;
+ ptr = ptr->GetRight();
+ } else {
+ HACD_ASSERT (CompareKeys (ptr->m_key, key) == 0) ;
+ break;
+ }
+ }
+ return ptr;
+}
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::GetNodeFromInfo (OBJECT &info) const
+{
+ dgTreeNode* const node = (dgTreeNode* ) &info;
+ int64_t offset = ((char*) &node->m_info) - ((char *) node);
+ dgTreeNode* const retnode = (dgTreeNode* ) (((char *) node) - offset);
+
+ HACD_ASSERT (retnode->IsInTree ());
+ HACD_ASSERT (&retnode->GetInfo () == &info);
+ return (retnode->IsInTree ()) ? retnode : NULL;
+
+}
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::FindGreater (KEY key) const
+{
+ if (m_head == NULL) {
+ return NULL;
+ }
+
+ dgTreeNode* prev = NULL;
+ dgTreeNode* ptr = m_head;
+
+ while (ptr != NULL) {
+ if (key < ptr->m_key) {
+ prev = ptr;
+ ptr = ptr->GetLeft();
+ } else {
+ ptr = ptr->GetRight();
+ }
+ }
+
+#ifdef __ENABLE_SANITY_CHECK
+ if (prev) {
+ Iterator iter (*this);
+ for (iter.Begin(); iter.GetNode() != prev; iter ++) {
+ KEY key1 = iter.GetKey();
+ HACD_ASSERT (key1 <= key);
+ }
+ for (; iter.GetNode(); iter ++) {
+ KEY key1 = iter.GetKey();
+ HACD_ASSERT (key1 > key);
+ }
+ }
+#endif
+
+ return (dgTreeNode* )prev;
+}
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::FindGreaterEqual (KEY key) const
+{
+ if (m_head == NULL) {
+ return NULL;
+ }
+
+ dgTreeNode* prev = NULL;
+ dgTreeNode* ptr = m_head;
+
+ while (ptr != NULL) {
+ if (key == ptr->m_key) {
+ return ptr;
+ }
+ if (key < ptr->m_key) {
+ prev = ptr;
+ ptr = ptr->GetLeft();
+ } else {
+ ptr = ptr->GetRight();
+ }
+ }
+
+#ifdef __ENABLE_SANITY_CHECK
+ if (prev) {
+ Iterator iter (*this);
+ for (iter.Begin(); iter.GetNode() != prev; iter ++) {
+ KEY key1 = iter.GetKey();
+ HACD_ASSERT (key1 <= key);
+ }
+ for (; iter.GetNode(); iter ++) {
+ KEY key1 = iter.GetKey();
+ HACD_ASSERT (key1 >= key);
+ }
+ }
+#endif
+
+ return (dgTreeNode* )prev;
+}
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::FindLessEqual (KEY key) const
+{
+ if (m_head == NULL) {
+ return NULL;
+ }
+
+ dgTreeNode* prev = NULL;
+ dgTreeNode* ptr = m_head;
+
+ while (ptr != NULL) {
+ if (key == ptr->m_key) {
+ return ptr;
+ }
+
+ if (key < ptr->m_key) {
+ ptr = ptr->GetLeft();
+ } else {
+ prev = ptr;
+ ptr = ptr->GetRight();
+ }
+
+ }
+
+#ifdef __ENABLE_SANITY_CHECK
+ if (prev) {
+ Iterator iter (*this);
+ for (iter.End(); iter.GetNode() != prev; iter --) {
+ KEY key1 = iter.GetKey();
+ HACD_ASSERT (key1 >= key);
+ }
+ for (; iter.GetNode(); iter --) {
+ KEY key1 = iter.GetKey();
+ HACD_ASSERT (key1 < key);
+ }
+ }
+#endif
+
+ return (dgTreeNode* )prev;
+}
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::Insert (const OBJECT &element, KEY key, bool& elementWasInTree)
+{
+ dgTreeNode* parent = NULL;
+ dgTreeNode* ptr = m_head;
+ int32_t val = 0;
+ elementWasInTree = false;
+ while (ptr != NULL) {
+ parent = ptr;
+
+ if (key < ptr->m_key) {
+ HACD_ASSERT (CompareKeys (ptr->m_key, key) == -1) ;
+ val = -1;
+ ptr = ptr->GetLeft();
+ } else if (key > ptr->m_key) {
+ HACD_ASSERT (CompareKeys (ptr->m_key, key) == 1) ;
+ val = 1;
+ ptr = ptr->GetRight();
+ } else {
+ HACD_ASSERT (CompareKeys (ptr->m_key, key) == 0) ;
+ elementWasInTree = true;
+ return ptr;
+ }
+ }
+
+ m_count ++;
+ ptr = HACD_NEW(dgTreeNode)(element, key, parent);
+ if (!parent) {
+ m_head = ptr;
+ } else {
+ if (val < 0) {
+ parent->m_left = ptr;
+ } else {
+ parent->m_right = ptr;
+ }
+ }
+
+ dgTreeNode** const headPtr = (dgTreeNode**) &m_head;
+// ptr->InsertFixup ((dgRedBackNode**)&m_head);
+ ptr->InsertFixup ((dgRedBackNode**)headPtr);
+ return ptr;
+}
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::Insert (const OBJECT &element, KEY key)
+{
+ bool foundState;
+
+ dgTreeNode* const node = Insert (element, key, foundState);
+ if (foundState) {
+ return NULL;
+ }
+ return node;
+}
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::Insert (typename dgTree<OBJECT, KEY>::dgTreeNode* const node, KEY key)
+{
+ int32_t val = 0;
+ dgTreeNode* ptr = m_head;
+ dgTreeNode* parent = NULL;
+ while (ptr != NULL) {
+ parent = ptr;
+// val = CompareKeys (ptr->m_key, key);
+// if (val < 0) {
+// ptr = ptr->GetLeft();
+// } else if (val > 0) {
+// ptr = ptr->GetRight();
+// } else {
+// return NULL;
+// }
+
+ if (key < ptr->m_key) {
+ HACD_ASSERT (CompareKeys (ptr->m_key, key) == -1) ;
+ val = -1;
+ ptr = ptr->GetLeft();
+ } else if (key > ptr->m_key) {
+ HACD_ASSERT (CompareKeys (ptr->m_key, key) == 1) ;
+ val = 1;
+ ptr = ptr->GetRight();
+ } else {
+ HACD_ASSERT (CompareKeys (ptr->m_key, key) == 0) ;
+ return NULL;
+ }
+ }
+
+ m_count ++;
+
+ ptr = node;
+ ptr->m_key = key;
+ ptr->Initdata (parent);
+
+ if (!parent) {
+ m_head = ptr;
+ } else {
+ if (val < 0) {
+ parent->m_left = ptr;
+ } else {
+ parent->m_right = ptr;
+ }
+ }
+
+ dgTreeNode** const headPtr = (dgTreeNode**) &m_head;
+// ptr->InsertFixup ((dgRedBackNode**)&m_head);
+ ptr->InsertFixup ((dgRedBackNode**)headPtr);
+ return ptr;
+}
+
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::Replace (OBJECT &element, KEY key)
+{
+ dgTreeNode* parent = NULL;
+ dgTreeNode* ptr = m_head;
+ int32_t val = 0;
+ while (ptr != NULL) {
+ parent = ptr;
+
+ HACD_ASSERT (0);
+ val = CompareKeys (ptr->m_key, key);
+ if (val == 0) {
+ ptr->m_info = element;
+ return ptr;
+ }
+ if (val < 0) {
+ ptr = ptr->GetLeft();
+ } else {
+ ptr = ptr->GetRight();
+ }
+ }
+
+ ptr = HACD_NEW(dgTreeNode) (element, key, parent);
+ if (!parent) {
+ m_head = ptr;
+ } else {
+ if (val < 0) {
+ parent->m_left = ptr;
+ } else {
+ parent->m_right = ptr;
+ }
+ }
+
+ dgTreeNode** const headPtr = (dgTreeNode**) &m_head;
+// ptr->InsertFixup ((dgRedBackNode**)&m_head);
+ ptr->InsertFixup ((dgRedBackNode**)headPtr );
+ return ptr;
+}
+
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::ReplaceKey (typename dgTree<OBJECT, KEY>::dgTreeNode* const node, KEY key)
+{
+ Unlink (node);
+ dgTreeNode* const ptr = Insert (node, key);
+ HACD_ASSERT (ptr);
+ return ptr;
+}
+
+template<class OBJECT, class KEY>
+typename dgTree<OBJECT, KEY>::dgTreeNode* dgTree<OBJECT, KEY>::ReplaceKey (KEY oldKey, KEY newKey)
+{
+ dgTreeNode* const node = Find (oldKey);
+ return node ? ReplaceKey (node, newKey) : NULL;
+}
+
+template<class OBJECT, class KEY>
+void dgTree<OBJECT, KEY>::Unlink (typename dgTree<OBJECT, KEY>::dgTreeNode* const node)
+{
+ m_count --;
+
+ dgTreeNode** const headPtr = (dgTreeNode**) &m_head;
+ node->Unlink ((dgRedBackNode**)headPtr);
+ HACD_ASSERT (!Find (node->GetKey()));
+}
+
+
+template<class OBJECT, class KEY>
+void dgTree<OBJECT, KEY>::Remove (typename dgTree<OBJECT, KEY>::dgTreeNode* const node)
+{
+ m_count --;
+ dgTreeNode** const headPtr = (dgTreeNode**) &m_head;
+ node->Remove ((dgRedBackNode**)headPtr);
+}
+
+template<class OBJECT, class KEY>
+void dgTree<OBJECT, KEY>::Remove (KEY key)
+{
+ dgTreeNode* node;
+
+ // find node in tree
+ node = Find (key);
+ if (node == NULL) {
+ return;
+ }
+ Remove (node);
+}
+
+template<class OBJECT, class KEY>
+void dgTree<OBJECT, KEY>::RemoveAll ()
+{
+ if (m_head) {
+ m_count = 0;
+ m_head->RemoveAll ();
+ m_head = NULL;
+ }
+}
+
+template<class OBJECT, class KEY>
+bool dgTree<OBJECT, KEY>::SanityCheck () const
+{
+ return SanityCheck (m_head, 0);
+}
+
+
+template<class OBJECT, class KEY>
+bool dgTree<OBJECT, KEY>::SanityCheck (typename dgTree<OBJECT, KEY>::dgTreeNode* const ptr, int32_t height) const
+{
+ if (!ptr) {
+ return true;
+ }
+
+ if (!ptr->IsInTree()) {
+ return false;
+ }
+
+ if (ptr->m_left) {
+ if (CompareKeys (ptr->m_key, ptr->GetLeft()->m_key) > 0) {
+ return false;
+ }
+ }
+
+ if (ptr->m_right) {
+ if (CompareKeys (ptr->m_key, ptr->GetRight()->m_key) < 0) {
+ return false;
+ }
+ }
+
+ if (ptr->GetColor() == dgTreeNode::BLACK) {
+ height ++;
+ } else if (!((!ptr->m_left || (ptr->m_left->GetColor() == dgTreeNode::BLACK)) &&
+ (!ptr->m_right || (ptr->m_right->GetColor() == dgTreeNode::BLACK)))) {
+ return false;
+ }
+
+ if (!ptr->m_left && !ptr->m_right) {
+ int32_t bh = 0;
+ for (dgTreeNode* x = ptr; x; x = x->GetParent()) {
+ if (x->GetColor() == dgTreeNode::BLACK) {
+ bh ++;
+ }
+ }
+ if (bh != height) {
+ return false;
+ }
+ }
+
+ if (ptr->m_left && !SanityCheck (ptr->GetLeft(), height)) {
+ return false;
+ }
+
+ if (ptr->m_right && !SanityCheck (ptr->GetRight(), height)) {
+ return false;
+ }
+ return true;
+}
+
+
+template<class OBJECT, class KEY>
+int32_t dgTree<OBJECT, KEY>::CompareKeys (const KEY &key0, const KEY &key1) const
+{
+ if (key1 < key0) {
+ return - 1;
+ }
+ if (key1 > key0) {
+ return 1;
+ }
+ return 0;
+}
+
+template<class OBJECT, class KEY>
+void dgTree<OBJECT, KEY>::SwapInfo (dgTree<OBJECT, KEY>& tree)
+{
+ Swap (m_head, tree.m_head);
+ Swap (m_count, tree.m_count);
+}
+
+
+#endif
+
+