13 #ifndef _FBXSDK_CORE_BASE_REDBLACKTREE_H_ 
   14 #define _FBXSDK_CORE_BASE_REDBLACKTREE_H_ 
   26 #ifndef DOXYGEN_SHOULD_SKIP_THIS 
   28 template <
typename RecordType> 
class FbxRedBlackConstIterator;
 
   30 template <
typename RecordType> 
class FbxRedBlackIterator
 
   33     FbxRedBlackIterator() : mRecord(0) {}
 
   34     FbxRedBlackIterator(RecordType* pRecord) : mRecord(pRecord) {}
 
   35     FbxRedBlackIterator(
const FbxRedBlackIterator<RecordType>& pV) : mRecord(pV.mRecord) {}
 
   37     FbxRedBlackIterator& operator++()
 
   39         FBX_ASSERT( mRecord != 
NULL );
 
   40         mRecord = mRecord->Successor();
 
   44     const FbxRedBlackIterator operator++(
int)
 
   46         FbxRedBlackIterator t(*
this);
 
   51     FbxRedBlackIterator& operator+=(
int pCount)
 
   53         FBX_ASSERT( mRecord != 
NULL );
 
   54         for( 
int i = 0; i < pCount; ++i )
 
   57             mRecord = mRecord->Successor();
 
   62     FbxRedBlackIterator& operator--()
 
   64         FBX_ASSERT( mRecord );
 
   65         mRecord = mRecord->Predecessor();
 
   69     const FbxRedBlackIterator operator--(
int)
 
   71         FbxRedBlackIterator t(*
this);
 
   76     FbxRedBlackIterator& operator-=(
int pCount)
 
   78         FBX_ASSERT( mRecord != 
NULL );
 
   79         for( 
int i = 0; i < pCount; ++i )
 
   82             mRecord = mRecord->Predecessor();
 
   87     const RecordType& operator*()
 const 
   89         FBX_ASSERT( mRecord );
 
   94     RecordType& operator*()
 
   96         FBX_ASSERT( mRecord );
 
  101     const RecordType* operator->()
 const 
  103         FBX_ASSERT( mRecord );
 
  108     RecordType* operator->()
 
  110         FBX_ASSERT( mRecord );
 
  115     inline bool operator==(
const FbxRedBlackIterator& pOther)
 const 
  117         return mRecord == pOther.mRecord;
 
  120     inline bool operator !=(
const FbxRedBlackIterator& pOther)
 const 
  122         return mRecord != pOther.mRecord;
 
  128     friend class FbxRedBlackConstIterator<RecordType>;
 
  131 template <
typename RecordType> 
class FbxRedBlackConstIterator
 
  134     FbxRedBlackConstIterator() : mRecord(0) {}
 
  135     FbxRedBlackConstIterator(
const RecordType* pRecord) : mRecord(pRecord) {}
 
  136     FbxRedBlackConstIterator(
const FbxRedBlackIterator<RecordType>& pV) : mRecord(pV.mRecord) {}
 
  137     FbxRedBlackConstIterator(
const FbxRedBlackConstIterator<RecordType>& pV) : mRecord(pV.mRecord) {}
 
  139     FbxRedBlackConstIterator & operator++()
 
  141         FBX_ASSERT( mRecord != 
NULL );
 
  142         mRecord = mRecord->Successor();
 
  146     const FbxRedBlackConstIterator operator++(
int)
 
  148         FbxRedBlackConstIterator t(*
this);
 
  153     FbxRedBlackConstIterator& operator+=(
int pCount)
 
  155         FBX_ASSERT( mRecord != 
NULL );
 
  156         for( 
int i = 0; i < pCount; ++i )
 
  158             if( !mRecord ) 
break;
 
  159             mRecord = mRecord->Successor();
 
  164     FbxRedBlackConstIterator & operator--()
 
  166         FBX_ASSERT( mRecord );
 
  167         mRecord = mRecord->Predecessor();
 
  171     const FbxRedBlackConstIterator operator--(
int)
 
  173         FbxRedBlackConstIterator t(*
this);
 
  178     FbxRedBlackConstIterator& operator-=(
int pCount)
 
  180         FBX_ASSERT( mRecord != 
NULL );
 
  181         for( 
int i = 0; i < pCount; ++i )
 
  183             if( !mRecord ) 
