00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef FAUDES_BASESET_H
00026 #define FAUDES_BASESET_H
00027
00028 #include "definitions.h"
00029 #include "interface.h"
00030 #include "tokenwriter.h"
00031 #include "tokenreader.h"
00032 #include <set>
00033 #include <algorithm>
00034
00035 namespace faudes {
00036
00084 template<class T, class Cmp=std::less<T> >
00085 class TBaseSet : FAUDES_TYPE {
00086
00087 public:
00088
00092 TBaseSet(void);
00093
00100 TBaseSet(const TBaseSet& rOtherSet);
00101
00105 virtual ~TBaseSet(void);
00106
00113 std::string Name(void) const;
00114
00121 void Name(const std::string& rName);
00122
00126 virtual void Clear(void);
00127
00134 Idx Size(void) const;
00135
00142 bool Empty(void) const;
00143
00148 class Iterator;
00149
00156 Iterator Begin(void) const;
00157
00164 Iterator End(void) const;
00165
00177 virtual bool Valid(const T& rElem) const;
00178
00179
00188 virtual bool Erase(const T& rElem);
00189
00190
00199 virtual Iterator Erase(const Iterator& pos);
00200
00201
00208 virtual void EraseSet(const TBaseSet& rOtherSet);
00209
00210
00219 virtual bool Insert(const T& rElem);
00220
00228 virtual void InsertSet(const TBaseSet& rOtherSet);
00229
00236 virtual void SetUnion(const TBaseSet& rOtherSet);
00237
00244 virtual void SetIntersection(const TBaseSet& rOtherSet);
00245
00246
00256 bool Exists(const T& rElem) const;
00257
00267 Iterator Find(const T& rElem) const;
00268
00275 TBaseSet operator + (const TBaseSet& rOtherSet) const;
00276
00283 TBaseSet operator - (const TBaseSet& rOtherSet) const;
00284
00291 TBaseSet operator * (const TBaseSet& rOtherSet) const;
00292
00293
00295 bool operator == (const TBaseSet& rOtherSet) const;
00296
00298 bool operator != (const TBaseSet& rOtherSet) const;
00299
00301 bool operator <= (const TBaseSet& rOtherSet) const;
00302
00304 bool operator >= (const TBaseSet& rOtherSet) const;
00305
00307 bool operator < (const TBaseSet& rOtherSet) const;
00308
00310 virtual const TBaseSet& operator=(const TBaseSet& rSrc) {return Assign(rSrc);};
00311
00313 void DValid(const std::string& rMessage="") const;
00314
00316 void Detach(void) const;
00317
00319 void Lock(void) const;
00320
00334 class Iterator : public std::set<T,Cmp>::const_iterator {
00335 public:
00337 Iterator() :
00338 std::set<T,Cmp>::const_iterator() ,
00339 pBaseSet(NULL),
00340 mAttached(false)
00341 {};
00342
00344 Iterator(
00345 const TBaseSet<T,Cmp>* pBaseSet,
00346 const typename std::set<T,Cmp>::const_iterator& sit) :
00347 std::set<T,Cmp>::const_iterator(sit),
00348 pBaseSet(pBaseSet),
00349 mAttached(false)
00350 {};
00351
00353 Iterator(const Iterator& fit) :
00354 std::set<T,Cmp>::const_iterator(fit),
00355 pBaseSet(fit.pBaseSet),
00356 mAttached(false)
00357 {
00358 if(pBaseSet) {
00359 pBaseSet->AttachIterator(this);
00360 mAttached=true;
00361 }
00362 };
00363
00365 ~Iterator(void) {
00366 if(mAttached) pBaseSet->DetachIterator(this);
00367 };
00368
00370 const Iterator& operator= (const Iterator& rSrc) {
00371 #ifdef FAUDES_DEBUG_CODE
00372 if(rSrc.pBaseSet==NULL) {
00373 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator= invalid iterator: no baseset");
00374 abort();
00375 }
00376 #endif
00377
00378 if(mAttached) if(pBaseSet==rSrc.pBaseSet) {
00379 std::set<T,Cmp>::const_iterator::operator= (rSrc);
00380 return *this;
00381 }
00382
00383 if(mAttached) pBaseSet->DetachIterator(this);
00384 std::set<T,Cmp>::const_iterator::operator= (rSrc);
00385 pBaseSet = rSrc.pBaseSet;
00386 if(pBaseSet) {
00387 pBaseSet->AttachIterator(this);
00388 mAttached=true;
00389 } else {
00390 mAttached=false;
00391 }
00392 return *this;
00393 };
00394
00396 void StlIterator(const typename std::set<T,Cmp>::const_iterator& sit) {
00397 std::set<T,Cmp>::const_iterator::operator= (sit);
00398 };
00399
00401 const typename std::set<T,Cmp>::const_iterator& StlIterator(void) const {
00402 return *this;
00403 };
00404
00406 void Invalidate(void) {
00407 pBaseSet=NULL;
00408 mAttached=false;
00409 };
00410
00412 void Detach(void) {
00413 mAttached=false;
00414 };
00415
00416
00418 void DValid(void) const {
00419 if(pBaseSet==NULL) {
00420 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):DValid(): invalid iterator: no baseset");
00421 abort();
00422 }
00423 pBaseSet->DValid();
00424 };
00425
00427 const T* operator-> (void) const {
00428 #ifdef FAUDES_DEBUG_CODE
00429 if(pBaseSet==NULL) {
00430 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator->: invalid iterator: no baseset");
00431 abort();
00432 }
00433 #endif
00434 return std::set<T,Cmp>::const_iterator::operator-> ();
00435 };
00436
00438 const T& operator* (void) const {
00439 #ifdef FAUDES_DEBUG_CODE
00440 if(pBaseSet==NULL) {
00441 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator*: invalid iterator: no baseset");
00442 abort();
00443 }
00444 #endif
00445 return std::set<T,Cmp>::const_iterator::operator* ();
00446 };
00447
00449 bool operator == (const Iterator& rOther) const {
00450 #ifdef FAUDES_DEBUG_CODE
00451 if(pBaseSet==NULL) {
00452 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator==: invalid iterator: no baseset");
00453 abort();
00454 }
00455 #endif
00456 return std::set<T,Cmp>::const_iterator::operator == (rOther);
00457 };
00458
00460 bool operator != (const Iterator& rOther) const {
00461 #ifdef FAUDES_DEBUG_CODE
00462 if(pBaseSet==NULL) {
00463 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator!=: invalid iterator: no baseset");
00464 abort();
00465 }
00466 #endif
00467 return std::set<T,Cmp>::const_iterator::operator != (rOther);
00468 };
00469
00471 Iterator operator++ (int step) {
00472 #ifdef FAUDES_DEBUG_CODE
00473 if(pBaseSet==NULL) {
00474 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator++: invalid iterator: no baseset");
00475 abort();
00476 }
00477 #endif
00478 Iterator old(pBaseSet,*this);
00479 std::set<T,Cmp>::const_iterator::operator++ (step);
00480 return old;
00481 };
00482
00484 const Iterator& operator++ (void) {
00485 #ifdef FAUDES_DEBUG_CODE
00486 if(pBaseSet==NULL) {
00487 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator++: invalid iterator: no baseset");
00488 abort();
00489 }
00490 #endif
00491 std::set<T,Cmp>::const_iterator::operator++ ();
00492 return *this;
00493 };
00494
00496 Iterator operator-- (int step) {
00497 #ifdef FAUDES_DEBUG_CODE
00498 if(pBaseSet==NULL) {
00499 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator--: invalid iterator: no baseset");
00500 abort();
00501 }
00502 #endif
00503 Iterator old(pBaseSet, *this);
00504 std::set<T,Cmp>::const_iterator::operator-- (step);
00505 return old;
00506 };
00507
00509 const Iterator& operator-- (void) {
00510 #ifdef FAUDES_DEBUG_CODE
00511 if(pBaseSet==NULL) {
00512 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator--: invalid iterator: no baseset");
00513 abort();
00514 }
00515 #endif
00516 std::set<T,Cmp>::const_iterator::operator-- ();
00517 return *this;
00518 };
00519
00520
00522
00523
00524
00525
00526
00527
00529 const TBaseSet<T,Cmp>* pBaseSet;
00530
00532 bool mAttached;
00533 };
00534
00535 #ifdef DONT_TRACK_REFERENCES
00536
00541 class Iterator : public std::set<T,Cmp>::const_iterator {
00542 public:
00543
00545 Iterator(void) :
00546 std::set<T,Cmp>::const_iterator()
00547 {};
00548
00550 Iterator(const Iterator& fit) :
00551 std::set<T,Cmp>::const_iterator(fit)
00552 {};
00553
00555 Iterator(const typename std::set<T,Cmp>::const_iterator& sit) :
00556 std::set<T,Cmp>::const_iterator(sit)
00557 {};
00558
00560 Iterator(
00561 const TBaseSet<T,Cmp>* pBaseSet,
00562 const typename std::set<T,Cmp>::const_iterator& sit) :
00563 std::set<T,Cmp>::const_iterator(sit)
00564 {};
00565
00567 void StlIterator(const typename std::set<T,Cmp>::const_iterator& sit) {
00568 std::set<T,Cmp>::const_iterator::operator= (sit);
00569 };
00570
00572 const typename std::set<T,Cmp>::const_iterator& StlIterator(void) const {
00573 return *this;
00574 };
00575
00577 void Invalidate(void) {};
00578
00579 };
00580
00581 #endif
00582
00583
00584 protected:
00585
00586
00598 virtual void DoDWrite(TokenWriter& rTw,const std::string& rLabel="", const Type* pContext=0) const;
00599
00616 virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="", const Type* pContext=0) const;
00617
00634 virtual void DoRead(TokenReader& rTr, const std::string& rLabel = "", const Type* pContext=0);
00635
00637 const TBaseSet<T,Cmp>& Assign(const TBaseSet<T,Cmp>& rOtherSet);
00638
00640 std::set<T,Cmp>* mpSet;
00641
00643 static std::set<T,Cmp> mEmptySet;
00644
00646 std::set<T,Cmp>* pSet;
00647
00649 typedef typename std::set<T,Cmp>::iterator iterator;
00650
00652 typedef typename std::set<T,Cmp>::const_iterator const_iterator;
00653
00655 typename TBaseSet<T,Cmp>::Iterator ThisIterator(const typename std::set<T,Cmp>::const_iterator& sit) const;
00656
00657
00658 private:
00659
00660
00662 std::string mMyName;
00663
00665 std::set< TBaseSet<T,Cmp>* > mReferences;
00666
00668 TBaseSet<T,Cmp>* pBaseSet;
00669
00671 bool mDetached;
00672
00674 bool mLocked;
00675
00677 void RelinkReferences(void);
00678
00680 void AttachReference(TBaseSet* pRef) const;
00681
00683 void DetachReference(TBaseSet* pRef) const;
00684
00686 std::set< Iterator* > mIterators;
00687
00689 void AttachIterator(Iterator* pFit) const;
00690
00692 void DetachIterator(Iterator* pFit) const;
00693
00694 };
00695
00696
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715 template<class T, class Cmp>
00716 std::set<T,Cmp> TBaseSet<T,Cmp>::mEmptySet=std::set<T,Cmp>();
00717
00718
00719
00720 template<class T, class Cmp>
00721 TBaseSet<T,Cmp>::TBaseSet(void) :
00722 mpSet(NULL),
00723 pSet(&mEmptySet),
00724 pBaseSet(this),
00725 mDetached(false),
00726 mLocked(false)
00727 {
00728 FD_DC("TBaseSet(" << this << ")::TBaseSet()");
00729
00730
00731
00732
00733
00734
00735
00736 mMyName="BaseSet";
00737 }
00738
00739
00740
00741
00742 template<class T, class Cmp>
00743 TBaseSet<T,Cmp>::TBaseSet(const TBaseSet& rOtherSet) :
00744 Type(rOtherSet),
00745 mpSet(NULL),
00746 pSet(NULL),
00747 pBaseSet(this),
00748 mDetached(false),
00749 mLocked(false)
00750 {
00751 FD_DC("TBaseSet(" << this << ")::TBaseSet(rOtherSet " << &rOtherSet << "): fake copy construct");
00752
00753 pBaseSet=rOtherSet.pBaseSet;
00754 pBaseSet->AttachReference(this);
00755 pSet=rOtherSet.pSet;
00756
00757 mMyName=rOtherSet.mMyName;
00758 #ifdef FAUDES_DEBUG_CONTAINER
00759 DValid();
00760 #endif
00761 }
00762
00763
00764 template<class T, class Cmp>
00765 TBaseSet<T,Cmp>::~TBaseSet(void) {
00766 FD_DC("TBaseSet(" << this << ")::~TBaseSet()");
00767
00768 RelinkReferences();
00769 pBaseSet->DetachReference(this);
00770 if(mpSet) delete mpSet;
00771
00772 typename std::set< Iterator* >::const_iterator iit;
00773 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
00774 (**iit).Invalidate();
00775 }
00776 }
00777
00778
00779 template<class T, class Cmp>
00780 const TBaseSet<T,Cmp>& TBaseSet<T,Cmp>::Assign(const TBaseSet<T,Cmp>& rOtherSet) {
00781 FD_DC("TBaseSet(" << this << ")::Assign(rOtherSet " << &rOtherSet << "): fake assignment");
00782
00783 if(this==&rOtherSet) return *this;
00784
00785 RelinkReferences();
00786 pBaseSet->DetachReference(this);
00787 mReferences.clear();
00788 pBaseSet=rOtherSet.pBaseSet;
00789 pBaseSet->AttachReference(this);
00790 pSet=rOtherSet.pSet;
00791 if(mpSet) {
00792 delete mpSet;
00793 mpSet=NULL;
00794 }
00795 mDetached=false;
00796 mLocked=false;
00797
00798 typename std::set< Iterator* >::iterator iit;
00799 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
00800 (**iit).Invalidate();
00801 }
00802 mIterators.clear();
00803
00804 mMyName=rOtherSet.mMyName;
00805 #ifdef FAUDES_DEBUG_CONTAINER
00806 DValid();
00807 #endif
00808 return *this;
00809 }
00810
00811
00812
00813 template<class T, class Cmp>
00814 void TBaseSet<T,Cmp>::Detach(void) const {
00815 FD_DC("TBaseSet(" << this << ")::Detach(void)");
00816 #ifdef FAUDES_DEBUG_CONTAINER
00817 DValid();
00818 #endif
00819
00820
00821 if(mDetached) return;
00822
00823
00824 TBaseSet<T,Cmp>* fake_const = const_cast< TBaseSet<T,Cmp>* >(this);
00825
00826
00827 if(pBaseSet->mReferences.empty() && pBaseSet->mpSet != NULL) {
00828 fake_const->mDetached=true;
00829 return;
00830 }
00831
00832
00833
00834
00835 if(mLocked==true) {
00836
00837 FD_DC("TBaseSet(" << this << ")::Detach(void): allocate and copy, strategie A");
00838
00839 std::set<T,Cmp>* copy = new std::set<T,Cmp>();
00840 *copy = *pSet;
00841
00842 TBaseSet<T,Cmp>* storage = *mReferences.begin();
00843 storage->pBaseSet=storage;
00844 storage->mpSet=copy;
00845 storage->pSet=copy;
00846 storage->mReferences=mReferences;
00847 storage->DetachReference(storage);
00848
00849 if(storage->mReferences.empty())
00850 storage->mDetached=true;
00851
00852 typename std::set< TBaseSet<T,Cmp>* >::const_iterator rit;
00853 for(rit=mReferences.begin(), ++rit ;rit!=mReferences.end(); ++rit) {
00854 (*rit)->pBaseSet=storage;
00855 (*rit)->pSet=copy;
00856 }
00857
00858 for(rit=mReferences.begin(); rit!=mReferences.end(); ++rit) {
00859 typename std::set< Iterator* >::iterator iit;
00860 for(iit=(*rit)->mIterators.begin(); iit!=(*rit)->mIterators.end(); ++iit) {
00861 if((**iit).StlIterator()==pSet->end())
00862 **iit=Iterator(this, copy->end());
00863 else
00864 **iit=Iterator(this, copy->find(***iit));
00865 }
00866 }
00867
00868 fake_const->mpSet=pSet;
00869 fake_const->mReferences.clear();
00870 fake_const->mDetached=true;
00871
00872 typename std::set< Iterator* >::const_iterator iit;
00873 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
00874 (**iit).Detach();
00875 }
00876 fake_const->mIterators.clear();
00877
00878
00879
00880
00881
00882 } else {
00883
00884
00885 FD_DC("TBaseSet(" << this << ")::Detach(void): allocate and copy, strategie B");
00886
00887 fake_const->RelinkReferences();
00888
00889 fake_const->mpSet = new std::set<T,Cmp>();
00890 *fake_const->mpSet= *pSet;
00891
00892 typename std::set< Iterator* >::iterator iit;
00893 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
00894 if((**iit).StlIterator()==pSet->end())
00895 **iit=Iterator(this, mpSet->end());
00896 else
00897 **iit=Iterator(this, mpSet->find(***iit));
00898 }
00899
00900 pBaseSet->DetachReference(fake_const);
00901 if(pBaseSet->pBaseSet->mReferences.empty() && pBaseSet->mpSet != NULL)
00902 pBaseSet->mDetached=true;
00903 fake_const->pBaseSet=fake_const;
00904 fake_const->pSet=mpSet;
00905 fake_const->mDetached=true;
00906
00907 }
00908
00909 #ifdef FAUDES_DEBUG_CONTAINER
00910 DValid();
00911 #endif
00912 FD_DC("TBaseSet(" << this << ")::Detach(void): done");
00913 }
00914
00915
00916 template<class T, class Cmp>
00917 void TBaseSet<T,Cmp>::Lock(void) const {
00918 FD_DC("TBaseSet(" << this << ")::Lock(void)");
00919 #ifdef FAUDES_DEBUG_CONTAINER
00920 DValid();
00921 #endif
00922
00923
00924 Detach();
00925
00926
00927 TBaseSet<T,Cmp>* fake_const = const_cast< TBaseSet<T,Cmp>* >(this);
00928
00929
00930 typename std::set< Iterator* >::const_iterator iit;
00931 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
00932 (**iit).Detach();
00933 }
00934 fake_const->mIterators.clear();
00935
00936
00937 fake_const->mLocked=true;
00938 }
00939
00940
00941
00942 template<class T, class Cmp>
00943 inline void TBaseSet<T,Cmp>::RelinkReferences(void) {
00944 FD_DC("TBaseSet::RelinkReferences(" << this << ")")
00945 #ifdef FAUDES_DEBUG_CONTAINER
00946 DValid();
00947 #endif
00948
00949 if(mReferences.empty()) return;
00950
00951 TBaseSet<T,Cmp>* storage = *mReferences.begin();
00952 #ifdef FAUDES_DEBUG_CODE
00953 if(storage->pBaseSet!=this) {
00954 FD_ERR("TBaseSet<T,Cmp>::RelinkRefernces: old reference must have this as storage provider");
00955 abort();
00956 }
00957 #endif
00958 storage->pBaseSet=storage;
00959 storage->mpSet=mpSet;
00960 storage->pSet=pSet;
00961 storage->mReferences=mReferences;
00962 storage->DetachReference(storage);
00963
00964 typename std::set< TBaseSet<T,Cmp>* >::const_iterator rit;
00965 for(rit=mReferences.begin(), ++rit;rit!=mReferences.end(); ++rit) {
00966 (*rit)->pBaseSet=storage;
00967 }
00968
00969 pBaseSet=storage;
00970 pSet=storage->pSet;
00971 mpSet=NULL;
00972 storage->AttachReference(this);
00973 mReferences.clear();
00974 #ifdef FAUDES_DEBUG_CONTAINER
00975 DValid();
00976 #endif
00977 FD_DC("TBaseSet::RelinkReferences(" << this << "): done")
00978 }
00979
00980
00981
00982 template<class T, class Cmp>
00983 inline void TBaseSet<T,Cmp>::AttachReference(TBaseSet* pRef) const {
00984 const_cast< TBaseSet<T,Cmp>* >(this)->mReferences.insert(pRef);
00985 const_cast< TBaseSet<T,Cmp>* >(this)->mDetached=false;
00986 }
00987
00988
00989 template<class T, class Cmp>
00990 inline void TBaseSet<T,Cmp>::DetachReference(TBaseSet* pRef) const {
00991 const_cast< TBaseSet<T,Cmp>* >(this)->mReferences.erase(pRef);
00992 }
00993
00994
00995
00996 template<class T, class Cmp>
00997 inline void TBaseSet<T,Cmp>::AttachIterator(Iterator* pFit) const {
00998 if(mLocked) return;
00999 FD_DC("TBaseSet::AttachIterator(" << this << "):" << pFit)
01000 const_cast< TBaseSet<T,Cmp>* >(this)->mIterators.insert(pFit);
01001 }
01002
01003
01004 template<class T, class Cmp>
01005 inline void TBaseSet<T,Cmp>::DetachIterator(Iterator* pFit) const {
01006 if(mLocked) return;
01007 FD_DC("TBaseSet::DetachIterator(" << this << "):" << pFit)
01008 const_cast< TBaseSet<T,Cmp>* >(this)->mIterators.erase(pFit);
01009 }
01010
01011
01012
01013
01014 template<class T, class Cmp>
01015 void TBaseSet<T,Cmp>::DValid(const std::string& rMessage) const {
01016 typename std::set< Iterator* >::const_iterator iit;
01017 #ifdef FAUDES_DEBUG_CONTAINER
01018 std::cout << "TBaseSet<T,Cmp>(" << this << "," << rMessage << ")::DValid: source "
01019 << pBaseSet << " #" << (pBaseSet->pSet==&mEmptySet ? "e" : "f") << " -- list: ";
01020 typename std::set< TBaseSet<T,Cmp>* >::const_iterator rit;
01021 for(rit=pBaseSet->mReferences.begin(); rit!=pBaseSet->mReferences.end(); ++rit)
01022 std::cout << *rit << " ";
01023 std::cout << "-- iterators: ";
01024 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit)
01025 std::cout << *iit << " ";
01026 std::cout << "." << std::endl;
01027 #endif
01028
01029 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01030 if((*iit)->pBaseSet!=this) {
01031 FD_ERR("TBaseSet<T,Cmp>("<< this << "," << rMessage <<"): invalid iterator (baseset): "<< *iit);
01032 abort();
01033 }
01034 }
01035
01036 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01037 if(!(*iit)->mAttached) {
01038 FD_ERR("TBaseSet<T,Cmp>("<< this << "," << rMessage <<"): invalid iterator (attached): "<< *iit);
01039 abort();
01040 }
01041 }
01042
01043 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01044 typename std::set<T,Cmp>::const_iterator vit;
01045 for(vit=pSet->begin(); vit!= pSet->end(); ++vit) {
01046 if(vit==(**iit).StlIterator()) break;
01047 }
01048 if(vit!=(**iit).StlIterator()) {
01049 FD_ERR("TBaseSet<T,Cmp>("<< this << "," << rMessage <<"): invalid iterator (stl "<< *iit);
01050 (**iit).StlIterator(pSet->end());
01051 }
01052 }
01053
01054 if(pBaseSet==NULL) {
01055 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): no base found");
01056 abort();
01057 }
01058
01059 if(pBaseSet->pBaseSet != pBaseSet) {
01060 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): no source found");
01061 abort();
01062 }
01063
01064 if((mpSet!=NULL) && (pBaseSet != this)) {
01065 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): double data");
01066 abort();
01067 }
01068
01069 if(pBaseSet!=this && !mReferences.empty()) {
01070 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): cannot have source and refs");
01071 abort();
01072 }
01073
01074 if((pBaseSet == this) && (mpSet==NULL) && (pSet!=&mEmptySet)) {
01075 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): no data");
01076 abort();
01077 }
01078
01079 if((pBaseSet == this) && (pSet != mpSet) && (pSet!=&mEmptySet)) {
01080 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): data pointer mismatch A");
01081 abort();
01082 }
01083
01084 if((pBaseSet != this) && (pSet != pBaseSet->pSet)) {
01085 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): data pointer mismatch B");
01086 abort();
01087 }
01088
01089 if(mDetached && !pBaseSet->mReferences.empty()) {
01090 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): invalid detached flag");
01091 abort();
01092 }
01093
01094 if(mDetached && (pSet==&mEmptySet)) {
01095 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): detached empty set");
01096 abort();
01097 }
01098
01099 if(pBaseSet!=this && mLocked) {
01100 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): locked reference");
01101 abort();
01102 }
01103
01104 if(!mEmptySet.empty()) {
01105 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): invalid empty set");
01106 abort();
01107 }
01108 }
01109
01110
01111
01112
01113 template<class T, class Cmp>
01114 std::string TBaseSet<T,Cmp>::Name(void) const {
01115 return mMyName;
01116 }
01117
01118
01119 template<class T, class Cmp>
01120 void TBaseSet<T,Cmp>::Name(const std::string& rName) {
01121 mMyName = rName;
01122 }
01123
01124
01125 template<class T, class Cmp>
01126 Idx TBaseSet<T,Cmp>::Size(void) const {
01127 return (Idx) pSet->size();
01128 }
01129
01130
01131 template<class T, class Cmp>
01132 bool TBaseSet<T,Cmp>::Empty(void) const {
01133 return pSet->empty();
01134 }
01135
01136
01137
01138 template<class T, class Cmp>
01139 void TBaseSet<T,Cmp>::DoWrite(TokenWriter& rTw,const std::string& rLabel, const Type* pContext) const {
01140 (void) pContext;
01141 std::string label=rLabel;
01142 if(label=="") label=Name();
01143 if(label=="") label="BaseSet";
01144 rTw.WriteBegin(label);
01145 rTw.WriteEnd(label);
01146 }
01147
01148
01149
01150 template<class T, class Cmp>
01151 void TBaseSet<T,Cmp>::DoDWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
01152 (void) pContext;
01153 (void) rLabel;
01154 rTw.WriteComment("");
01155 rTw.WriteComment(" Size/Shares/Iterators: " + ToStringInteger(pSet->size())
01156 + "/" + ToStringInteger(pBaseSet->mReferences.size())
01157 + "/" + ToStringInteger(mIterators.size()));
01158 rTw.WriteComment("");
01159 #ifdef FAUDES_DEBUG_CONTAINER
01160 DValid();
01161 #endif
01162 }
01163
01164
01165 template<class T, class Cmp>
01166 void TBaseSet<T,Cmp>::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
01167 (void) pContext;
01168 Name(rLabel);
01169 rTr.SeekBegin(rLabel);
01170 rTr.SeekEnd(rLabel);
01171 }
01172
01173
01174 template<class T, class Cmp>
01175 typename TBaseSet<T,Cmp>::Iterator TBaseSet<T,Cmp>::ThisIterator(const typename std::set<T,Cmp>::const_iterator& sit) const {
01176 return Iterator(this,sit);
01177 }
01178
01179
01180 template<class T, class Cmp>
01181 inline typename TBaseSet<T,Cmp>::Iterator TBaseSet<T,Cmp>::Begin(void) const {
01182 return ThisIterator(pSet->begin());
01183 }
01184
01185
01186 template<class T, class Cmp>
01187 inline typename TBaseSet<T,Cmp>::Iterator TBaseSet<T,Cmp>::End(void) const {
01188 return ThisIterator(pSet->end());
01189 }
01190
01191
01192
01193 template<class T, class Cmp>
01194 void TBaseSet<T,Cmp>::Clear(void) {
01195 FD_DC("TBaseSet(" << this << ")::Clear()");
01196 #ifdef FAUDES_DEBUG_CONTAINER
01197 DValid();
01198 #endif
01199
01200 if(pSet==&mEmptySet) return;
01201
01202 if(mLocked) Detach();
01203
01204 if(!mReferences.empty())
01205 RelinkReferences();
01206
01207 if(pBaseSet!=this) {
01208 FD_DC("TBaseSet(" << this << ")::Clear(): allocate");
01209 mpSet = new std::set<T,Cmp>();
01210 pSet=mpSet;
01211 pBaseSet->DetachReference(this);
01212 pBaseSet=this;
01213 FD_DC("TBaseSet(" << this << ")::Clear(): allocate: done");
01214 }
01215
01216 typename std::set< Iterator* >::iterator iit;
01217 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01218 (**iit).Invalidate();
01219 }
01220 mIterators.clear();
01221 mDetached=true;
01222
01223 pSet->clear();
01224 #ifdef FAUDES_DEBUG_CONTAINER
01225 DValid();
01226 #endif
01227 }
01228
01229
01230
01231 template<class T, class Cmp>
01232 inline bool TBaseSet<T,Cmp>::Valid(const T& rElem) const {
01233 (void) rElem;
01234 return true;
01235 }
01236
01237
01238 template<class T, class Cmp>
01239 bool TBaseSet<T,Cmp>::Insert(const T& rElem) {
01240 #ifdef FAUDES_CHECKED
01241 if(!Valid(rElem)) {
01242 std::stringstream errstr;
01243 errstr << "cannot insert invalid element" << std::endl;
01244 throw Exception("TBaseSet<T,Cmp>::Insert", errstr.str(), 61);
01245 }
01246 #endif
01247 if(!mDetached) Detach();
01248 return pSet->insert(rElem).second;
01249 }
01250
01251
01252 template<class T, class Cmp>
01253 void TBaseSet<T,Cmp>::InsertSet(const TBaseSet& rOtherSet) {
01254 FD_DC("TBaseSet(" << this << ")::InsertSet(" << &rOtherSet << ")");
01255 if(!mDetached) Detach();
01256
01257 iterator it1 = pSet->begin();
01258 iterator it2 = rOtherSet.pSet->begin();
01259 while ((it1 != pSet->end()) && (it2 != rOtherSet.pSet->end())) {
01260 if (*it1 < *it2) {
01261 ++it1;
01262 }
01263 else if (*it1 == *it2) {
01264 ++it1;
01265 ++it2;
01266 }
01267 else {
01268 pSet->insert(*it2);
01269 ++it2;
01270 }
01271 }
01272 while (it2 != rOtherSet.pSet->end()) {
01273 pSet->insert(*it2);
01274 ++it2;
01275 }
01276 }
01277
01278
01279 template<class T, class Cmp>
01280 bool TBaseSet<T,Cmp>::Erase(const T& rElem) {
01281 if(!mDetached) Detach();
01282 return (pSet->erase(rElem)!=0);
01283 }
01284
01285
01286
01287 template<class T, class Cmp>
01288 typename TBaseSet<T,Cmp>::Iterator TBaseSet<T,Cmp>::Erase(const Iterator& pos) {
01289 #ifdef FAUDES_CHECKED
01290 if (pos == End()) {
01291 std::stringstream errstr;
01292 errstr << "iterator out of range " << std::endl;
01293 throw Exception("TBaseSet<T,Cmp>::Erase", errstr.str(), 62);
01294 }
01295 #endif
01296 Detach();
01297 iterator del= pos.StlIterator();
01298 iterator res= del;
01299 res++;
01300 pSet->erase(del);
01301 return ThisIterator(res);
01302 }
01303
01304
01305
01306 template<class T, class Cmp>
01307 void TBaseSet<T,Cmp>::EraseSet(const TBaseSet& rOtherSet) {
01308 FD_DC("TBaseSet(" << this << ")::EraseSet(" << &rOtherSet << ")");
01309 if(!mDetached) Detach();
01310
01311 iterator tmpit;
01312 iterator it = pSet->begin();
01313 iterator oit = rOtherSet.pSet->begin();
01314 while ((it != pSet->end()) && (oit != rOtherSet.pSet->end())) {
01315 if (*it < *oit) {
01316 it=pSet->lower_bound(*oit);
01317 }
01318 else if (*it == *oit) {
01319 tmpit=it;
01320 ++it;
01321 ++oit;
01322 pSet->erase(tmpit);
01323 }
01324 else {
01325 oit=rOtherSet.pSet->lower_bound(*it);
01326 }
01327 }
01328 }
01329
01330
01331
01332 template<class T, class Cmp>
01333 typename TBaseSet<T,Cmp>::Iterator TBaseSet<T,Cmp>::Find(const T& rElem) const {
01334 return ThisIterator(pSet->find(rElem));
01335 }
01336
01337
01338 template<class T, class Cmp>
01339 bool TBaseSet<T,Cmp>::Exists(const T& rElem) const {
01340 return pSet->find(rElem) != pSet->end();
01341 }
01342
01343
01344
01345 template<class T, class Cmp>
01346 void TBaseSet<T,Cmp>::SetUnion(const TBaseSet& rOtherSet) {
01347 if(!mDetached) Detach();
01348 iterator it1 = pSet->begin();
01349 iterator it2 = rOtherSet.pSet->begin();
01350 while ((it1 != pSet->end()) && (it2 != rOtherSet.pSet->end())) {
01351 if (*it1 < *it2) {
01352 ++it1;
01353 continue;
01354 }
01355 if (*it1 == *it2) {
01356 ++it1;
01357 ++it2;
01358 continue;
01359 }
01360
01361 pSet->insert(it1,*it2);
01362 ++it2;
01363 }
01364 while (it2 != rOtherSet.pSet->end()) {
01365 pSet->insert(pSet->end(),*it2);
01366 ++it2;
01367 }
01368 }
01369
01370
01371 template<class T, class Cmp>
01372 void TBaseSet<T,Cmp>::SetIntersection(const TBaseSet& rOtherSet) {
01373 if(!mDetached) Detach();
01374 iterator tmpit;
01375 iterator it1 = pSet->begin();
01376 iterator it2 = rOtherSet.pSet->begin();
01377 while ((it1 != pSet->end()) && (it2 != rOtherSet.pSet->end())) {
01378 if (*it1 < *it2) {
01379 tmpit=it1;
01380 ++it1;
01381 pSet->erase(tmpit);
01382 continue;
01383 }
01384 if (*it1 == *it2) {
01385 ++it1;
01386 ++it2;
01387 continue;
01388 }
01389
01390 ++it2;
01391 }
01392 while(it1 != pSet->end()) {
01393 tmpit=it1;
01394 ++it1;
01395 pSet->erase(tmpit);
01396 }
01397 }
01398
01399
01400
01401 template<class T, class Cmp>
01402 TBaseSet<T,Cmp> TBaseSet<T,Cmp>::operator + (const TBaseSet& rOtherSet) const {
01403 FD_DC("TBaseSet(" << this << ")::operator + (" << &rOtherSet << ")");
01404 TBaseSet res;
01405 res.Detach();
01406 std::insert_iterator< std::set<Idx> > insit(*res.pSet, res.pSet->begin());
01407 std::set_union(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end(), insit);
01408 res.Name(CollapsString(Name() + "+" + rOtherSet.Name()));
01409 return res;
01410 }
01411
01412
01413 template<class T, class Cmp>
01414 TBaseSet<T,Cmp> TBaseSet<T,Cmp>::operator - (const TBaseSet& rOtherSet) const {
01415 FD_DC("TBaseSet(" << this << ")::operator - (" << &rOtherSet << ")");
01416 TBaseSet res;
01417 res.Detach();
01418 std::insert_iterator< std::set<Idx> > insit(*res.pSet, res.pSet->begin());
01419 std::set_difference(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end(), insit);
01420 res.Name(CollapsString(Name() + "-" + rOtherSet.Name()));
01421 return res;
01422 }
01423
01424
01425
01426 template<class T, class Cmp>
01427 TBaseSet<T,Cmp> TBaseSet<T,Cmp>::operator * (const TBaseSet& rOtherSet) const {
01428 FD_DC("TBaseSet(" << this << ")::operator * (" << &rOtherSet << ")");
01429 TBaseSet res;
01430 res.Detach();
01431 std::insert_iterator< std::set<Idx> > insit(*res.pSet, res.pSet->begin());
01432 std::set_intersection(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end(), insit);
01433 res.Name(CollapsString(Name() + "*" + rOtherSet.Name()));
01434 return res;
01435 }
01436
01437
01438
01439 template<class T, class Cmp>
01440 bool TBaseSet<T,Cmp>::operator == (const TBaseSet& rOtherSet) const {
01441 return ( *pSet == *rOtherSet.pSet );
01442 }
01443
01444
01445 template<class T, class Cmp>
01446 bool TBaseSet<T,Cmp>::operator != (const TBaseSet& rOtherSet) const {
01447 return ( *pSet != *rOtherSet.pSet );
01448 }
01449
01450
01451 template<class T, class Cmp>
01452 bool TBaseSet<T,Cmp>::operator <= (const TBaseSet& rOtherSet) const {
01453 return ( std::includes(rOtherSet.pSet->begin(), rOtherSet.pSet->end(), pSet->begin(), pSet->end()) ) ;
01454 }
01455
01456
01457 template<class T, class Cmp>
01458 bool TBaseSet<T,Cmp>::operator >= (const TBaseSet& rOtherSet) const {
01459 return ( std::includes(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end()) );
01460 }
01461
01462
01463 template<class T, class Cmp>
01464 bool TBaseSet<T,Cmp>::operator < (const TBaseSet& rOtherSet) const {
01465 return *pSet < *rOtherSet.pSet;
01466 }
01467
01468
01471 }
01472
01473 #endif