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