break;
 
  184             mRecord = mRecord->Predecessor();
 
  189     const RecordType& operator*()
 const 
  191         FBX_ASSERT( mRecord );
 
  196     const RecordType& operator*()
 
  198         FBX_ASSERT( mRecord );
 
  203     const RecordType* operator->()
 const 
  205         FBX_ASSERT( mRecord );
 
  210     const RecordType* operator->()
 
  212         FBX_ASSERT( mRecord );
 
  217     inline bool operator==(
const FbxRedBlackConstIterator& pOther)
 const 
  219         return mRecord == pOther.mRecord;
 
  222     inline bool operator !=(
const FbxRedBlackConstIterator& pOther)
 const 
  224         return mRecord != pOther.mRecord;
 
  228     const RecordType* mRecord;
 
  230     friend class FbxRedBlackIterator<RecordType>;
 
  234 template <
typename Type, 
typename Compare, 
typename Allocator> 
class FbxRedBlackTree
 
  237     typedef Type DataType;
 
  238     typedef typename Type::KeyType         KeyType;
 
  239     typedef typename Type::ConstKeyType    ConstKeyType;
 
  240     typedef typename Type::ValueType       ValueType;
 
  241     typedef typename Type::ConstValueType  ConstValueType;
 
  242     typedef Allocator AllocatorType;
 
  251         inline ConstKeyType& GetKey()
 const { 
return mData.GetKey(); }
 
  252         inline ConstValueType& GetValue()
 const { 
return mData.GetValue(); }
 
  253         inline ValueType& GetValue() { 
return mData.GetValue(); }
 
  255         inline const RecordType* Minimum()
 const 
  257             const RecordType* lParent = 0;
 
  258             const RecordType* lNode = 
this;
 
  262                 lNode = lNode->mLeftChild;
 
  268         inline RecordType* Minimum()
 
  270             RecordType* lParent = 0;
 
  271             RecordType* lNode = 
this;
 
  275                 lNode = lNode->mLeftChild;
 
  281         inline const RecordType* Maximum()
 const 
  283             const RecordType* lParent = 0;
 
  284             const RecordType* lNode = 
this;
 
  288                 lNode = lNode->mRightChild;
 
  294         inline RecordType* Maximum()
 
  296             RecordType* lParent = 0;
 
  297             RecordType* lNode = 
this;
 
  301                 lNode = lNode->mRightChild;
 
  307         inline const RecordType* Predecessor()
 const 
  311                 return mLeftChild->Maximum();
 
  315                 const RecordType* lParent = mParent;
 
  316                 const RecordType* lNode = 
this;
 
  318                 while (lParent && lParent->mLefttChild == lNode)
 
  321                     lParent = lParent->mParent;
 
  328         inline RecordType* Predecessor()
 
  332                 return mLeftChild->Maximum();
 
  336                 RecordType* lParent = mParent;
 
  337                 RecordType* lNode = 
this;
 
  339                 while (lParent && lParent->mLeftChild == lNode)
 
  342                     lParent = lParent->mParent;
 
  349         inline const RecordType* Successor()
 const 
  353                 return mRightChild->Minimum();
 
  357                 const RecordType* lParent = mParent;
 
  358                 const RecordType* lNode = 
this;
 
  360                 while (lParent && lParent->mRightChild == lNode)
 
  363                     lParent = lParent->mParent;
 
  370         inline RecordType* Successor()
 
  374                 return mRightChild->Minimum();
 
  378                 RecordType* lParent = mParent;
 
  379                 RecordType* lNode = 
