00001
00004 #ifndef FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KMAP_H
00005 #define FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KMAP_H
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <fbxfilesdk/fbxfilesdk_def.h>
00042
00043 #include <fbxfilesdk/components/kbaselib/klib/kpair.h>
00044 #include <fbxfilesdk/components/kbaselib/klib/kcontainerallocators.h>
00045 #include <fbxfilesdk/components/kbaselib/klib/kdebug.h>
00046
00047 #include <new>
00048
00049 #include <fbxfilesdk/fbxfilesdk_nsbegin.h>
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 template <typename RecordType> class RedBack_ConstIteratorType;
00080 template <typename RecordType> class RedBack_IteratorType;
00081
00082 template <typename RecordType>
00083
00086 class RedBack_IteratorType
00087 {
00088 public:
00089 RedBack_IteratorType() : mRecord(0) {}
00090 RedBack_IteratorType(RecordType* pRecord) : mRecord(pRecord) {}
00091 RedBack_IteratorType(RedBack_IteratorType<RecordType> const& pV) : mRecord(pV.mRecord) {}
00092
00093
00094 RedBack_IteratorType const& operator++()
00095 {
00096 K_ASSERT( mRecord != NULL );
00097
00098 mRecord = mRecord->Successor();
00099
00100 return *this;
00101 }
00102
00103
00104 RedBack_IteratorType operator++(int)
00105 {
00106 RedBack_IteratorType t(*this);
00107 operator++();
00108 return t;
00109 }
00110
00111
00112 RedBack_IteratorType const& operator--()
00113 {
00114 K_ASSERT( mRecord );
00115
00116 RecordType* lRecord = mRecord->Predecessor();
00117 mRecord = lRecord;
00118 return *this;
00119 }
00120
00121
00122 RedBack_IteratorType operator--(int)
00123 {
00124 RedBack_IteratorType t(*this);
00125 operator--();
00126 return t;
00127 }
00128
00129 RecordType const& operator*() const
00130 {
00131 K_ASSERT( mRecord );
00132
00133 return *mRecord;
00134 }
00135
00136 RecordType & operator*()
00137 {
00138 K_ASSERT( mRecord );
00139
00140 return *mRecord;
00141 }
00142
00143 RecordType const* operator->() const
00144 {
00145 K_ASSERT( mRecord );
00146
00147 return mRecord;
00148 }
00149
00150 RecordType* operator->()
00151 {
00152 K_ASSERT( mRecord );
00153
00154 return mRecord;
00155 }
00156
00157 inline bool operator==(const RedBack_IteratorType& pOther) const
00158 {
00159 return mRecord == pOther.mRecord;
00160 }
00161
00162 inline bool operator !=(const RedBack_IteratorType& pOther) const
00163 {
00164 return mRecord != pOther.mRecord;
00165 }
00166
00167 protected:
00168 friend class RedBack_ConstIteratorType<RecordType>;
00169
00170 RecordType* mRecord;
00171 };
00172
00173 template <typename RecordType>
00174 class RedBack_ConstIteratorType
00175 {
00176 public:
00177 RedBack_ConstIteratorType() : mRecord(0) {}
00178 RedBack_ConstIteratorType(const RecordType* pRecord) : mRecord(pRecord) {}
00179 RedBack_ConstIteratorType(RedBack_IteratorType<RecordType> const& pV) : mRecord(pV.mRecord) {}
00180 RedBack_ConstIteratorType(RedBack_ConstIteratorType<RecordType> const& pV) : mRecord(pV.mRecord) {}
00181
00182
00183 RedBack_ConstIteratorType const& operator++()
00184 {
00185 K_ASSERT( mRecord != NULL );
00186
00187 mRecord = mRecord->Successor();
00188
00189 return *this;
00190 }
00191
00192
00193 RedBack_ConstIteratorType operator++(int)
00194 {
00195 RedBack_ConstIteratorType t(*this);
00196 operator++();
00197 return t;
00198 }
00199
00200
00201 RedBack_ConstIteratorType const& operator--()
00202 {
00203 K_ASSERT( mRecord );
00204
00205 RecordType const* lRecord = mRecord->Predecessor();
00206 mRecord = lRecord;
00207 return *this;
00208 }
00209
00210
00211 RedBack_ConstIteratorType operator--(int)
00212 {
00213 RedBack_ConstIteratorType t(*this);
00214 operator--();
00215 return t;
00216 }
00217
00218 RecordType const& operator*() const
00219 {
00220 K_ASSERT( mRecord );
00221
00222 return *mRecord;
00223 }
00224
00225 RecordType const& operator*()
00226 {
00227 K_ASSERT( mRecord );
00228
00229 return *mRecord;
00230 }
00231
00232 RecordType const* operator->() const
00233 {
00234 K_ASSERT( mRecord );
00235
00236 return mRecord;
00237 }
00238
00239 RecordType const* operator->()
00240 {
00241 K_ASSERT( mRecord );
00242
00243 return mRecord;
00244 }
00245
00246 inline bool operator==(const RedBack_ConstIteratorType& pOther) const
00247 {
00248 return mRecord == pOther.mRecord;
00249 }
00250
00251 inline bool operator !=(const RedBack_ConstIteratorType& pOther) const
00252 {
00253 return mRecord != pOther.mRecord;
00254 }
00255
00256 protected:
00257 friend class RedBack_IteratorType<RecordType>;
00258
00259 RecordType const* mRecord;
00260 };
00261
00264 template <typename DATA_TYPE,
00265 typename KEY_COMPARE_FUNCTOR,
00266 typename ALLOCATOR>
00267 class KRedBlackTree
00268 {
00269 public:
00270 typedef DATA_TYPE DataType;
00271 typedef typename DATA_TYPE::KeyType KeyType;
00272 typedef typename DATA_TYPE::ConstKeyType ConstKeyType;
00273 typedef typename DATA_TYPE::ValueType ValueType;
00274 typedef typename DATA_TYPE::ConstValueType ConstValueType;
00275 typedef ALLOCATOR AllocatorType;
00276
00281 class RecordType
00282 {
00283 public:
00284 inline ConstKeyType& GetKey() const { return mData.GetKey(); }
00285 inline ConstValueType& GetValue() const { return mData.GetValue(); }
00286 inline ValueType& GetValue() { return mData.GetValue(); }
00287
00288 inline RecordType const* Minimum() const
00289 {
00290 RecordType const* lParent = 0;
00291 RecordType const* lNode = this;
00292 while (lNode != 0)
00293 {
00294 lParent = lNode;
00295 lNode = lNode->mLeftChild;
00296 }
00297
00298 return lParent;
00299 }
00300
00301 inline RecordType* Minimum()
00302 {
00303 RecordType* lParent = 0;
00304 RecordType* lNode = this;
00305 while (lNode != 0)
00306 {
00307 lParent = lNode;
00308 lNode = lNode->mLeftChild;
00309 }
00310
00311 return lParent;
00312 }
00313
00314 inline RecordType const* Maximum() const
00315 {
00316 RecordType const* lParent = 0;
00317 RecordType const* lNode = this;
00318 while (lNode != 0)
00319 {
00320 lParent = lNode;
00321 lNode = lNode->mRightChild;
00322 }
00323
00324 return lParent;
00325 }
00326
00327 inline RecordType* Maximum()
00328 {
00329 RecordType* lParent = 0;
00330 RecordType* lNode = this;
00331 while (lNode != 0)
00332 {
00333 lParent = lNode;
00334 lNode = lNode->mRightChild;
00335 }
00336
00337 return lParent;
00338 }
00339
00340 inline RecordType const* Predecessor() const
00341 {
00342 if (mLeftChild)
00343 {
00344 return mLeftChild->Maximum();
00345 }
00346 else
00347 {
00348 RecordType const* lParent = mParent;
00349 RecordType const* lNode = this;
00350
00351 while (lParent && lParent->mLefttChild == lNode)
00352 {
00353 lNode = lParent;
00354 lParent = lParent->mParent;
00355 }
00356
00357 return lParent;
00358 }
00359 }
00360
00361 inline RecordType* Predecessor()
00362 {
00363 if (mLeftChild)
00364 {
00365 return mLeftChild->Maximum();
00366 }
00367 else
00368 {
00369 RecordType* lParent = mParent;
00370 RecordType* lNode = this;
00371
00372 while (lParent && lParent->mLeftChild == lNode)
00373 {
00374 lNode = lParent;
00375 lParent = lParent->mParent;
00376 }
00377
00378 return lParent;
00379 }
00380 }
00381
00382 inline RecordType const* Successor() const
00383 {
00384 if (mRightChild)
00385 {
00386 return mRightChild->Minimum();
00387 }
00388 else
00389 {
00390 RecordType const* lParent = mParent;
00391 RecordType const* lNode = this;
00392
00393 while (lParent && lParent->mRightChild == lNode)
00394 {
00395 lNode = lParent;
00396 lParent = lParent->mParent;
00397 }
00398
00399 return lParent;
00400 }
00401 }
00402
00403 inline RecordType* Successor()
00404 {
00405 if (mRightChild)
00406 {
00407 return mRightChild->Minimum();
00408 }
00409 else
00410 {
00411 RecordType* lParent = mParent;
00412 RecordType* lNode = this;
00413
00414 while (lParent && lParent->mRightChild == lNode)
00415 {
00416 lNode = lParent;
00417 lParent = lParent->mParent;
00418 }
00419
00420 return lParent;
00421 }
00422 }
00423
00424 inline int GetBlackDepth() const { return mBlackDepth; }
00425
00426 private:
00427 enum { eRed, eBlack };
00428
00429 inline RecordType(DataType const& pData)
00430 : mData(pData)
00431 , mParent(0)
00432 , mLeftChild(0)
00433 , mRightChild(0)
00434 , mColor(eRed)
00435 , mBlackDepth(0)
00436 {
00437 }
00438
00439 inline RecordType(RecordType const& pRecordType)
00440 : mData(pRecordType.mData)
00441 , mParent(0)
00442 , mLeftChild(0)
00443 , mRightChild(0)
00444 , mColor(pRecordType.mColor)
00445 , mBlackDepth(pRecordType.mBlackDepth)
00446 {
00447 }
00448
00449 DataType mData;
00450
00451 friend class KRedBlackTree;
00452
00453 RecordType* mParent;
00454 RecordType* mLeftChild;
00455 RecordType* mRightChild;
00456 unsigned int mColor:2;
00457 unsigned int mBlackDepth:30;
00458
00459 #if defined(KARCH_DEV_MSC) // Microsoft compiler
00460 #if (_MSC_VER <= 1200) // VC6
00461 friend KRedBlackTree<DATA_TYPE, KEY_COMPARE_FUNCTOR, ALLOCATOR>;
00462 #endif
00463 #endif
00464 };
00465
00466 public:
00467 typedef RedBack_ConstIteratorType<RecordType> ConstIteratorType;
00468 typedef RedBack_IteratorType<RecordType> IteratorType;
00469
00470 public:
00471 inline KRedBlackTree() : mRoot(0), mSize(0), mAllocator(sizeof(RecordType)) {}
00472 inline KRedBlackTree(KRedBlackTree const& pTree) : mRoot(0), mSize(0), mAllocator(sizeof(RecordType)) { operator=(pTree); }
00473 inline ~KRedBlackTree() { Clear(); }
00474
00478 inline KRedBlackTree& operator=(KRedBlackTree const& pTree)
00479 {
00480 if( this != &pTree )
00481 {
00482 Clear();
00483
00484 mAllocator = pTree.mAllocator;
00485
00486 if( pTree.mRoot )
00487 {
00488 void* lBuffer = mAllocator.AllocateRecords();
00489 #if ( defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
00490 #pragma push_macro("new")
00491 #undef new
00492 #endif
00493 mRoot = new(lBuffer) RecordType(*(pTree.mRoot));
00494 #if ( defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
00495 #pragma pop_macro("new")
00496 #endif
00497 mRoot->mLeftChild = DuplicateSubTree(pTree.mRoot->mLeftChild);
00498 mRoot->mRightChild = DuplicateSubTree(pTree.mRoot->mRightChild);
00499
00500 if (mRoot->mLeftChild)
00501 {
00502 mRoot->mLeftChild->mParent = mRoot;
00503 }
00504
00505 if (mRoot->mRightChild)
00506 {
00507 mRoot->mRightChild->mParent = mRoot;
00508 }
00509 }
00510 else
00511 {
00512 K_ASSERT( pTree.mSize == 0 );
00513 K_ASSERT( mRoot == 0 );
00514 }
00515
00516 mSize = pTree.mSize;
00517 }
00518
00519 return *this;
00520 }
00521
00522 inline bool operator==(KRedBlackTree const& pTree) const
00523 {
00524
00525 if( this == &pTree )
00526 return true;
00527
00528 if( GetSize() != pTree.GetSize() )
00529 return false;
00530
00531
00532
00533 ConstIteratorType End;
00534 ConstIteratorType Iter1(Minimum());
00535 ConstIteratorType Iter2(pTree.Minimum());
00536
00537 while( (Iter1 != End) && (Iter2 != End) &&
00538 (Iter1->GetKey() == Iter2->GetKey()) &&
00539 (Iter1->GetValue() == Iter2->GetValue()) )
00540 {
00541 ++Iter1;
00542 ++Iter2;
00543 }
00544
00545 return Iter1 == End && Iter2 == End;
00546 }
00547
00551 inline void Reserve(unsigned int pRecordCount)
00552 {
00553 mAllocator.Reserve(pRecordCount);
00554 }
00555
00559 inline int GetSize() const { return mSize; }
00560
00561 inline bool Empty() const { return mSize == 0; }
00562
00568 inline KPair<RecordType*, bool> Insert(DataType const& pData)
00569 {
00570 KEY_COMPARE_FUNCTOR lCompareKeys;
00571 bool lResult = false;
00572 RecordType* lParent = 0;
00573 RecordType* lNode = mRoot;
00574 while (lNode != 0)
00575 {
00576 KeyType const& lNodeKey = lNode->GetKey();
00577 KeyType const& lDataKey = pData.GetKey();
00578
00579 if (lCompareKeys(lNodeKey, lDataKey) < 0)
00580 {
00581 lParent = lNode;
00582 lNode = lNode->mRightChild;
00583 }
00584 else if (lCompareKeys(lNodeKey, lDataKey) > 0)
00585 {
00586 lParent = lNode;
00587 lNode = lNode->mLeftChild;
00588 }
00589 else
00590 {
00591 break;
00592 }
00593 }
00594
00595 if (lNode == 0)
00596 {
00597 void* lBuffer = mAllocator.AllocateRecords();
00598 #if ( defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
00599 #pragma push_macro("new")
00600 #undef new
00601 #endif
00602 lNode = new(lBuffer) RecordType(pData);
00603 #if ( defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
00604 #pragma pop_macro("new")
00605 #endif
00606 mSize++;
00607
00608 #if ( !defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
00609 K_ASSERT(lNode == lBuffer);
00610 #endif
00611
00612 if (lParent)
00613 {
00614 if (lCompareKeys(lParent->GetKey(), pData.GetKey()) < 0)
00615 {
00616 K_ASSERT(lParent->mRightChild == 0);
00617 lParent->mRightChild = lNode;
00618 lNode->mParent = lParent;
00619 }
00620 else
00621 {
00622 K_ASSERT(lParent->mLeftChild == 0);
00623 lParent->mLeftChild = lNode;
00624 lNode->mParent = lParent;
00625 }
00626 }
00627 else
00628 {
00629 mRoot = lNode;
00630 }
00631
00632
00633 FixNodesAfterInsertion(lNode);
00634
00635 lResult = true;
00636 }
00637
00638 #ifdef SANITY_CHECK
00639 IsSane();
00640 #endif
00641
00642 return KPair<RecordType*, bool>(lNode, lResult);
00643 }
00644
00648 inline bool Remove(KeyType const& pKey)
00649 {
00650 KEY_COMPARE_FUNCTOR lCompareKeys;
00651 bool lResult = false;
00652 RecordType* lNode = mRoot;
00653 while (lNode != 0)
00654 {
00655 if (lCompareKeys(lNode->GetKey(), pKey) < 0)
00656 {
00657 lNode = lNode->mRightChild;
00658 }
00659 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
00660 {
00661 lNode = lNode->mLeftChild;
00662 }
00663 else
00664 {
00665 break;
00666 }
00667 }
00668
00669 if (lNode)
00670 {
00671 RemoveNode(lNode);
00672 mSize--;
00673 lNode->~RecordType();
00674 mAllocator.FreeMemory(lNode);
00675
00676 lResult = true;
00677 }
00678
00679 #ifdef SANITY_CHECK
00680 IsSane();
00681 #endif
00682
00683 return lResult;
00684 }
00685
00688 inline void Clear()
00689 {
00690 if (mRoot)
00691 {
00692 ClearSubTree(mRoot->mLeftChild);
00693 ClearSubTree(mRoot->mRightChild);
00694 mRoot->~RecordType();
00695 mAllocator.FreeMemory(mRoot);
00696 mRoot = 0;
00697 mSize = 0;
00698 }
00699 }
00700
00704 inline RecordType const* Minimum() const
00705 {
00706 if (0 != mRoot)
00707 {
00708 return mRoot->Minimum();
00709 }
00710 else
00711 {
00712 return 0;
00713 }
00714 }
00715
00719 inline RecordType* Minimum()
00720 {
00721 if (0 != mRoot)
00722 {
00723 return mRoot->Minimum();
00724 }
00725 else
00726 {
00727 return 0;
00728 }
00729 }
00730
00734 inline RecordType const* Maximum() const
00735 {
00736 if (0 != mRoot)
00737 {
00738 return mRoot->Maximum();
00739 }
00740 else
00741 {
00742 return 0;
00743 }
00744 }
00745
00749 inline RecordType* Maximum()
00750 {
00751 if (0 != mRoot)
00752 {
00753 return mRoot->Maximum();
00754 }
00755 else
00756 {
00757 return 0;
00758 }
00759 }
00760
00765 inline RecordType const* Find(KeyType const& pKey) const
00766 {
00767 KEY_COMPARE_FUNCTOR lCompareKeys;
00768 RecordType const* lNode = mRoot;
00769 while (lNode != 0)
00770 {
00771 if (lCompareKeys(lNode->GetKey(), pKey) < 0)
00772 {
00773 lNode = lNode->mRightChild;
00774 }
00775 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
00776 {
00777 lNode = lNode->mLeftChild;
00778 }
00779 else
00780 {
00781 break;
00782 }
00783 }
00784
00785 return lNode;
00786 }
00787
00792 inline RecordType* Find(KeyType const& pKey)
00793 {
00794 KEY_COMPARE_FUNCTOR lCompareKeys;
00795 RecordType* lNode = mRoot;
00796 while (lNode != 0)
00797 {
00798 if (lCompareKeys(lNode->GetKey(), pKey) < 0)
00799 {
00800 lNode = lNode->mRightChild;
00801 }
00802 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
00803 {
00804 lNode = lNode->mLeftChild;
00805 }
00806 else
00807 {
00808 break;
00809 }
00810 }
00811
00812 return lNode;
00813 }
00814
00819 inline RecordType const* UpperBound(KeyType const& pKey) const
00820 {
00821 KEY_COMPARE_FUNCTOR lCompareKeys;
00822 RecordType const* lNode = mRoot;
00823 RecordType const* lCandidate = 0;
00824 while (lNode != 0)
00825 {
00826 if (lCompareKeys(lNode->GetKey(), pKey) <= 0)
00827 {
00828 lNode = lNode->mRightChild;
00829 }
00830 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
00831 {
00832 lCandidate = lNode;
00833 lNode = lNode->mLeftChild;
00834 }
00835 }
00836
00837 return lCandidate;
00838 }
00839
00844 inline RecordType* UpperBound(KeyType const& pKey)
00845 {
00846 KEY_COMPARE_FUNCTOR lCompareKeys;
00847 RecordType* lNode = mRoot;
00848 RecordType* lCandidate = 0;
00849 while (lNode != 0)
00850 {
00851 if (lCompareKeys(lNode->GetKey(), pKey) <= 0)
00852 {
00853 lNode = lNode->mRightChild;
00854 }
00855 else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
00856 {
00857 lCandidate = lNode;
00858 lNode = lNode->mLeftChild;
00859 }
00860 }
00861
00862 return lCandidate;
00863 }
00864
00865 protected:
00866 RecordType* mRoot;
00867 int mSize;
00868
00869 AllocatorType mAllocator;
00870
00875 inline void IsSane()
00876 {
00877 K_ASSERT((mRoot == 0) || (mRoot->mColor == RecordType::eBlack));
00878 K_ASSERT(((mRoot == 0) && (mSize == 0)) || (mRoot != 0) && (mSize != 0));
00879 IsSubTreeSane(mRoot);
00880
00881 ComputeBlackDepth(mRoot, 0);
00882
00883 RecordType* lNode = mRoot;
00884 unsigned int lLeafBlackDepth = 0;
00885 while (lNode)
00886 {
00887 if (lNode->mLeftChild == 0)
00888 {
00889 lLeafBlackDepth = lNode->mBlackDepth + ((lNode->mColor == RecordType::eBlack) ? 1 : 0);
00890 }
00891
00892 lNode = lNode->mLeftChild;
00893 }
00894
00895 CheckLeavesBlackDepth(mRoot, lLeafBlackDepth);
00896 }
00897
00898 inline void IsSubTreeSane(RecordType const* pNode) const
00899 {
00900 KEY_COMPARE_FUNCTOR lCompareKeys;
00901
00902 if (pNode)
00903 {
00904 K_ASSERT(pNode != pNode->mParent);
00905 K_ASSERT(pNode != pNode->mLeftChild);
00906 K_ASSERT(pNode != pNode->mRightChild);
00907
00908
00909 K_ASSERT((pNode->mColor == RecordType::eBlack) ||
00910 (pNode->mLeftChild == NULL) ||
00911 (pNode->mLeftChild->mColor == RecordType::eBlack));
00912
00913 K_ASSERT((pNode->mColor == RecordType::eBlack) ||
00914 (pNode->mRightChild == NULL) ||
00915 (pNode->mRightChild->mColor == RecordType::eBlack));
00916
00917
00918 K_ASSERT((pNode->mLeftChild == 0 ||
00919 lCompareKeys(pNode->GetKey(), pNode->mLeftChild->GetKey()) > 0));
00920
00921 K_ASSERT((pNode->mRightChild == 0 ||
00922 lCompareKeys(pNode->GetKey(), pNode->mRightChild->GetKey()) < 0));
00923
00924 IsSubTreeSane(pNode->mLeftChild);
00925 IsSubTreeSane(pNode->mRightChild);
00926 }
00927 }
00928
00929 inline void ComputeBlackDepth(RecordType* pNode, unsigned int pDepth)
00930 {
00931 if (pNode)
00932 {
00933 pNode->mBlackDepth = pDepth;
00934 if (pNode->mColor == RecordType::eBlack)
00935 {
00936 pDepth++;
00937 }
00938
00939 ComputeBlackDepth(pNode->mLeftChild, pDepth);
00940 ComputeBlackDepth(pNode->mRightChild, pDepth);
00941 }
00942 }
00943
00944 inline void CheckLeavesBlackDepth(RecordType* pNode, unsigned int pBlackDepth)
00945 {
00946 if (pNode)
00947 {
00948 if ((pNode->mLeftChild == 0) || pNode->mRightChild == 0)
00949 {
00950 int lBlackDepth = pNode->mBlackDepth + ((pNode->mColor == RecordType::eBlack) ? 1 : 0);
00951 K_ASSERT(lBlackDepth == pBlackDepth);
00952 }
00953
00954 CheckLeavesBlackDepth(pNode->mLeftChild, pBlackDepth);
00955 CheckLeavesBlackDepth(pNode->mRightChild, pBlackDepth);
00956 }
00957 }
00958
00959 inline RecordType* DuplicateSubTree(RecordType const* pNode)
00960 {
00961 RecordType* lNewSubTree = 0;
00962
00963 if (pNode)
00964 {
00965 void* lBuffer = mAllocator.AllocateRecords();
00966 #if ( defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
00967 #pragma push_macro("new")
00968 #undef new
00969 #endif
00970 lNewSubTree = new(lBuffer) RecordType(*pNode);
00971 #if ( defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
00972 #pragma pop_macro("new")
00973 #endif
00974 lNewSubTree->mLeftChild = DuplicateSubTree(pNode->mLeftChild);
00975 lNewSubTree->mRightChild = DuplicateSubTree(pNode->mRightChild);
00976
00977 if (lNewSubTree->mLeftChild)
00978 {
00979 lNewSubTree->mLeftChild->mParent = lNewSubTree;
00980 }
00981
00982 if (lNewSubTree->mRightChild)
00983 {
00984 lNewSubTree->mRightChild->mParent = lNewSubTree;
00985 }
00986 }
00987
00988 return lNewSubTree;
00989 }
00990
00991 inline void FixNodesAfterInsertion(RecordType* pNode)
00992 {
00993 RecordType* lNode = pNode;
00994 bool lDone = false;
00995
00996 while (!lDone)
00997 {
00998 lDone = true;
00999
01000 if (lNode->mParent == 0)
01001 {
01002 lNode->mColor = RecordType::eBlack;
01003 }
01004 else if (lNode->mParent->mColor == RecordType::eRed)
01005 {
01006 RecordType* lUncle = 0;
01007 if (lNode->mParent == lNode->mParent->mParent->mLeftChild)
01008 {
01009 lUncle = lNode->mParent->mParent->mRightChild;
01010 }
01011 else if (lNode->mParent == lNode->mParent->mParent->mRightChild)
01012 {
01013 lUncle = lNode->mParent->mParent->mLeftChild;
01014 }
01015
01016
01017
01018 if (lUncle && lUncle->mColor == RecordType::eRed)
01019 {
01020 lNode->mParent->mColor = RecordType::eBlack;
01021 lUncle->mColor = RecordType::eBlack;
01022 lNode->mParent->mParent->mColor = RecordType::eRed;
01023 lNode = lNode->mParent->mParent;
01024
01025 lDone = false;
01026 }
01027 else
01028 {
01029 if ((lNode == lNode->mParent->mRightChild) &&
01030 (lNode->mParent == lNode->mParent->mParent->mLeftChild))
01031 {
01032 LeftRotate(lNode->mParent);
01033 lNode = lNode->mLeftChild;
01034 }
01035 else if ((lNode == lNode->mParent->mLeftChild) &&
01036 (lNode->mParent == lNode->mParent->mParent->mRightChild))
01037 {
01038 RightRotate(lNode->mParent);
01039 lNode = lNode->mRightChild;
01040 }
01041
01042 lNode->mParent->mColor = RecordType::eBlack;
01043 lNode->mParent->mParent->mColor = RecordType::eRed;
01044 if ((lNode == lNode->mParent->mLeftChild) &&
01045 (lNode->mParent == lNode->mParent->mParent->mLeftChild))
01046 {
01047 RightRotate(lNode->mParent->mParent);
01048 }
01049 else
01050 {
01051 LeftRotate(lNode->mParent->mParent);
01052 }
01053 }
01054 }
01055 }
01056
01057 mRoot->mColor = RecordType::eBlack;
01058 }
01059
01060 inline void LeftRotate(RecordType* pNode)
01061 {
01062 RecordType* lNode = pNode->mRightChild;
01063
01064 #ifdef _DEBUG
01065 RecordType* A = pNode->mLeftChild;
01066 RecordType* B = lNode->mLeftChild;
01067 RecordType* C = lNode->mRightChild;
01068 RecordType* Z = pNode->mParent;
01069 #endif
01070
01071 pNode->mRightChild = lNode->mLeftChild;
01072 if (pNode->mRightChild)
01073 {
01074 pNode->mRightChild->mParent = pNode;
01075 }
01076
01077 lNode->mParent = pNode->mParent;
01078 if (pNode->mParent == 0)
01079 {
01080 K_ASSERT(mRoot == pNode);
01081 mRoot = lNode;
01082 }
01083 else if (pNode == pNode->mParent->mLeftChild)
01084 {
01085 pNode->mParent->mLeftChild = lNode;
01086 }
01087 else
01088 {
01089 pNode->mParent->mRightChild = lNode;
01090 }
01091 pNode->mParent = lNode;
01092 lNode->mLeftChild = pNode;
01093
01094 K_ASSERT(pNode->mLeftChild == A);
01095 K_ASSERT(pNode->mRightChild == B);
01096 K_ASSERT(pNode->mParent == lNode);
01097
01098 K_ASSERT(lNode->mLeftChild == pNode);
01099 K_ASSERT(lNode->mRightChild == C);
01100 K_ASSERT(lNode->mParent == Z);
01101
01102 K_ASSERT(A == 0 || A->mParent == pNode);
01103 K_ASSERT(B == 0 || B->mParent == pNode);
01104 K_ASSERT(C == 0 || C->mParent == lNode);
01105 K_ASSERT(Z == 0 || Z->mLeftChild == lNode || Z->mRightChild == lNode);
01106 }
01107
01108
01109 inline void RightRotate(RecordType* pNode)
01110 {
01111 RecordType* lNode = pNode->mLeftChild;
01112
01113 #ifdef _DEBUG
01114 RecordType* A = lNode->mLeftChild;
01115 RecordType* B = lNode->mRightChild;
01116 RecordType* C = pNode->mRightChild;
01117 RecordType* Z = pNode->mParent;
01118 #endif
01119
01120 pNode->mLeftChild = lNode->mRightChild;
01121 if (pNode->mLeftChild)
01122 {
01123 pNode->mLeftChild->mParent = pNode;
01124 }
01125
01126 lNode->mParent = pNode->mParent;
01127 if (pNode->mParent == 0)
01128 {
01129 K_ASSERT(mRoot == pNode);
01130 mRoot = lNode;
01131 }
01132 else if (pNode == pNode->mParent->mRightChild)
01133 {
01134 pNode->mParent->mRightChild = lNode;
01135 }
01136 else
01137 {
01138 pNode->mParent->mLeftChild = lNode;
01139 }
01140 pNode->mParent = lNode;
01141 lNode->mRightChild = pNode;
01142
01143 K_ASSERT(lNode->mLeftChild == A);
01144 K_ASSERT(lNode->mRightChild == pNode);
01145 K_ASSERT(lNode->mParent == Z);
01146
01147 K_ASSERT(pNode->mLeftChild == B);
01148 K_ASSERT(pNode->mRightChild == C);
01149 K_ASSERT(pNode->mParent == lNode);
01150
01151 K_ASSERT(A == 0 || A->mParent == lNode);
01152 K_ASSERT(B == 0 || B->mParent == pNode);
01153 K_ASSERT(C == 0 || C->mParent == pNode);
01154 K_ASSERT(Z == 0 || Z->mLeftChild == lNode || Z->mRightChild == lNode);
01155 }
01156
01157
01158 inline void RemoveNode(RecordType* pNode)
01159 {
01160 if (pNode->mLeftChild == 0)
01161 {
01162 if (pNode->mRightChild == 0)
01163 {
01164 if (pNode->mParent)
01165 {
01166 if (pNode->mParent->mLeftChild == pNode)
01167 {
01168 pNode->mParent->mLeftChild = 0;
01169 }
01170 else if (pNode->mParent->mRightChild == pNode)
01171 {
01172 pNode->mParent->mRightChild = 0;
01173 }
01174 else
01175 {
01176 K_ASSERT_MSG_NOW("Node not found in KRedBlackTree");
01177 }
01178 }
01179 else
01180 {
01181 K_ASSERT(mRoot == pNode);
01182 mRoot = 0;
01183 }
01184
01185 if (pNode->mColor == RecordType::eBlack)
01186 {
01187 FixNodesAfterRemoval(pNode->mParent, 0);
01188 }
01189 }
01190 else
01191 {
01192 if (pNode->mParent)
01193 {
01194 if (pNode->mParent->mLeftChild == pNode)
01195 {
01196 pNode->mParent->mLeftChild = pNode->mRightChild;
01197 pNode->mRightChild->mParent = pNode->mParent;
01198 }
01199 else if (pNode->mParent->mRightChild == pNode)
01200 {
01201 pNode->mParent->mRightChild = pNode->mRightChild;
01202 pNode->mRightChild->mParent = pNode->mParent;
01203 }
01204 else
01205 {
01206 K_ASSERT_MSG_NOW("Node not found in KRedBlackTree");
01207 }
01208 }
01209 else
01210 {
01211 K_ASSERT(mRoot == pNode);
01212 mRoot = pNode->mRightChild;
01213 pNode->mRightChild->mParent = 0;
01214 }
01215
01216 if (pNode->mColor == RecordType::eBlack)
01217 {
01218 FixNodesAfterRemoval(pNode->mRightChild->mParent, pNode->mRightChild);
01219 }
01220 }
01221 }
01222 else
01223 {
01224 if (pNode->mRightChild == 0)
01225 {
01226 if (pNode->mParent)
01227 {
01228 if (pNode->mParent->mLeftChild == pNode)
01229 {
01230 pNode->mParent->mLeftChild = pNode->mLeftChild;
01231 pNode->mLeftChild->mParent = pNode->mParent;
01232 }
01233 else if (pNode->mParent->mRightChild == pNode)
01234 {
01235 pNode->mParent->mRightChild = pNode->mLeftChild;
01236 pNode->mLeftChild->mParent = pNode->mParent;
01237 }
01238 else
01239 {
01240 K_ASSERT_MSG_NOW("Node not found in KRedBlackTree");
01241 }
01242 }
01243 else
01244 {
01245 K_ASSERT(mRoot == pNode);
01246 mRoot = pNode->mLeftChild;
01247 pNode->mLeftChild->mParent = 0;
01248 }
01249
01250 if (pNode->mColor == RecordType::eBlack)
01251 {
01252 FixNodesAfterRemoval(pNode->mLeftChild->mParent, pNode->mLeftChild);
01253 }
01254 }
01255 else
01256 {
01257 RecordType* lMinRightNode = pNode->mRightChild->Minimum();
01258 RemoveNode(lMinRightNode);
01259
01260 lMinRightNode->mColor = pNode->mColor;
01261 ReplaceNode(pNode, lMinRightNode);
01262 }
01263 }
01264
01265 pNode->mParent = 0;
01266 pNode->mLeftChild = 0;
01267 pNode->mRightChild = 0;
01268 }
01269
01270
01271 inline void ReplaceNode(RecordType* pNodeToReplace, RecordType* pReplacement)
01272 {
01273 pReplacement->mParent = pNodeToReplace->mParent;
01274 if (pNodeToReplace->mParent)
01275 {
01276 if (pNodeToReplace->mParent->mLeftChild == pNodeToReplace)
01277 {
01278 pNodeToReplace->mParent->mLeftChild = pReplacement;
01279 }
01280 else if (pNodeToReplace->mParent->mRightChild == pNodeToReplace)
01281 {
01282 pNodeToReplace->mParent->mRightChild = pReplacement;
01283 }
01284 }
01285 else
01286 {
01287 K_ASSERT(mRoot == pNodeToReplace);
01288 mRoot = pReplacement;
01289 }
01290
01291 pReplacement->mLeftChild = pNodeToReplace->mLeftChild;
01292 if (pReplacement->mLeftChild)
01293 {
01294 pReplacement->mLeftChild->mParent = pReplacement;
01295 }
01296
01297 pReplacement->mRightChild = pNodeToReplace->mRightChild;
01298 if (pReplacement->mRightChild)
01299 {
01300 pReplacement->mRightChild->mParent = pReplacement;
01301 }
01302 }
01303
01304 inline RecordType* Sibling(RecordType const* pParent, RecordType const* pNode) const
01305 {
01306 if (pParent)
01307 {
01308 if (pParent->mLeftChild == pNode)
01309 {
01310 return pParent->mRightChild;
01311 }
01312 else if (pParent->mRightChild == pNode)
01313 {
01314 return pParent->mLeftChild;
01315 }
01316 }
01317
01318 return 0;
01319 }
01320
01321 inline bool IsBlack(RecordType const* pNode)
01322 {
01323 return ((pNode == 0) || (pNode->mColor == RecordType::eBlack));
01324 }
01325
01326 inline void FixNodesAfterRemoval(RecordType* pParent, RecordType* pNode)
01327 {
01328 RecordType* lParent = pParent;
01329 RecordType* lNode = pNode;
01330 bool lDone = false;
01331
01332 while (!lDone)
01333 {
01334 lDone = true;
01335
01336 if (!IsBlack(lNode))
01337 {
01338 lNode->mColor = RecordType::eBlack;
01339 }
01340 else if (lParent != NULL)
01341 {
01342 RecordType* lSibling = Sibling(lParent, lNode);
01343
01344 if (!IsBlack(lSibling))
01345 {
01346 lParent->mColor = RecordType::eRed;
01347 lSibling->mColor = RecordType::eBlack;
01348 if (lNode == lParent->mLeftChild)
01349 {
01350 LeftRotate(lParent);
01351 }
01352 else
01353 {
01354 RightRotate(lParent);
01355 }
01356
01357
01358
01359 lSibling = Sibling(lParent, lNode);
01360 }
01361
01362
01363 if (lSibling &&
01364 IsBlack(lParent) &&
01365 IsBlack(lSibling) &&
01366 IsBlack(lSibling->mLeftChild) &&
01367 IsBlack(lSibling->mRightChild))
01368 {
01369 lSibling->mColor = RecordType::eRed;
01370 lNode = lParent;
01371 lParent = lParent->mParent;
01372 lDone = false;
01373 }
01374 else
01375 {
01376 if (!IsBlack(lParent) &&
01377 IsBlack(lSibling) &&
01378 ((lSibling == 0) || IsBlack(lSibling->mLeftChild)) &&
01379 ((lSibling == 0) || IsBlack(lSibling->mRightChild)))
01380 {
01381 if (lSibling)
01382 {
01383 lSibling->mColor = RecordType::eRed;
01384 }
01385 lParent->mColor = RecordType::eBlack;
01386 }
01387 else
01388 {
01389 if ((lNode == lParent->mLeftChild) &&
01390 IsBlack(lSibling) &&
01391 !IsBlack(lSibling->mLeftChild) &&
01392 IsBlack(lSibling->mRightChild))
01393 {
01394 lSibling->mColor = RecordType::eRed;
01395 lSibling->mLeftChild->mColor = RecordType::eBlack;
01396 RightRotate(lSibling);
01397 }
01398 else if ((lNode == lParent->mRightChild) &&
01399 IsBlack(lSibling) &&
01400 IsBlack(lSibling->mLeftChild) &&
01401 !IsBlack(lSibling->mRightChild))
01402 {
01403 lSibling->mColor = RecordType::eRed;
01404 lSibling->mRightChild->mColor = RecordType::eBlack;
01405 LeftRotate(lSibling);
01406 }
01407
01408
01409 lSibling = Sibling(lParent, lNode);
01410 K_ASSERT(lSibling != 0);
01411
01412
01413
01414
01415 lSibling->mColor = lParent->mColor;
01416 lParent->mColor = RecordType::eBlack;
01417 if (lNode == lParent->mLeftChild)
01418 {
01419 if (lSibling->mRightChild)
01420 {
01421 lSibling->mRightChild->mColor = RecordType::eBlack;
01422 }
01423 LeftRotate(lParent);
01424 }
01425 else
01426 {
01427 if (lSibling->mLeftChild)
01428 {
01429 lSibling->mLeftChild->mColor = RecordType::eBlack;
01430 }
01431 RightRotate(lParent);
01432 }
01433 }
01434 }
01435 }
01436 }
01437
01438 if (mRoot)
01439 {
01440 mRoot->mColor = RecordType::eBlack;
01441 }
01442 }
01443
01444
01445 inline void ClearSubTree(RecordType* pNode)
01446 {
01447 if (pNode)
01448 {
01449 ClearSubTree(pNode->mLeftChild);
01450 ClearSubTree(pNode->mRightChild);
01451 pNode->~RecordType();
01452 mAllocator.FreeMemory(pNode);
01453 }
01454 }
01455
01456 inline int GetSubTreeSize(RecordType* pNode) const
01457 {
01458 if (pNode)
01459 {
01460 return GetSubTreeSize(pNode->mLeftChild) + GetSubTreeSize(pNode->mRightChild) + 1;
01461 }
01462 else
01463 {
01464 return 0;
01465 }
01466 }
01467
01468 };
01469
01470
01471
01472
01473
01474
01475
01476 template <typename T>
01477 struct KFbxLessCompare
01478 {
01479 inline int operator()(const T& left, const T& right) const
01480 {
01481 return (left < right) ? -1 : ((right < left) ? 1 : 0);
01482 }
01483 };
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493 template <typename KEY_TYPE,
01494 typename VALUE_TYPE,
01495 typename KEY_COMPARE_FUNCTOR = KFbxLessCompare<KEY_TYPE>,
01496 typename ALLOCATOR = KBaseAllocator>
01497 class KMap
01498 {
01499 protected:
01500 class KKeyValuePair : private KPair<const KEY_TYPE, VALUE_TYPE>
01501 {
01502 public:
01503 KKeyValuePair(KEY_TYPE const& pFirst, VALUE_TYPE const& pSecond)
01504 : KPair<const KEY_TYPE, VALUE_TYPE>(pFirst, pSecond) {}
01505
01506
01507 typedef const KEY_TYPE KeyType;
01508 typedef const KEY_TYPE ConstKeyType;
01509 typedef VALUE_TYPE ValueType;
01510 typedef const VALUE_TYPE ConstValueType;
01511
01512 ConstKeyType & GetKey() const { return this->mFirst; }
01513 KeyType & GetKey() { return this->mFirst; }
01514
01515 ConstValueType& GetValue() const { return this->mSecond; }
01516 ValueType& GetValue() { return this->mSecond; }
01517 };
01518
01519 typedef KRedBlackTree<KKeyValuePair, KEY_COMPARE_FUNCTOR, ALLOCATOR> StorageType;
01520 StorageType mTree;
01521
01522
01523 public:
01524 typedef VALUE_TYPE ValueType;
01525 typedef KEY_TYPE KeyType;
01526 typedef typename StorageType::RecordType RecordType;
01527 typedef typename StorageType::IteratorType Iterator;
01528 typedef typename StorageType::ConstIteratorType ConstIterator;
01529
01530 inline KMap() {}
01531 inline KMap(KMap const& pMap) : mTree(pMap.mTree) {}
01532 inline ~KMap() {Clear();}
01533
01534 inline void Reserve(unsigned int pRecordCount)
01535 {
01536 mTree.Reserve(pRecordCount);
01537 }
01538
01539 inline int GetSize() const
01540 {
01541 return mTree.GetSize();
01542 }
01543
01544 inline KPair<RecordType*, bool> Insert(KeyType const& pKey, ValueType const& pValue)
01545 {
01546 return mTree.Insert(KKeyValuePair(pKey, pValue));
01547 }
01548
01549 inline int Remove(KeyType const& pKey)
01550 {
01551 return mTree.Remove(pKey);
01552 }
01553
01554 inline void Clear()
01555 {
01556 mTree.Clear();
01557 }
01558
01559 inline bool Empty() const
01560 {
01561 return mTree.Empty();
01562 }
01563
01564 Iterator Begin()
01565 {
01566 return Iterator(Minimum());
01567 }
01568
01569 Iterator End()
01570 {
01571 return Iterator();
01572 }
01573
01574 ConstIterator Begin() const
01575 {
01576 return ConstIterator(Minimum());
01577 }
01578
01579 ConstIterator End() const
01580 {
01581 return ConstIterator();
01582 }
01583
01584 inline RecordType const* Find(KeyType const& pKey) const
01585 {
01586 return mTree.Find(pKey);
01587 }
01588
01589 inline RecordType* Find(KeyType const& pKey)
01590 {
01591 return mTree.Find(pKey);
01592 }
01593
01594 inline RecordType const* UpperBound(KeyType const& pKey) const
01595 {
01596 return mTree.UpperBound(pKey);
01597 }
01598
01599 inline RecordType* UpperBound(KeyType const& pKey)
01600 {
01601 return mTree.UpperBound(pKey);
01602 }
01603
01604 inline ValueType& operator[](KeyType const& pKey)
01605 {
01606 RecordType* lRecord = Find(pKey);
01607
01608 if( !lRecord )
01609 {
01610 lRecord = Insert(pKey, ValueType()).mFirst;
01611 }
01612
01613 return lRecord->GetValue();
01614 }
01615
01616 inline RecordType const* Minimum() const
01617 {
01618 return mTree.Minimum();
01619 }
01620
01621 inline RecordType* Minimum()
01622 {
01623 return mTree.Minimum();
01624 }
01625
01626 inline RecordType const* Maximum() const
01627 {
01628 return mTree.Maximum();
01629 }
01630
01631 inline RecordType* Maximum()
01632 {
01633 return mTree.Maximum();
01634 }
01635 };
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645 template <typename VALUE_TYPE,
01646 typename KEY_COMPARE_FUNCTOR = KFbxLessCompare<VALUE_TYPE>,
01647 typename ALLOCATOR = KBaseAllocator>
01648 class KSet2
01649 {
01650 protected:
01651 class KValue
01652 {
01653 public:
01654 inline KValue(VALUE_TYPE const& pValue)
01655 : mValue(pValue) {}
01656
01657
01658 typedef const VALUE_TYPE KeyType;
01659 typedef const VALUE_TYPE ConstKeyType;
01660 typedef const VALUE_TYPE ValueType;
01661 typedef const VALUE_TYPE ConstValueType;
01662
01663 inline KeyType& GetKey() const { return mValue; }
01664 inline ConstKeyType& GetKey() { return mValue; }
01665
01666 inline ValueType& GetValue() const { return mValue; }
01667 inline ConstValueType& GetValue() { return mValue; }
01668
01669 protected:
01670 ValueType mValue;
01671 };
01672
01673 typedef KRedBlackTree<KValue, KEY_COMPARE_FUNCTOR, ALLOCATOR> StorageType;
01674 StorageType mTree;
01675
01676
01677 public:
01678 typedef VALUE_TYPE ValueType;
01679 typedef typename StorageType::RecordType RecordType;
01680 typedef typename StorageType::IteratorType Iterator;
01681 typedef typename StorageType::ConstIteratorType ConstIterator;
01682
01683 inline KSet2() {}
01684 inline KSet2(KSet2 const& pSet) : mTree(pSet.mTree) {}
01685 inline ~KSet2() {Clear();}
01686
01687 inline void Reserve(unsigned int pRecordCount)
01688 {
01689 mTree.Reserve(pRecordCount);
01690 }
01691
01692 inline int GetSize() const
01693 {
01694 return mTree.GetSize();
01695 }
01696
01697 inline KPair<RecordType*, bool> Insert(ValueType const& pValue)
01698 {
01699 return mTree.Insert(KValue(pValue));
01700 }
01701
01702 inline int Remove(ValueType const& pValue)
01703 {
01704 return mTree.Remove(pValue);
01705 }
01706
01707 inline void Clear()
01708 {
01709 mTree.Clear();
01710 }
01711
01712 inline bool Empty() const
01713 {
01714 return mTree.Empty();
01715 }
01716
01717 Iterator Begin()
01718 {
01719 return Iterator(Minimum());
01720 }
01721
01722 Iterator End()
01723 {
01724 return Iterator();
01725 }
01726
01727 ConstIterator Begin() const
01728 {
01729 return ConstIterator(Minimum());
01730 }
01731
01732 ConstIterator End() const
01733 {
01734 return ConstIterator();
01735 }
01736
01737 inline RecordType const* Find(ValueType const& pValue) const
01738 {
01739 return mTree.Find(pValue);
01740 }
01741
01742 inline RecordType* Find(ValueType const& pValue)
01743 {
01744 return mTree.Find(pValue);
01745 }
01746
01747 inline RecordType const* Minimum() const
01748 {
01749 return mTree.Minimum();
01750 }
01751
01752 inline RecordType* Minimum()
01753 {
01754 return mTree.Minimum();
01755 }
01756
01757 inline RecordType const* Maximum() const
01758 {
01759 return mTree.Maximum();
01760 }
01761
01762 inline RecordType* Maximum()
01763 {
01764 return mTree.Maximum();
01765 }
01766
01767 inline bool operator==(const KSet2<VALUE_TYPE, KEY_COMPARE_FUNCTOR, ALLOCATOR>& pOther) const
01768 {
01769 return (this == &pOther) || (mTree == pOther.mTree);
01770 }
01771
01772 inline bool operator != (const KSet2<VALUE_TYPE, KEY_COMPARE_FUNCTOR, ALLOCATOR>& pOther) const
01773 {
01774 return !(*this == pOther);
01775 }
01776 };
01777 #include <fbxfilesdk/fbxfilesdk_nsend.h>
01778
01779 #endif // FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KMAP_H
01780