00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef BASESET_H
00026
00027 #include "definitions.h"
00028 #include "tokenwriter.h"
00029 #include "tokenreader.h"
00030 #include <set>
00031 #include <algorithm>
00032
00033 namespace faudes {
00034
00081 template<class T, class Cmp=std::less<T> >
00082 class TBaseSet {
00083
00084 public:
00085
00089 TBaseSet(void);
00090
00097 TBaseSet(const TBaseSet& rOtherSet);
00098
00102 virtual ~TBaseSet(void);
00103
00110 std::string Name(void) const;
00111
00118 void Name(const std::string& rName);
00119
00123 virtual void Clear(void);
00124
00131 Idx Size(void) const;
00132
00139 bool Empty(void) const;
00140
00147 void Write(void) const;
00148
00164 void Write(const std::string& pFileName, const std::string& rLabel="",
00165 std::ios::openmode openmode = std::ios::out|std::ios::trunc) const;
00166
00180 void Write(TokenWriter& rTw, const std::string& rLabel="") const;
00181
00192 std::string ToString(void) const;
00193
00200 void DWrite(void) const;
00201
00210 void DWrite(TokenWriter& rTw) const;
00211
00225 void DWrite(const char* pFileName,
00226 std::ios::openmode openmode = std::ios::out|std::ios::trunc) const;
00227
00242 void Read(const std::string& rFileName, const std::string& rLabel = "BaseSet");
00243
00258 void Read(TokenReader& rTr, const std::string& rLabel = "BaseSet");
00259
00260
00265 class Iterator;
00266
00273 Iterator Begin(void) const;
00274
00281 Iterator End(void) const;
00282
00294 virtual bool Valid(const T& rElem) const;
00295
00296
00305 virtual bool Erase(const T& rElem);
00306
00307
00316 virtual Iterator Erase(const Iterator& pos);
00317
00318
00325 virtual void EraseSet(const TBaseSet& rOtherSet);
00326
00327
00336 virtual bool Insert(const T& rElem);
00337
00345 virtual void InsertSet(const TBaseSet& rOtherSet);
00346
00353 virtual void SetUnion(const TBaseSet& rOtherSet);
00354
00361 virtual void SetIntersection(const TBaseSet& rOtherSet);
00362
00363
00373 bool Exists(const T& rElem) const;
00374
00384 Iterator Find(const T& rElem) const;
00385
00392 TBaseSet operator + (const TBaseSet& rOtherSet) const;
00393
00400 TBaseSet operator - (const TBaseSet& rOtherSet) const;
00401
00408 TBaseSet operator * (const TBaseSet& rOtherSet) const;
00409
00410
00412 bool operator == (const TBaseSet& rOtherSet) const;
00413
00415 bool operator != (const TBaseSet& rOtherSet) const;
00416
00418 bool operator <= (const TBaseSet& rOtherSet) const;
00419
00421 bool operator >= (const TBaseSet& rOtherSet) const;
00422
00424 bool operator < (const TBaseSet& rOtherSet) const;
00425
00427 virtual const TBaseSet& operator=(const TBaseSet& rSrc) {return Assign(rSrc);};
00428
00430 void DValid(const std::string& rMessage="") const;
00431
00433 void Detach(void) const;
00434
00436 void Lock(void) const;
00437
00447 class Iterator : private std::set<T,Cmp>::const_iterator {
00448 public:
00450 Iterator() :
00451 std::set<T,Cmp>::const_iterator() ,
00452 pBaseSet(NULL),
00453 mAttached(false)
00454 {};
00455
00457 Iterator(
00458 const TBaseSet<T,Cmp>* pBaseSet,
00459 const typename std::set<T,Cmp>::const_iterator& sit) :
00460 std::set<T,Cmp>::const_iterator(sit),
00461 pBaseSet(pBaseSet),
00462 mAttached(false)
00463 {};
00464
00466 Iterator(const Iterator& fit) :
00467 std::set<T,Cmp>::const_iterator(fit),
00468 pBaseSet(fit.pBaseSet),
00469 mAttached(false)
00470 {
00471 if(pBaseSet) {
00472 pBaseSet->AttachIterator(this);
00473 mAttached=true;
00474 }
00475 };
00476
00478 ~Iterator(void) {
00479 if(mAttached) pBaseSet->DetachIterator(this);
00480 };
00481
00483 const Iterator& operator= (const Iterator& rSrc) {
00484 #ifdef FAUDES_DEBUG_CODE
00485 if(rSrc.pBaseSet==NULL) {
00486 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator= invalid iterator: no baseset");
00487 abort();
00488 }
00489 #endif
00490
00491 if(mAttached) if(pBaseSet==rSrc.pBaseSet) {
00492 std::set<T,Cmp>::const_iterator::operator= (rSrc);
00493 return *this;
00494 }
00495
00496 if(mAttached) pBaseSet->DetachIterator(this);
00497 std::set<T,Cmp>::const_iterator::operator= (rSrc);
00498 pBaseSet = rSrc.pBaseSet;
00499 if(pBaseSet) {
00500 pBaseSet->AttachIterator(this);
00501 mAttached=true;
00502 } else {
00503 mAttached=false;
00504 }
00505 return *this;
00506 };
00507
00509 void StlIterator(const typename std::set<T,Cmp>::const_iterator& sit) {
00510 std::set<T,Cmp>::const_iterator::operator= (sit);
00511 };
00512
00514 const typename std::set<T,Cmp>::const_iterator& StlIterator(void) const {
00515 return *this;
00516 };
00517
00519 void Invalidate(void) {
00520 pBaseSet=NULL;
00521 mAttached=false;
00522 };
00523
00525 void Detach(void) {
00526 mAttached=false;
00527 };
00528
00529
00531 void DValid(void) const {
00532 if(pBaseSet==NULL) {
00533 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):DValid(): invalid iterator: no baseset");
00534 abort();
00535 }
00536 pBaseSet->DValid();
00537 };
00538
00540 const T* operator-> (void) const {
00541 #ifdef FAUDES_DEBUG_CODE
00542 if(pBaseSet==NULL) {
00543 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator->: invalid iterator: no baseset");
00544 abort();
00545 }
00546 #endif
00547 return std::set<T,Cmp>::const_iterator::operator-> ();
00548 };
00549
00551 const T& operator* (void) const {
00552 #ifdef FAUDES_DEBUG_CODE
00553 if(pBaseSet==NULL) {
00554 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator*: invalid iterator: no baseset");
00555 abort();
00556 }
00557 #endif
00558 return std::set<T,Cmp>::const_iterator::operator* ();
00559 };
00560
00562 bool operator == (const Iterator& rOther) const {
00563 #ifdef FAUDES_DEBUG_CODE
00564 if(pBaseSet==NULL) {
00565 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator==: invalid iterator: no baseset");
00566 abort();
00567 }
00568 #endif
00569 return std::set<T,Cmp>::const_iterator::operator == (rOther);
00570 };
00571
00573 bool operator != (const Iterator& rOther) const {
00574 #ifdef FAUDES_DEBUG_CODE
00575 if(pBaseSet==NULL) {
00576 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator!=: invalid iterator: no baseset");
00577 abort();
00578 }
00579 #endif
00580 return std::set<T,Cmp>::const_iterator::operator != (rOther);
00581 };
00582
00584 Iterator operator++ (int step) {
00585 #ifdef FAUDES_DEBUG_CODE
00586 if(pBaseSet==NULL) {
00587 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator++: invalid iterator: no baseset");
00588 abort();
00589 }
00590 #endif
00591 Iterator old(pBaseSet,*this);
00592 std::set<T,Cmp>::const_iterator::operator++ (step);
00593 return old;
00594 };
00595
00597 const Iterator& operator++ (void) {
00598 #ifdef FAUDES_DEBUG_CODE
00599 if(pBaseSet==NULL) {
00600 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator++: invalid iterator: no baseset");
00601 abort();
00602 }
00603 #endif
00604 std::set<T,Cmp>::const_iterator::operator++ ();
00605 return *this;
00606 };
00607
00609 Iterator operator-- (int step) {
00610 #ifdef FAUDES_DEBUG_CODE
00611 if(pBaseSet==NULL) {
00612 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator--: invalid iterator: no baseset");
00613 abort();
00614 }
00615 #endif
00616 Iterator old(pBaseSet, *this);
00617 std::set<T,Cmp>::const_iterator::operator-- (step);
00618 return old;
00619 };
00620
00622 const Iterator& operator-- (void) {
00623 #ifdef FAUDES_DEBUG_CODE
00624 if(pBaseSet==NULL) {
00625 FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator--: invalid iterator: no baseset");
00626 abort();
00627 }
00628 #endif
00629 std::set<T,Cmp>::const_iterator::operator-- ();
00630 return *this;
00631 };
00632
00633
00635
00636
00637
00638
00639
00640
00642 const TBaseSet<T,Cmp>* pBaseSet;
00643
00645 bool mAttached;
00646 };
00647
00648 #ifdef DONT_TRACK_REFERENCES
00649
00654 class Iterator : public std::set<T,Cmp>::const_iterator {
00655 public:
00656
00658 Iterator(void) :
00659 std::set<T,Cmp>::const_iterator()
00660 {};
00661
00663 Iterator(const Iterator& fit) :
00664 std::set<T,Cmp>::const_iterator(fit)
00665 {};
00666
00668 Iterator(const typename std::set<T,Cmp>::const_iterator& sit) :
00669 std::set<T,Cmp>::const_iterator(sit)
00670 {};
00671
00673 Iterator(
00674 const TBaseSet<T,Cmp>* pBaseSet,
00675 const typename std::set<T,Cmp>::const_iterator& sit) :
00676 std::set<T,Cmp>::const_iterator(sit)
00677 {};
00678
00680 void StlIterator(const typename std::set<T,Cmp>::const_iterator& sit) {
00681 std::set<T,Cmp>::const_iterator::operator= (sit);
00682 };
00683
00685 const typename std::set<T,Cmp>::const_iterator& StlIterator(void) const {
00686 return *this;
00687 };
00688
00690 void Invalidate(void) {};
00691
00692 };
00693
00694 #endif
00695
00696
00697 protected:
00698
00699
00705 virtual void DoDWrite(TokenWriter& rTw) const;
00706
00712 virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="") const;
00713
00719 virtual void DoRead(TokenReader& rTr, const std::string& rLabel = "BaseSet");
00720
00722 const TBaseSet<T,Cmp>& Assign(const TBaseSet<T,Cmp>& rOtherSet);
00723
00725 std::set<T,Cmp>* mpSet;
00726
00728 static std::set<T,Cmp> mEmptySet;
00729
00731 std::set<T,Cmp>* pSet;
00732
00734 typedef typename std::set<T,Cmp>::iterator iterator;
00735
00737 typedef typename std::set<T,Cmp>::const_iterator const_iterator;
00738
00740 typename TBaseSet<T,Cmp>::Iterator ThisIterator(const typename std::set<T,Cmp>::const_iterator& sit) const;
00741
00742
00743 private:
00744
00745
00747 std::string mMyName;
00748
00750 std::set< TBaseSet<T,Cmp>* > mReferences;
00751
00753 TBaseSet<T,Cmp>* pBaseSet;
00754
00756 bool mDetached;
00757
00759 bool mLocked;
00760
00762 void RelinkReferences(void);
00763
00765 void AttachReference(TBaseSet* pRef) const;
00766
00768 void DetachReference(TBaseSet* pRef) const;
00769
00771 std::set< Iterator* > mIterators;
00772
00774 void AttachIterator(Iterator* pFit) const;
00775
00777 void DetachIterator(Iterator* pFit) const;
00778
00779 };
00780
00781
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 template<class T, class Cmp>
00801 std::set<T,Cmp> TBaseSet<T,Cmp>::mEmptySet=std::set<T,Cmp>();
00802
00803
00804
00805 template<class T, class Cmp>
00806 TBaseSet<T,Cmp>::TBaseSet(void) :
00807 mpSet(NULL),
00808 pSet(&mEmptySet),
00809 pBaseSet(this),
00810 mDetached(false),
00811 mLocked(false)
00812 {
00813 FD_DC("TBaseSet(" << this << ")::TBaseSet()");
00814
00815
00816
00817
00818
00819
00820
00821 mMyName="BaseSet";
00822 }
00823
00824
00825
00826
00827 template<class T, class Cmp>
00828 TBaseSet<T,Cmp>::TBaseSet(const TBaseSet& rOtherSet) :
00829 mpSet(NULL),
00830 pSet(NULL),
00831 pBaseSet(this),
00832 mDetached(false),
00833 mLocked(false)
00834 {
00835 FD_DC("TBaseSet(" << this << ")::TBaseSet(rOtherSet " << &rOtherSet << "): fake copy construct");
00836
00837 pBaseSet=rOtherSet.pBaseSet;
00838 pBaseSet->AttachReference(this);
00839 pSet=rOtherSet.pSet;
00840
00841 mMyName=rOtherSet.mMyName;
00842 #ifdef FAUDES_DEBUG_CONTAINER
00843 DValid();
00844 #endif
00845 }
00846
00847
00848 template<class T, class Cmp>
00849 TBaseSet<T,Cmp>::~TBaseSet(void) {
00850 FD_DC("TBaseSet(" << this << ")::~TBaseSet()");
00851
00852 RelinkReferences();
00853 pBaseSet->DetachReference(this);
00854 if(mpSet) delete mpSet;
00855
00856 typename std::set< Iterator* >::const_iterator iit;
00857 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
00858 (**iit).Invalidate();
00859 }
00860 }
00861
00862
00863 template<class T, class Cmp>
00864 const TBaseSet<T,Cmp>& TBaseSet<T,Cmp>::Assign(const TBaseSet<T,Cmp>& rOtherSet) {
00865 FD_DC("TBaseSet(" << this << ")::Assign(rOtherSet " << &rOtherSet << "): fake assignment");
00866
00867 if(this==&rOtherSet) return *this;
00868
00869 RelinkReferences();
00870 pBaseSet->DetachReference(this);
00871 mReferences.clear();
00872 pBaseSet=rOtherSet.pBaseSet;
00873 pBaseSet->AttachReference(this);
00874 pSet=rOtherSet.pSet;
00875 if(mpSet) {
00876 delete mpSet;
00877 mpSet=NULL;
00878 }
00879 mDetached=false;
00880 mLocked=false;
00881
00882 typename std::set< Iterator* >::iterator iit;
00883 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
00884 (**iit).Invalidate();
00885 }
00886 mIterators.clear();
00887
00888 mMyName=rOtherSet.mMyName;
00889 #ifdef FAUDES_DEBUG_CONTAINER
00890 DValid();
00891 #endif
00892 return *this;
00893 }
00894
00895
00896
00897 template<class T, class Cmp>
00898 void TBaseSet<T,Cmp>::Detach(void) const {
00899 FD_DC("TBaseSet(" << this << ")::Detach(void)");
00900 #ifdef FAUDES_DEBUG_CONTAINER
00901 DValid();
00902 #endif
00903
00904
00905 if(mDetached) return;
00906
00907
00908 TBaseSet<T,Cmp>* fake_const = const_cast< TBaseSet<T,Cmp>* >(this);
00909
00910
00911 if(pBaseSet->mReferences.empty() && pBaseSet->mpSet != NULL) {
00912 fake_const->mDetached=true;
00913 return;
00914 }
00915
00916
00917
00918
00919 if(mLocked==true) {
00920
00921 FD_DC("TBaseSet(" << this << ")::Detach(void): allocate and copy, strategie A");
00922
00923 std::set<T,Cmp>* copy = new std::set<T,Cmp>();
00924 *copy = *pSet;
00925
00926 TBaseSet<T,Cmp>* storage = *mReferences.begin();
00927 storage->pBaseSet=storage;
00928 storage->mpSet=copy;
00929 storage->pSet=copy;
00930 storage->mReferences=mReferences;
00931 storage->DetachReference(storage);
00932
00933 if(storage->mReferences.empty())
00934 storage->mDetached=true;
00935
00936 typename std::set< TBaseSet<T,Cmp>* >::const_iterator rit;
00937 for(rit=mReferences.begin(), ++rit ;rit!=mReferences.end(); ++rit) {
00938 (*rit)->pBaseSet=storage;
00939 (*rit)->pSet=copy;
00940 }
00941
00942 for(rit=mReferences.begin(); rit!=mReferences.end(); ++rit) {
00943 typename std::set< Iterator* >::iterator iit;
00944 for(iit=(*rit)->mIterators.begin(); iit!=(*rit)->mIterators.end(); ++iit) {
00945 if((**iit).StlIterator()==pSet->end())
00946 **iit=Iterator(this, copy->end());
00947 else
00948 **iit=Iterator(this, copy->find(***iit));
00949 }
00950 }
00951
00952 fake_const->mpSet=pSet;
00953 fake_const->mReferences.clear();
00954 fake_const->mDetached=true;
00955
00956 typename std::set< Iterator* >::const_iterator iit;
00957 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
00958 (**iit).Detach();
00959 }
00960 fake_const->mIterators.clear();
00961
00962
00963
00964
00965
00966 } else {
00967
00968
00969 FD_DC("TBaseSet(" << this << ")::Detach(void): allocate and copy, strategie B");
00970
00971 fake_const->RelinkReferences();
00972
00973 fake_const->mpSet = new std::set<T,Cmp>();
00974 *fake_const->mpSet= *pSet;
00975
00976 typename std::set< Iterator* >::iterator iit;
00977 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
00978 if((**iit).StlIterator()==pSet->end())
00979 **iit=Iterator(this, mpSet->end());
00980 else
00981 **iit=Iterator(this, mpSet->find(***iit));
00982 }
00983
00984 pBaseSet->DetachReference(fake_const);
00985 if(pBaseSet->pBaseSet->mReferences.empty() && pBaseSet->mpSet != NULL)
00986 pBaseSet->mDetached=true;
00987 fake_const->pBaseSet=fake_const;
00988 fake_const->pSet=mpSet;
00989 fake_const->mDetached=true;
00990
00991 }
00992
00993 #ifdef FAUDES_DEBUG_CONTAINER
00994 DValid();
00995 #endif
00996 FD_DC("TBaseSet(" << this << ")::Detach(void): done");
00997 }
00998
00999
01000 template<class T, class Cmp>
01001 void TBaseSet<T,Cmp>::Lock(void) const {
01002 FD_DC("TBaseSet(" << this << ")::Lock(void)");
01003 #ifdef FAUDES_DEBUG_CONTAINER
01004 DValid();
01005 #endif
01006
01007
01008 Detach();
01009
01010
01011 TBaseSet<T,Cmp>* fake_const = const_cast< TBaseSet<T,Cmp>* >(this);
01012
01013
01014 typename std::set< Iterator* >::const_iterator iit;
01015 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01016 (**iit).Detach();
01017 }
01018 fake_const->mIterators.clear();
01019
01020
01021 fake_const->mLocked=true;
01022 }
01023
01024
01025
01026 template<class T, class Cmp>
01027 inline void TBaseSet<T,Cmp>::RelinkReferences(void) {
01028 FD_DC("TBaseSet::RelinkReferences(" << this << ")")
01029 #ifdef FAUDES_DEBUG_CONTAINER
01030 DValid();
01031 #endif
01032
01033 if(mReferences.empty()) return;
01034
01035 TBaseSet<T,Cmp>* storage = *mReferences.begin();
01036 #ifdef FAUDES_DEBUG_CODE
01037 if(storage->pBaseSet!=this) {
01038 FD_ERR("TBaseSet<T,Cmp>::RelinkRefernces: old reference must have this as storage provider");
01039 abort();
01040 }
01041 #endif
01042 storage->pBaseSet=storage;
01043 storage->mpSet=mpSet;
01044 storage->pSet=pSet;
01045 storage->mReferences=mReferences;
01046 storage->DetachReference(storage);
01047
01048 typename std::set< TBaseSet<T,Cmp>* >::const_iterator rit;
01049 for(rit=mReferences.begin(), ++rit;rit!=mReferences.end(); ++rit) {
01050 (*rit)->pBaseSet=storage;
01051 }
01052
01053 pBaseSet=storage;
01054 pSet=storage->pSet;
01055 mpSet=NULL;
01056 storage->AttachReference(this);
01057 mReferences.clear();
01058 #ifdef FAUDES_DEBUG_CONTAINER
01059 DValid();
01060 #endif
01061 FD_DC("TBaseSet::RelinkReferences(" << this << "): done")
01062 }
01063
01064
01065
01066 template<class T, class Cmp>
01067 inline void TBaseSet<T,Cmp>::AttachReference(TBaseSet* pRef) const {
01068 const_cast< TBaseSet<T,Cmp>* >(this)->mReferences.insert(pRef);
01069 const_cast< TBaseSet<T,Cmp>* >(this)->mDetached=false;
01070 }
01071
01072
01073 template<class T, class Cmp>
01074 inline void TBaseSet<T,Cmp>::DetachReference(TBaseSet* pRef) const {
01075 const_cast< TBaseSet<T,Cmp>* >(this)->mReferences.erase(pRef);
01076 }
01077
01078
01079
01080 template<class T, class Cmp>
01081 inline void TBaseSet<T,Cmp>::AttachIterator(Iterator* pFit) const {
01082 if(mLocked) return;
01083 FD_DC("TBaseSet::AttachIterator(" << this << "):" << pFit)
01084 const_cast< TBaseSet<T,Cmp>* >(this)->mIterators.insert(pFit);
01085 }
01086
01087
01088 template<class T, class Cmp>
01089 inline void TBaseSet<T,Cmp>::DetachIterator(Iterator* pFit) const {
01090 if(mLocked) return;
01091 FD_DC("TBaseSet::DetachIterator(" << this << "):" << pFit)
01092 const_cast< TBaseSet<T,Cmp>* >(this)->mIterators.erase(pFit);
01093 }
01094
01095
01096
01097
01098 template<class T, class Cmp>
01099 void TBaseSet<T,Cmp>::DValid(const std::string& rMessage) const {
01100 typename std::set< Iterator* >::const_iterator iit;
01101 #ifdef FAUDES_DEBUG_CONTAINER
01102 std::cout << "TBaseSet<T,Cmp>(" << this << "," << rMessage << ")::DValid: source "
01103 << pBaseSet << " #" << (pBaseSet->pSet==&mEmptySet ? "e" : "f") << " -- list: ";
01104 typename std::set< TBaseSet<T,Cmp>* >::const_iterator rit;
01105 for(rit=pBaseSet->mReferences.begin(); rit!=pBaseSet->mReferences.end(); ++rit)
01106 std::cout << *rit << " ";
01107 std::cout << "-- iterators: ";
01108 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit)
01109 std::cout << *iit << " ";
01110 std::cout << "." << std::endl;
01111 #endif
01112
01113 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01114 if((*iit)->pBaseSet!=this) {
01115 FD_ERR("TBaseSet<T,Cmp>("<< this << "," << rMessage <<"): invalid iterator (baseset): "<< *iit);
01116 abort();
01117 }
01118 }
01119
01120 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01121 if(!(*iit)->mAttached) {
01122 FD_ERR("TBaseSet<T,Cmp>("<< this << "," << rMessage <<"): invalid iterator (attached): "<< *iit);
01123 abort();
01124 }
01125 }
01126
01127 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01128 typename std::set<T,Cmp>::const_iterator vit;
01129 for(vit=pSet->begin(); vit!= pSet->end(); ++vit) {
01130 if(vit==(**iit).StlIterator()) break;
01131 }
01132 if(vit!=(**iit).StlIterator()) {
01133 FD_ERR("TBaseSet<T,Cmp>("<< this << "," << rMessage <<"): invalid iterator (stl "<< *iit);
01134 (**iit).StlIterator(pSet->end());
01135 }
01136 }
01137
01138 if(pBaseSet==NULL) {
01139 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): no base found");
01140 abort();
01141 }
01142
01143 if(pBaseSet->pBaseSet != pBaseSet) {
01144 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): no source found");
01145 abort();
01146 }
01147
01148 if((mpSet!=NULL) && (pBaseSet != this)) {
01149 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): double data");
01150 abort();
01151 }
01152
01153 if(pBaseSet!=this && !mReferences.empty()) {
01154 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): cannot have source and refs");
01155 abort();
01156 }
01157
01158 if((pBaseSet == this) && (mpSet==NULL) && (pSet!=&mEmptySet)) {
01159 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): no data");
01160 abort();
01161 }
01162
01163 if((pBaseSet == this) && (pSet != mpSet) && (pSet!=&mEmptySet)) {
01164 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): data pointer mismatch A");
01165 abort();
01166 }
01167
01168 if((pBaseSet != this) && (pSet != pBaseSet->pSet)) {
01169 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): data pointer mismatch B");
01170 abort();
01171 }
01172
01173 if(mDetached && !pBaseSet->mReferences.empty()) {
01174 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): invalid detached flag");
01175 abort();
01176 }
01177
01178 if(mDetached && (pSet==&mEmptySet)) {
01179 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): detached empty set");
01180 abort();
01181 }
01182
01183 if(pBaseSet!=this && mLocked) {
01184 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): locked reference");
01185 abort();
01186 }
01187
01188 if(!mEmptySet.empty()) {
01189 FD_ERR("TBaseSet<T,Cmp>(" << this << "," << rMessage << "): invalid empty set");
01190 abort();
01191 }
01192 }
01193
01194
01195
01196
01197 template<class T, class Cmp>
01198 std::string TBaseSet<T,Cmp>::Name(void) const {
01199 return mMyName;
01200 }
01201
01202
01203 template<class T, class Cmp>
01204 void TBaseSet<T,Cmp>::Name(const std::string& rName) {
01205 mMyName = rName;
01206 }
01207
01208
01209 template<class T, class Cmp>
01210 Idx TBaseSet<T,Cmp>::Size(void) const {
01211 return (Idx) pSet->size();
01212 }
01213
01214
01215 template<class T, class Cmp>
01216 bool TBaseSet<T,Cmp>::Empty(void) const {
01217 return pSet->empty();
01218 }
01219
01220
01221 template<class T, class Cmp>
01222 void TBaseSet<T,Cmp>::Write(void) const {
01223 TokenWriter tw(TokenWriter::Stdout);
01224 DoWrite(tw);
01225 }
01226
01227
01228 template<class T, class Cmp>
01229 void TBaseSet<T,Cmp>::Write(const std::string& rFileName, const std::string& rLabel, std::ios::openmode openmode) const {
01230 try {
01231 TokenWriter tw(rFileName, openmode);
01232 DoWrite(tw, rLabel);
01233 }
01234 catch (std::ios::failure&) {
01235 std::stringstream errstr;
01236 errstr << "Exception opening/writing file \"" << rFileName << "\"";
01237 throw Exception("TBaseSet::Write", errstr.str(), 2);
01238 }
01239 }
01240
01241
01242 template<class T, class Cmp>
01243 void TBaseSet<T,Cmp>::Write(TokenWriter& rTw, const std::string& rLabel) const {
01244 DoWrite(rTw,rLabel);
01245 }
01246
01247
01248 template<class T, class Cmp>
01249 std::string TBaseSet<T,Cmp>::ToString(void) const {
01250 TokenWriter tw(TokenWriter::String);
01251 DoWrite(tw);
01252 return tw.Str();
01253 }
01254
01255
01256 template<class T, class Cmp>
01257 void TBaseSet<T,Cmp>::DoWrite(TokenWriter& rTw,const std::string& rLabel) const {
01258 std::string label=rLabel;
01259 if(label=="") label=Name();
01260 rTw.WriteBegin(label);
01261 rTw.WriteEnd(label);
01262 }
01263
01264
01265 template<class T, class Cmp>
01266 void TBaseSet<T,Cmp>::DWrite(void) const {
01267 TokenWriter tw(TokenWriter::Stdout);
01268 DoDWrite(tw);
01269 }
01270
01271
01272 template<class T, class Cmp>
01273 void TBaseSet<T,Cmp>::DWrite(const char* rFileName, std::ios::openmode openmode) const {
01274 try {
01275 TokenWriter tw(rFileName, openmode);
01276 DoDWrite(tw);
01277 }
01278 catch (std::ios::failure&) {
01279 std::stringstream errstr;
01280 errstr << "Exception opening/writing file \"" << rFileName << "\"";
01281 throw Exception("TBaseSet::DWrite", errstr.str(), 2);
01282 }
01283 }
01284
01285
01286 template<class T, class Cmp>
01287 void TBaseSet<T,Cmp>::DWrite(TokenWriter& rTw) const {
01288 DoDWrite(rTw);
01289 }
01290
01291
01292 template<class T, class Cmp>
01293 void TBaseSet<T,Cmp>::DoDWrite(TokenWriter& rTw) const {
01294 rTw.Comment("");
01295 rTw.Comment(" Size/Shares/Iterators: " + ToStringInteger(pSet->size())
01296 + "/" + ToStringInteger(pBaseSet->mReferences.size())
01297 + "/" + ToStringInteger(mIterators.size()));
01298 rTw.Comment("");
01299 #ifdef FAUDES_DEBUG_CONTAINER
01300 DValid();
01301 #endif
01302 }
01303
01304
01305 template<class T, class Cmp>
01306 void TBaseSet<T,Cmp>::Read(const std::string& rFilename, const std::string& rLabel) {
01307 TokenReader tr(rFilename);
01308 Read(tr,rLabel);
01309 }
01310
01311
01312 template<class T, class Cmp>
01313 void TBaseSet<T,Cmp>::Read(TokenReader& rTr, const std::string& rLabel) {
01314 DoRead(rTr,rLabel);
01315 }
01316
01317
01318 template<class T, class Cmp>
01319 void TBaseSet<T,Cmp>::DoRead(TokenReader& rTr, const std::string& rLabel) {
01320 Name(rLabel);
01321 Clear();
01322 rTr.SeekBegin(rLabel);
01323 rTr.SeekEnd(rLabel);
01324 }
01325
01326
01327 template<class T, class Cmp>
01328 typename TBaseSet<T,Cmp>::Iterator TBaseSet<T,Cmp>::ThisIterator(const typename std::set<T,Cmp>::const_iterator& sit) const {
01329 return Iterator(this,sit);
01330 }
01331
01332
01333 template<class T, class Cmp>
01334 inline typename TBaseSet<T,Cmp>::Iterator TBaseSet<T,Cmp>::Begin(void) const {
01335 return ThisIterator(pSet->begin());
01336 }
01337
01338
01339 template<class T, class Cmp>
01340 inline typename TBaseSet<T,Cmp>::Iterator TBaseSet<T,Cmp>::End(void) const {
01341 return ThisIterator(pSet->end());
01342 }
01343
01344
01345
01346 template<class T, class Cmp>
01347 void TBaseSet<T,Cmp>::Clear(void) {
01348 FD_DC("TBaseSet(" << this << ")::Clear(void)");
01349 #ifdef FAUDES_DEBUG_CONTAINER
01350 DValid();
01351 #endif
01352
01353 if(pSet==&mEmptySet) return;
01354
01355 if(mLocked) Detach();
01356
01357 if(!mReferences.empty())
01358 RelinkReferences();
01359
01360 if(pBaseSet!=this) {
01361 FD_DC("TBaseSet(" << this << ")::Clear(void): allocate");
01362 mpSet = new std::set<T,Cmp>();
01363 pSet=mpSet;
01364 pBaseSet->DetachReference(this);
01365 pBaseSet=this;
01366 FD_DC("TBaseSet(" << this << ")::Clear(void): allocate: done");
01367 }
01368
01369 typename std::set< Iterator* >::iterator iit;
01370 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01371 (**iit).Invalidate();
01372 }
01373 mIterators.clear();
01374 mDetached=true;
01375
01376 pSet->clear();
01377 #ifdef FAUDES_DEBUG_CONTAINER
01378 DValid();
01379 #endif
01380 }
01381
01382
01383
01384 template<class T, class Cmp>
01385 inline bool TBaseSet<T,Cmp>::Valid(const T& rElem) const {
01386 (void) rElem;
01387 return true;
01388 }
01389
01390
01391 template<class T, class Cmp>
01392 bool TBaseSet<T,Cmp>::Insert(const T& rElem) {
01393 #ifdef FAUDES_CHECKED
01394 if(!Valid(rElem)) {
01395 std::stringstream errstr;
01396 errstr << "cannot insert invalid element" << std::endl;
01397 throw Exception("TBaseSet<T,Cmp>::Insert", errstr.str(), 61);
01398 }
01399 #endif
01400 if(!mDetached) Detach();
01401 return pSet->insert(rElem).second;
01402 }
01403
01404
01405 template<class T, class Cmp>
01406 void TBaseSet<T,Cmp>::InsertSet(const TBaseSet& rOtherSet) {
01407 FD_DC("TBaseSet(" << this << ")::InsertSet(" << &rOtherSet << ")");
01408 if(!mDetached) Detach();
01409
01410 iterator it1 = pSet->begin();
01411 iterator it2 = rOtherSet.pSet->begin();
01412 while ((it1 != pSet->end()) && (it2 != rOtherSet.pSet->end())) {
01413 if (*it1 < *it2) {
01414 ++it1;
01415 }
01416 else if (*it1 == *it2) {
01417 ++it1;
01418 ++it2;
01419 }
01420 else {
01421 pSet->insert(*it2);
01422 ++it2;
01423 }
01424 }
01425 while (it2 != rOtherSet.pSet->end()) {
01426 pSet->insert(*it2);
01427 ++it2;
01428 }
01429 }
01430
01431
01432 template<class T, class Cmp>
01433 bool TBaseSet<T,Cmp>::Erase(const T& rElem) {
01434 if(!mDetached) Detach();
01435 return (pSet->erase(rElem)!=0);
01436 }
01437
01438
01439
01440 template<class T, class Cmp>
01441 typename TBaseSet<T,Cmp>::Iterator TBaseSet<T,Cmp>::Erase(const Iterator& pos) {
01442 #ifdef FAUDES_CHECKED
01443 if (pos == End()) {
01444 std::stringstream errstr;
01445 errstr << "iterator out of range " << std::endl;
01446 throw Exception("TBaseSet<T,Cmp>::Erase", errstr.str(), 62);
01447 }
01448 #endif
01449 Detach();
01450 iterator del= pos.StlIterator();
01451 iterator res= del;
01452 res++;
01453 pSet->erase(del);
01454 return ThisIterator(res);
01455 }
01456
01457
01458
01459 template<class T, class Cmp>
01460 void TBaseSet<T,Cmp>::EraseSet(const TBaseSet& rOtherSet) {
01461 FD_DC("TBaseSet(" << this << ")::EraseSet(" << &rOtherSet << ")");
01462 if(!mDetached) Detach();
01463
01464 iterator tmpit;
01465 iterator it = pSet->begin();
01466 iterator oit = rOtherSet.pSet->begin();
01467 while ((it != pSet->end()) && (oit != rOtherSet.pSet->end())) {
01468 if (*it < *oit) {
01469 it=pSet->lower_bound(*oit);
01470 }
01471 else if (*it == *oit) {
01472 tmpit=it;
01473 ++it;
01474 ++oit;
01475 pSet->erase(tmpit);
01476 }
01477 else {
01478 oit=rOtherSet.pSet->lower_bound(*it);
01479 }
01480 }
01481 }
01482
01483
01484
01485 template<class T, class Cmp>
01486 typename TBaseSet<T,Cmp>::Iterator TBaseSet<T,Cmp>::Find(const T& rElem) const {
01487 return ThisIterator(pSet->find(rElem));
01488 }
01489
01490
01491 template<class T, class Cmp>
01492 bool TBaseSet<T,Cmp>::Exists(const T& rElem) const {
01493 return pSet->find(rElem) != pSet->end();
01494 }
01495
01496
01497
01498 template<class T, class Cmp>
01499 void TBaseSet<T,Cmp>::SetUnion(const TBaseSet& rOtherSet) {
01500 if(!mDetached) Detach();
01501 iterator it1 = pSet->begin();
01502 iterator it2 = rOtherSet.pSet->begin();
01503 while ((it1 != pSet->end()) && (it2 != rOtherSet.pSet->end())) {
01504 if (*it1 < *it2) {
01505 ++it1;
01506 continue;
01507 }
01508 if (*it1 == *it2) {
01509 ++it1;
01510 ++it2;
01511 continue;
01512 }
01513
01514 pSet->insert(it1,*it2);
01515 ++it2;
01516 }
01517 while (it2 != rOtherSet.pSet->end()) {
01518 pSet->insert(pSet->end(),*it2);
01519 ++it2;
01520 }
01521 }
01522
01523
01524 template<class T, class Cmp>
01525 void TBaseSet<T,Cmp>::SetIntersection(const TBaseSet& rOtherSet) {
01526 if(!mDetached) Detach();
01527 iterator tmpit;
01528 iterator it1 = pSet->begin();
01529 iterator it2 = rOtherSet.pSet->begin();
01530 while ((it1 != pSet->end()) && (it2 != rOtherSet.pSet->end())) {
01531 if (*it1 < *it2) {
01532 tmpit=it1;
01533 ++it1;
01534 pSet->erase(tmpit);
01535 continue;
01536 }
01537 if (*it1 == *it2) {
01538 ++it1;
01539 ++it2;
01540 continue;
01541 }
01542
01543 ++it2;
01544 }
01545 while(it1 != pSet->end()) {
01546 tmpit=it1;
01547 ++it1;
01548 pSet->erase(tmpit);
01549 }
01550 }
01551
01552
01553
01554 template<class T, class Cmp>
01555 TBaseSet<T,Cmp> TBaseSet<T,Cmp>::operator + (const TBaseSet& rOtherSet) const {
01556 FD_DC("TBaseSet(" << this << ")::operator + (" << &rOtherSet << ")");
01557 TBaseSet res;
01558 res.Detach();
01559 std::insert_iterator< std::set<Idx> > insit(*res.pSet, res.pSet->begin());
01560 std::set_union(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end(), insit);
01561 res.Name(CollapsString(Name() + "+" + rOtherSet.Name()));
01562 return res;
01563 }
01564
01565
01566 template<class T, class Cmp>
01567 TBaseSet<T,Cmp> TBaseSet<T,Cmp>::operator - (const TBaseSet& rOtherSet) const {
01568 FD_DC("TBaseSet(" << this << ")::operator - (" << &rOtherSet << ")");
01569 TBaseSet res;
01570 res.Detach();
01571 std::insert_iterator< std::set<Idx> > insit(*res.pSet, res.pSet->begin());
01572 std::set_difference(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end(), insit);
01573 res.Name(CollapsString(Name() + "-" + rOtherSet.Name()));
01574 return res;
01575 }
01576
01577
01578
01579 template<class T, class Cmp>
01580 TBaseSet<T,Cmp> TBaseSet<T,Cmp>::operator * (const TBaseSet& rOtherSet) const {
01581 FD_DC("TBaseSet(" << this << ")::operator * (" << &rOtherSet << ")");
01582 TBaseSet res;
01583 res.Detach();
01584 std::insert_iterator< std::set<Idx> > insit(*res.pSet, res.pSet->begin());
01585 std::set_intersection(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end(), insit);
01586 res.Name(CollapsString(Name() + "*" + rOtherSet.Name()));
01587 return res;
01588 }
01589
01590
01591
01592 template<class T, class Cmp>
01593 bool TBaseSet<T,Cmp>::operator == (const TBaseSet& rOtherSet) const {
01594 return ( *pSet == *rOtherSet.pSet );
01595 }
01596
01597
01598 template<class T, class Cmp>
01599 bool TBaseSet<T,Cmp>::operator != (const TBaseSet& rOtherSet) const {
01600 return ( *pSet != *rOtherSet.pSet );
01601 }
01602
01603
01604 template<class T, class Cmp>
01605 bool TBaseSet<T,Cmp>::operator <= (const TBaseSet& rOtherSet) const {
01606 return ( std::includes(rOtherSet.pSet->begin(), rOtherSet.pSet->end(), pSet->begin(), pSet->end()) ) ;
01607 }
01608
01609
01610 template<class T, class Cmp>
01611 bool TBaseSet<T,Cmp>::operator >= (const TBaseSet& rOtherSet) const {
01612 return ( std::includes(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end()) );
01613 }
01614
01615
01616 template<class T, class Cmp>
01617 bool TBaseSet<T,Cmp>::operator < (const TBaseSet& rOtherSet) const {
01618 return *pSet < *rOtherSet.pSet;
01619 }
01620
01621
01624 }
01625
01626 #define BASESET_H
01627 #endif