this;
 
  381                 while (lParent && lParent->mRightChild == lNode)
 
  384                     lParent = lParent->mParent;
 
  391         inline const int GetBlackDepth() { 
return mBlackDepth; }
 
  394         enum ETreeType {eRed, eBlack};
 
  396         inline RecordType(
const DataType& pData)
 
  406         inline RecordType(
const RecordType& pRecordType)
 
  407             : mData(pRecordType.mData)
 
  411             , mColor(pRecordType.mColor)
 
  412             , mBlackDepth(pRecordType.mBlackDepth)
 
  418         friend class FbxRedBlackTree;
 
  421         RecordType* mLeftChild;
 
  422         RecordType* mRightChild;
 
  423         unsigned int mColor:2;
 
  424         unsigned int mBlackDepth:30;
 
  428     typedef FbxRedBlackConstIterator<RecordType>  ConstIteratorType;
 
  429     typedef FbxRedBlackIterator<RecordType>       IteratorType;
 
  431     inline FbxRedBlackTree() : mRoot(0), mSize(0), mAllocator(sizeof(RecordType)) {}
 
  432     inline FbxRedBlackTree(
const FbxRedBlackTree& pTree) : mRoot(0), mSize(0), mAllocator(sizeof(RecordType)) { operator=(pTree); }
 
  433     inline ~FbxRedBlackTree() { Clear(); }
 
  437     inline FbxRedBlackTree& operator=(
const FbxRedBlackTree& pTree)
 
  443             mAllocator = pTree.mAllocator;
 
  447                 void* lBuffer = mAllocator.AllocateRecords();
 
  448                 mRoot = 
new(lBuffer) RecordType(*(pTree.mRoot));    
 
  449                 mRoot->mLeftChild = DuplicateSubTree(pTree.mRoot->mLeftChild);
 
  450                 mRoot->mRightChild = DuplicateSubTree(pTree.mRoot->mRightChild);
 
  452                 if (mRoot->mLeftChild)
 
  454                     mRoot->mLeftChild->mParent = mRoot;
 
  457                 if (mRoot->mRightChild)
 
  459                     mRoot->mRightChild->mParent = mRoot;
 
  464                 FBX_ASSERT( pTree.mSize == 0 );
 
  465                 FBX_ASSERT( mRoot == 0 );
 
  474     inline bool operator==(
const FbxRedBlackTree& pTree)
 const 
  480         if( GetSize() != pTree.GetSize() )
 
  485         ConstIteratorType End;
 
  486         ConstIteratorType Iter1(Minimum());
 
  487         ConstIteratorType Iter2(pTree.Minimum());
 
  489         while( (Iter1 != End) && (Iter2 != End) &&
 
  490                (Iter1->GetKey() == Iter2->GetKey()) &&
 
  491                (Iter1->GetValue() == Iter2->GetValue()) )
 
  497         return Iter1 == End && Iter2 == End;
 
  503     inline void Reserve(
unsigned int pRecordCount)
 
  505         mAllocator.Reserve(pRecordCount);
 
  511     inline int GetSize()
 const { 
return mSize; }
 
  513     inline bool Empty()
 const { 
return mSize == 0; }
 
  522         Compare lCompareKeys;
 
  523         bool lResult = 
false;
 
  524         RecordType* lParent = 0;
 
  525         RecordType* lNode = mRoot;
 
  528             const KeyType& lNodeKey = lNode->GetKey();
 
  529             const KeyType& lDataKey = pData.GetKey();
 
  531             if (lCompareKeys(lNodeKey, lDataKey) < 0)
 
  534                 lNode = lNode->mRightChild;
 
  536             else if (lCompareKeys(lNodeKey, lDataKey) > 0)
 
  539                 lNode = lNode->mLeftChild;
 
  549             void* lBuffer = mAllocator.AllocateRecords();
 
  550             lNode = 
new(lBuffer) RecordType(pData); 
 
  553             FBX_ASSERT(lNode == lBuffer);
 
  557                 if (lCompareKeys(lParent->GetKey(), pData.GetKey()) < 0)
 
  559                     FBX_ASSERT(lParent->mRightChild == 0);
 
  560                     lParent->mRightChild = lNode;
 
  561                     lNode->mParent = lParent;
 
  565                     FBX_ASSERT(lParent->mLeftChild == 0);
 
  566                     lParent->mLeftChild = lNode;
 
  567                     lNode->mParent = lParent;
 
  576             FixNodesAfterInsertion(lNode);
 
  587     inline bool Remove(
const KeyType& pKey)
 
  589         Compare lCompareKeys;
 
  590         bool lResult = 
false;
 
  591         RecordType* lNode = mRoot;
 
  594             if (lCompareKeys(lNode->GetKey(), pKey) < 0)
 
  596                 lNode = lNode->mRightChild;
 
  598             else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
 
  600                 lNode = lNode->mLeftChild;
 
  612             lNode->~RecordType();
 
  613             mAllocator.FreeMemory(lNode);
 
  627             ClearSubTree(mRoot->mLeftChild);
 
  628             ClearSubTree(mRoot->mRightChild);
 
  629             mRoot->~RecordType();
 
  630             mAllocator.FreeMemory(mRoot);
 
  639     inline const RecordType* Minimum()
 const 
  643             return mRoot->Minimum();
 
  654     inline RecordType* Minimum()
 
  658             return mRoot->Minimum();
 
  669     inline const RecordType* Maximum()
 const 
  673             return mRoot->Maximum();
 
  684     inline RecordType* Maximum()
 
  688             return mRoot->Maximum();
 
  700     inline const RecordType* Find(
const KeyType& pKey)
 const 
  702         Compare lCompareKeys;
 
  703         const RecordType* lNode = mRoot;
 
  706             if (lCompareKeys(lNode->GetKey(), pKey) < 0)
 
  708                 lNode = lNode->mRightChild;
 
  710             else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
 
  712                 lNode = lNode->mLeftChild;
 
  727     inline RecordType* Find(
const KeyType& pKey)
 
  729         Compare lCompareKeys;
 
  730         RecordType* lNode = mRoot;
 
  733             if (lCompareKeys(lNode->GetKey(), pKey) < 0)
 
  735                 lNode = lNode->mRightChild;
 
  737             else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
 
  739                 lNode = lNode->mLeftChild;
 
  754     inline const RecordType* UpperBound(
const KeyType& pKey)
 const 
  756         Compare lCompareKeys;
 
  757         const RecordType* lNode = mRoot;
 
  758         const RecordType* lCandidate = 0;
 
  761             if (lCompareKeys(lNode->GetKey(), pKey) <= 0)
 
  763                 lNode = lNode->mRightChild;
 
  765             else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
 
  768                 lNode = lNode->mLeftChild;
 
  779     inline RecordType* UpperBound(
const KeyType& pKey)
 
  781         Compare lCompareKeys;
 
  782         RecordType* lNode = mRoot;
 
  783         RecordType* lCandidate = 0;
 
  786             if (lCompareKeys(lNode->GetKey(), pKey) <= 0)
 
  788                 lNode = lNode->mRightChild;
 
  790             else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
 
  793                 lNode = lNode->mLeftChild;
 
  804     AllocatorType mAllocator;
 
  806     inline RecordType* DuplicateSubTree(
const RecordType* pNode)
 
  808         RecordType* lNewSubTree = 0;
 
  812             void* lBuffer = mAllocator.AllocateRecords();
 
  813             lNewSubTree = 
new(lBuffer) RecordType(*pNode);  
 
  814             lNewSubTree->mLeftChild = DuplicateSubTree(pNode->mLeftChild);
 
  815             lNewSubTree->mRightChild = DuplicateSubTree(pNode->mRightChild);
 
  817             if (lNewSubTree->mLeftChild)
 
  819                 lNewSubTree->mLeftChild->mParent = lNewSubTree;
 
  822             if (lNewSubTree->mRightChild)
 
  824                 lNewSubTree->mRightChild->mParent = lNewSubTree;
 
  831     inline void FixNodesAfterInsertion(RecordType* pNode)
 
  833         RecordType* lNode = pNode;
 
  840             if (lNode->mParent == 0)
 
  842                 lNode->mColor = RecordType::eBlack;
 
  844             else if (lNode->mParent->mColor == RecordType::eRed)
 
  846                 RecordType* lUncle = 0;
 
  847                 if (lNode->mParent == lNode->mParent->mParent->mLeftChild)
 
  849                     lUncle = lNode->mParent->mParent->mRightChild;
 
  851                 else if (lNode->mParent == lNode->mParent->mParent->mRightChild)
 
  853                     lUncle = lNode->mParent->mParent->mLeftChild;
 
  858                 if (lUncle && lUncle->mColor == RecordType::eRed)
 
  860                     lNode->mParent->mColor = RecordType::eBlack;
 
  861                     lUncle->mColor = RecordType::eBlack;
 
  862                     lNode->mParent->mParent->mColor = RecordType::eRed;
 
  863                     lNode = lNode->mParent->mParent;
 
  869                     if ((lNode == lNode->mParent->mRightChild) &&
 
  870                         (lNode->mParent == lNode->mParent->mParent->mLeftChild))
 
  872                         LeftRotate(lNode->mParent);
 
  873                         lNode = lNode->mLeftChild;
 
  875                     else if ((lNode == lNode->mParent->mLeftChild) &&
 
  876                             (lNode->mParent == lNode->mParent->mParent->mRightChild))
 
  878                         RightRotate(lNode->mParent);
 
  879                         lNode = lNode->mRightChild;
 
  882                     lNode->mParent->mColor = RecordType::eBlack;
 
  883                     lNode->mParent->mParent->mColor = RecordType::eRed;
 
  884                     if ((lNode == lNode->mParent->mLeftChild) &&
 
  885                         (lNode->mParent == lNode->mParent->mParent->mLeftChild))
 
  887                         RightRotate(lNode->mParent->mParent);
 
  891                         LeftRotate(lNode->mParent->mParent);
 
  897         mRoot->mColor = RecordType::eBlack;
 
  900     inline void LeftRotate(RecordType* pNode)
 
  902         FBX_ASSERT_RETURN(pNode);
 
  904         RecordType* lNode = pNode->mRightChild;
 
  905         FBX_ASSERT_RETURN(lNode);
 
  908         RecordType* A = pNode->mLeftChild;
 
  909         RecordType* B = lNode->mLeftChild;
 
  910         RecordType* C = lNode->mRightChild;
 
  911         RecordType* Z = pNode->mParent;
 
  914         pNode->mRightChild = lNode->mLeftChild;
 
  915         if (pNode->mRightChild)
 
  917             pNode->mRightChild->mParent = pNode;
 
  920         lNode->mParent = pNode->mParent;
 
  921         if (pNode->mParent == 0)
 
  923             FBX_ASSERT(mRoot == pNode);
 
  926         else if (pNode == pNode->mParent->mLeftChild)
 
  928             pNode->mParent->mLeftChild = lNode;
 
  932             pNode->mParent->mRightChild = lNode;
 
  934         pNode->mParent = lNode;
 
  935         lNode->mLeftChild = pNode;
 
  937         FBX_ASSERT(pNode->mLeftChild == A);
 
  938         FBX_ASSERT(pNode->mRightChild == B);
 
  939         FBX_ASSERT(pNode->mParent == lNode);
 
  941         FBX_ASSERT(lNode->mLeftChild == pNode);
 
  942         FBX_ASSERT(lNode->mRightChild == C);
 
  943         FBX_ASSERT(lNode->mParent == Z);
 
  945         FBX_ASSERT(A == 0 || A->mParent == pNode);
 
  946         FBX_ASSERT(B == 0 || B->mParent == pNode);
 
  947         FBX_ASSERT(C == 0 || C->mParent == lNode);
 
  948         FBX_ASSERT(Z == 0 || Z->mLeftChild == lNode || Z->mRightChild == lNode);
 
  951     inline void RightRotate(RecordType* pNode)
 
  953         RecordType* lNode = pNode->mLeftChild;
 
  956         RecordType* A = lNode->mLeftChild;
 
  957         RecordType* B = lNode->mRightChild;
 
  958         RecordType* C = pNode->mRightChild;
 
  959         RecordType* Z = pNode->mParent;
 
  962         pNode->mLeftChild = lNode->mRightChild;
 
  963         if (pNode->mLeftChild)
 
  965             pNode->mLeftChild->mParent = pNode;
 
  968         lNode->mParent = pNode->mParent;
 
  969         if (pNode->mParent == 0)
 
  971             FBX_ASSERT(mRoot == pNode);
 
  974         else if (pNode == pNode->mParent->mRightChild)
 
  976             pNode->mParent->mRightChild = lNode;
 
  980             pNode->mParent->mLeftChild = lNode;
 
  982         pNode->mParent = lNode;
 
  983         lNode->mRightChild = pNode;
 
  985         FBX_ASSERT(lNode->mLeftChild == A);
 
  986         FBX_ASSERT(lNode->mRightChild == pNode);
 
  987         FBX_ASSERT(lNode->mParent == Z);
 
  989         FBX_ASSERT(pNode->mLeftChild == B);
 
  990         FBX_ASSERT(pNode->mRightChild == C);
 
  991         FBX_ASSERT(pNode->mParent == lNode);
 
  993         FBX_ASSERT(A == 0 || A->mParent == lNode);
 
  994         FBX_ASSERT(B == 0 || B->mParent == pNode);
 
  995         FBX_ASSERT(C == 0 || C->mParent == pNode);
 
  996         FBX_ASSERT(Z == 0 || Z->mLeftChild == lNode || Z->mRightChild == lNode);
 
  999     inline void RemoveNode(RecordType* pNode)
 
 1001         if (pNode->mLeftChild == 0)
 
 1003             if (pNode->mRightChild == 0)
 
 1007                     if (pNode->mParent->mLeftChild == pNode)
 
 1009                         pNode->mParent->mLeftChild = 0;
 
 1011                     else if (pNode->mParent->mRightChild == pNode)
 
 1013                         pNode->mParent->mRightChild = 0;
 
 1017                         FBX_ASSERT_NOW(
"Node not found in FbxRedBlackTree");
 
 1022                     FBX_ASSERT(mRoot == pNode);
 
 1026                 if (pNode->mColor == RecordType::eBlack)
 
 1028                     FixNodesAfterRemoval(pNode->mParent, 0);
 
 1035                     if (pNode->mParent->mLeftChild == pNode)
 
 1037                         pNode->mParent->mLeftChild = pNode->mRightChild;
 
 1038                         pNode->mRightChild->mParent = pNode->mParent;
 
 1040                     else if (pNode->mParent->mRightChild == pNode)
 
 1042                         pNode->mParent->mRightChild = pNode->mRightChild;
 
 1043                         pNode->mRightChild->mParent = pNode->mParent;
 
 1047                         FBX_ASSERT_NOW(
"Node not found in FbxRedBlackTree");
 
 1052                     FBX_ASSERT(mRoot == pNode);
 
 1053                     mRoot = pNode->mRightChild;
 
 1054                     pNode->mRightChild->mParent = 0;
 
 1057                 if (pNode->mColor == RecordType::eBlack)
 
 1059                     FixNodesAfterRemoval(pNode->mRightChild->mParent, pNode->mRightChild);
 
 1065             if (pNode->mRightChild == 0)
 
 1069                     if (pNode->mParent->mLeftChild == pNode)
 
 1071                         pNode->mParent->mLeftChild = pNode->mLeftChild;
 
 1072                         pNode->mLeftChild->mParent = pNode->mParent;
 
 1074                     else if (pNode->mParent->mRightChild == pNode)
 
 1076                         pNode->mParent->mRightChild = pNode->mLeftChild;
 
 1077                         pNode->mLeftChild->mParent = pNode->mParent;
 
 1081                         FBX_ASSERT_NOW(
"Node not found in FbxRedBlackTree");
 
 1086                     FBX_ASSERT(mRoot == pNode);
 
 1087                     mRoot = pNode->mLeftChild;
 
 1088                     pNode->mLeftChild->mParent = 0;
 
 1091                 if (pNode->mColor == RecordType::eBlack)
 
 1093                     FixNodesAfterRemoval(pNode->mLeftChild->mParent, pNode->mLeftChild);
 
 1098                 RecordType* lMinRightNode = pNode->mRightChild->Minimum();
 
 1099                 RemoveNode(lMinRightNode);
 
 1101                 lMinRightNode->mColor = pNode->mColor;
 
 1102                 ReplaceNode(pNode, lMinRightNode);
 
 1107         pNode->mLeftChild = 0;
 
 1108         pNode->mRightChild = 0;
 
 1111     inline void ReplaceNode(RecordType* pNodeToReplace, RecordType* pReplacement)
 
 1113         pReplacement->mParent = pNodeToReplace->mParent;
 
 1114         if (pNodeToReplace->mParent)
 
 1116             if (pNodeToReplace->mParent->mLeftChild == pNodeToReplace)
 
 1118                 pNodeToReplace->mParent->mLeftChild = pReplacement;
 
 1120             else if (pNodeToReplace->mParent->mRightChild == pNodeToReplace)
 
 1122                 pNodeToReplace->mParent->mRightChild = pReplacement;
 
 1127             FBX_ASSERT(mRoot == pNodeToReplace);
 
 1128             mRoot = pReplacement;
 
 1131         pReplacement->mLeftChild = pNodeToReplace->mLeftChild;
 
 1132         if (pReplacement->mLeftChild)
 
 1134             pReplacement->mLeftChild->mParent = pReplacement;
 
 1137         pReplacement->mRightChild = pNodeToReplace->mRightChild;
 
 1138         if (pReplacement->mRightChild)
 
 1140             pReplacement->mRightChild->mParent = pReplacement;
 
 1144     inline RecordType* Sibling(
const RecordType* pParent, 
const RecordType* pNode)
 const 
 1148             if (pParent->mLeftChild == pNode)
 
 1150                 return pParent->mRightChild;
 
 1152             else if (pParent->mRightChild == pNode)
 
 1154                 return pParent->mLeftChild;
 
 1161     inline bool IsBlack(
const RecordType* pNode)
 
 1163         return ((pNode == 0) || (pNode->mColor == RecordType::eBlack));
 
 1166     inline void FixNodesAfterRemoval(RecordType* pParent, RecordType* pNode)
 
 1168         RecordType* lParent = pParent;
 
 1169         RecordType* lNode = pNode;
 
 1176             if (!IsBlack(lNode))
 
 1178                 lNode->mColor = RecordType::eBlack;
 
 1180             else if (lParent != 
NULL)
 
 1182                 RecordType* lSibling = Sibling(lParent, lNode);
 
 1184                 if (!IsBlack(lSibling))
 
 1186                     lParent->mColor = RecordType::eRed;
 
 1187                     lSibling->mColor = RecordType::eBlack;
 
 1188                     if (lNode == lParent->mLeftChild)
 
 1190                         LeftRotate(lParent);
 
 1194                         RightRotate(lParent);
 
 1199                     lSibling = Sibling(lParent, lNode);
 
 1205                     IsBlack(lSibling) &&
 
 1206                     IsBlack(lSibling->mLeftChild) &&
 
 1207                     IsBlack(lSibling->mRightChild))
 
 1209                     lSibling->mColor = RecordType::eRed;
 
 1211                     lParent = lParent->mParent;
 
 1216                     if (!IsBlack(lParent) &&
 
 1217                         IsBlack(lSibling) &&
 
 1218                         ((lSibling == 0) || IsBlack(lSibling->mLeftChild)) &&
 
 1219                         ((lSibling == 0) || IsBlack(lSibling->mRightChild)))
 
 1223                             lSibling->mColor = RecordType::eRed;
 
 1225                         lParent->mColor = RecordType::eBlack;
 
 1227                     else if( lSibling != 0 )
 
 1229                         if ((lNode == lParent->mLeftChild) &&
 
 1230                             IsBlack(lSibling) &&
 
 1231                             !IsBlack(lSibling->mLeftChild) &&
 
 1232                             IsBlack(lSibling->mRightChild))
 
 1234                             lSibling->mColor = RecordType::eRed;
 
 1235                             lSibling->mLeftChild->mColor = RecordType::eBlack;
 
 1236                             RightRotate(lSibling);
 
 1238                         else if ((lNode == lParent->mRightChild) &&
 
 1239                                  IsBlack(lSibling) &&
 
 1240                                  IsBlack(lSibling->mLeftChild) &&
 
 1241                                  !IsBlack(lSibling->mRightChild))
 
 1243                             lSibling->mColor = RecordType::eRed;
 
 1244                             lSibling->mRightChild->mColor = RecordType::eBlack;
 
 1245                             LeftRotate(lSibling);
 
 1249                         lSibling = Sibling(lParent, lNode);
 
 1250                         FBX_ASSERT(lSibling != 0 && lParent != 0); 
 
 1255                         if( lSibling != 0 && lParent != 0 )
 
 1257                             lSibling->mColor = lParent->mColor;
 
 1258                             lParent->mColor = RecordType::eBlack;
 
 1259                             if (lNode == lParent->mLeftChild)
 
 1261                                 if (lSibling->mRightChild)
 
 1263                                     lSibling->mRightChild->mColor = RecordType::eBlack;
 
 1265                                 LeftRotate(lParent);
 
 1269                                 if (lSibling->mLeftChild)
 
 1271                                     lSibling->mLeftChild->mColor = RecordType::eBlack;
 
 1273                                 RightRotate(lParent);
 
 1283             mRoot->mColor = RecordType::eBlack;
 
 1287     inline void ClearSubTree(RecordType* pNode)
 
 1291             ClearSubTree(pNode->mLeftChild);
 
 1292             ClearSubTree(pNode->mRightChild);
 
 1293             pNode->~RecordType();
 
 1294             mAllocator.FreeMemory(pNode);
 
 1298     inline int GetSubTreeSize(RecordType* pNode)
 const 
 1302             return GetSubTreeSize(pNode->mLeftChild) + GetSubTreeSize(pNode->mRightChild) + 1;
 
 1311     inline void IsSane()
 
 1313         FBX_ASSERT((mRoot == 0) || (mRoot->mColor == RecordType::eBlack));
 
 1314         FBX_ASSERT(((mRoot == 0) && (mSize == 0)) || (mRoot != 0) && (mSize != 0));
 
 1315         IsSubTreeSane(mRoot);
 
 1317         ComputeBlackDepth(mRoot, 0);
 
 1319         RecordType* lNode = mRoot;
 
 1320         unsigned int lLeafBlackDepth = 0;
 
 1323             if (lNode->mLeftChild == 0)
 
 1325                 lLeafBlackDepth = lNode->mBlackDepth + ((lNode->mColor == RecordType::eBlack) ? 1 : 0);
 
 1328             lNode = lNode->mLeftChild;
 
 1331         CheckLeavesBlackDepth(mRoot, lLeafBlackDepth);
 
 1334     inline void IsSubTreeSane(
const RecordType* pNode)
 const 
 1336         Compare lCompareKeys;
 
 1340             FBX_ASSERT(pNode != pNode->mParent);
 
 1341             FBX_ASSERT(pNode != pNode->mLeftChild);
 
 1342             FBX_ASSERT(pNode != pNode->mRightChild);
 
 1345             FBX_ASSERT((pNode->mColor == RecordType::eBlack) ||
 
 1346                      (pNode->mLeftChild == 
NULL) ||
 
 1347                      (pNode->mLeftChild->mColor == RecordType::eBlack));
 
 1349             FBX_ASSERT((pNode->mColor == RecordType::eBlack) ||
 
 1350                      (pNode->mRightChild == 
NULL) ||
 
 1351                      (pNode->mRightChild->mColor == RecordType::eBlack));
 
 1354             FBX_ASSERT((pNode->mLeftChild == 0 ||
 
 1355                       lCompareKeys(pNode->GetKey(), pNode->mLeftChild->GetKey()) > 0));
 
 1357             FBX_ASSERT((pNode->mRightChild == 0 ||
 
 1358                       lCompareKeys(pNode->GetKey(), pNode->mRightChild->GetKey()) < 0));
 
 1360             IsSubTreeSane(pNode->mLeftChild);
 
 1361             IsSubTreeSane(pNode->mRightChild);
 
 1365     inline void ComputeBlackDepth(RecordType* pNode, 
unsigned int pDepth)
 
 1369             pNode->mBlackDepth = pDepth;
 
 1370             if( pNode->mColor == RecordType::eBlack )
 
 1374             ComputeBlackDepth(pNode->mLeftChild, pDepth);
 
 1375             ComputeBlackDepth(pNode->mRightChild, pDepth);
 
 1379     inline void CheckLeavesBlackDepth(RecordType* pNode, 
unsigned int pBlackDepth)
 
 1383             if( pNode->mLeftChild == 0 || pNode->mRightChild == 0 )
 
 1385                 FBX_ASSERT((pNode->mBlackDepth + ((pNode->mColor == RecordType::eBlack) ? 1 : 0)) == pBlackDepth);
 
 1387             CheckLeavesBlackDepth(pNode->mLeftChild, pBlackDepth);
 
 1388             CheckLeavesBlackDepth(pNode->mRightChild, pBlackDepth);
 
FBX SDK environment definition. 
 
This class template holds a pair of objects.