libFAUDES

Sections

Index

baseset.h

Go to the documentation of this file.
00001 /** @file baseset.h @brief Class TBaseSet */
00002 
00003 
00004 /* FAU Discrete Event Systems Library (libfaudes)
00005 
00006    Copyright (C) 2008  Thomas Moor
00007    Exclusive copyright is granted to Klaus Schmidt
00008 
00009    This library is free software; you can redistribute it and/or
00010    modify it under the terms of the GNU Lesser General Public
00011    License as published by the Free Software Foundation; either
00012    version 2.1 of the License, or (at your option) any later version.
00013 
00014    This library is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017    Lesser General Public License for more details.
00018 
00019    You should have received a copy of the GNU Lesser General Public
00020    License along with this library; if not, write to the Free Software
00021    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00022 
00023 
00024 
00025 #ifndef FAUDES_BASESET_H
00026 #define FAUDES_BASESET_H
00027 
00028 #include "definitions.h"
00029 #include "tokenwriter.h"
00030 #include "tokenreader.h"
00031 #include "rtiregistry.h"
00032 #include "rtitypes.h"
00033 #include "attributes.h"
00034 #include <set>
00035 #include <algorithm>
00036 
00037 namespace faudes {
00038 
00039 /** @addtogroup ContainerClasses */
00040 /** @{*/
00041 
00042 // Forward declaration for the attributed version of baseset
00043 template<class T, class Attr, class Cmp> class TaBaseSet;
00044 
00045 /**
00046  * STL style set template.
00047  * This class template is built on top of the STL set template. It provides essentials of 
00048  * the STL interface relevant to libFAUDES plus a deferred copy mechanism, aka copy-on-write. 
00049  * TBaseSet serves as a base class for all libFaudes containers: 
00050  * - IndexSet (indices), 
00051  * - TaIndexSet (indices with attributes), 
00052  * - SymbolSet (symbolic names), 
00053  * - NameSet (indices with symbolic names), 
00054  * - TaNameSet (indices with attributes and symbolic names), 
00055  * - TTransSet (transitions in a sepcific order),
00056  * - TaTransSet (transitions in std order with attribute).
00057  *
00058  * The public functions of a TBaseSet provide the high-level api, with the intention
00059  * to organize the deferred copy machanism in a transparent manner. Since STL iterators
00060  * refer to a particular STL container, they become invalid when the internal container 
00061  * is copied. Therefor, TBaseSet tracks iterators and fixes them when the actual copy takes place.
00062  * Clearly, this introduces some overhead, in particular when your application represents
00063  * subsets as sets of iterators. You may use the public method Lock() to enforce 
00064  * a full copy and to prevent any further re-allocation.
00065  *
00066  * Alternatively to the high-level api, a protected low-level api is provided with direct 
00067  * access to the internal STL set. When using this api, it is up to the derived class to ensure
00068  * that the BaseSet gets detached from its refernces befor write operations can take
00069  * place. 
00070  *
00071  * The virtual function TBaseSet<T>::Valid() is used to indicate whether a candidate
00072  * element is valid as a set member. If the macro FAUDES_CHECKED
00073  * is defined, the attempt to insert an invalid element triggers an exception (id 61). Invalid
00074  * iterators throw an exception (id 62) when used as an argument to a BaseSet function. 
00075  *
00076  * While the TBaseSet itself does not provide any attributes attached to its elements, it
00077  * does provide an interface to attributes implemented in derived classes. The implementation
00078  * of the interface behaves as if the attribute type was AttributeVoid. Thus, there is
00079  * a uniform access to attributes for all faudes container classes. The actual attribute
00080  * type can be detected via the C++ RTTI. 
00081  *
00082  * Note on a boring technical detail: 
00083  * since STL sets are sorted, effectively all set iterators should be const.
00084  * However, there is a minor issue whether or not the erase function should use a 
00085  * const iterator as argument. SGI derived STL implementations (as used on most GNU systems) 
00086  * avoid this issue by defining const and non-const iterators on sets as identical types. 
00087  * MS implementation (used in VS C++ by default) differ in this aspect. The class 
00088  * TBaseSet::Iterator hides the issue from the faudes API but it is still present internaly: 
00089  * in its current implementation, libfaudes will not compile with MS STL. At this stage we are 
00090  * aware of two workarounds, one simple but on cost of performance, one a little bit awkward. 
00091  * Let us know if MS STL is missioncrititical for your libfaudes application.
00092  *
00093  */
00094 
00095 template<class T, class Cmp=std::less<T> >
00096   class TBaseSet : public Type {
00097 
00098 FAUDES_TYPE_DECLARATION(TBaseSet,Type)
00099 
00100 
00101   /** 
00102    * We implement "protected privacy for template classes" by friendship.
00103    * This is used for the pragmatic implemention conversion constructors.
00104    */
00105   template<class TP, class AP, class CP> friend class TaBaseSet;
00106 
00107 
00108 public:
00109 
00110   /**
00111    * Constructor. 
00112    */
00113   TBaseSet(void);
00114 
00115   /**
00116    * Copy-constructor. 
00117    *
00118    * @param rOtherSet 
00119    *    Source to copy from
00120    */
00121   TBaseSet(const TBaseSet& rOtherSet);
00122 
00123   /**
00124    * Constructor from file.
00125    * This constructor indicates the intended interface for derived classes. The base set 
00126    * itself cannot read from token streams.
00127    *
00128    * @param rFilename
00129    *   Name of File
00130    * @param rLabel
00131    *   Section for the set in the file; 
00132    */
00133   TBaseSet(const std::string& rFilename, const std::string& rLabel = "BaseSet");
00134 
00135   /**
00136    * Virtual destructor
00137    */
00138   virtual ~TBaseSet(void);
00139 
00140   /** 
00141    * Return name of TBaseSet 
00142    * 
00143    * @return
00144    *   Name of TBaseSet
00145    */
00146   const std::string& Name(void) const;
00147         
00148   /**
00149    * Set name of TBaseSet
00150    *
00151    * @param rName
00152    *   Name to set
00153    */
00154   void Name(const std::string& rName);
00155 
00156   /** 
00157    * Clear all set
00158    */
00159   virtual void Clear(void);
00160       
00161   /**
00162    * Get Size of TBaseSet
00163    *
00164    * @return 
00165    *   Number of indices in TBaseSet
00166    */
00167   Idx Size(void) const;
00168 
00169   /** 
00170    * Check if the TBaseSet ist Empty 
00171    *
00172    * @return 
00173    *   True if empty
00174    */
00175   bool Empty(void) const;
00176 
00177   /**
00178    * Return pretty printable element. 
00179    * Reimplement this method for derived classes.
00180    *
00181    * @param rElem
00182    *   Element to print
00183    *
00184    * @return
00185    *   String
00186    */
00187   virtual std::string Str(const T& rElem) const;
00188 
00189   /** 
00190    * Iterator class for high-level api to TBaseSet.
00191    *
00192    */
00193   class Iterator;
00194 
00195   /** 
00196    * Iterator to the begin of set
00197    *
00198    * @return 
00199    *   Iterator
00200    */
00201   Iterator Begin(void) const;
00202         
00203   /** 
00204    * Iterator to the end of set
00205    *
00206    * @return 
00207    *   Iterator
00208    */
00209   Iterator End(void) const;
00210 
00211   /**
00212    * Test validty of candidate element.
00213    *
00214    * Reimplement this function for particular type T of elements,
00215    * eg for an index set with T=Idx indicate 0 an invalid index.
00216    *
00217    * @param rElem
00218    *    Candidate to test
00219    * @return
00220    *    True if element is valid
00221    */
00222   virtual bool Valid(const T& rElem) const;
00223    
00224 
00225   /** 
00226    * Erase element by reference
00227    *
00228    * @param rElem
00229    *    Element to erase
00230    * @return
00231    *    True if element used to exist
00232    */
00233   virtual bool Erase(const T& rElem);
00234 
00235 
00236   /** 
00237    * Erase element by iterator 
00238    *
00239    * @param pos
00240    *    Iterator to specify element
00241    * @return 
00242    *    Iterator to next element (or End if no such)
00243    */
00244   virtual Iterator Erase(const Iterator& pos); 
00245 
00246 
00247   /** 
00248    * Erase elements given by other set 
00249    *
00250    * @param rOtherSet 
00251    *    Set of elements to erase
00252    */
00253   virtual void EraseSet(const TBaseSet& rOtherSet);
00254 
00255   /** 
00256    * Restrict elements given by other set 
00257    *
00258    * @param rOtherSet 
00259    *    Set of elements to keep
00260    */
00261   virtual void RestrictSet(const TBaseSet& rOtherSet);
00262 
00263 
00264   /** 
00265    * Insert specified element
00266    *
00267    * @param rElem
00268    *    Element to insert
00269    * @return
00270    *   True if index was new to set 
00271    */
00272   virtual bool Insert(const T& rElem);
00273 
00274   /**
00275    * Insert elements given by rOtherSet 
00276    *
00277    *
00278    * @param rOtherSet
00279    *   Set of elements to insert
00280    */
00281   virtual void InsertSet(const TBaseSet& rOtherSet);
00282 
00283   /**
00284    * Set Union, result is accumulated in this set.
00285    *
00286    * @param rOtherSet
00287    *   Other TBaseSet
00288    */
00289   virtual void SetUnion(const TBaseSet& rOtherSet);
00290 
00291   /**
00292    * Set Intersection, result is stored in this set.
00293    * 
00294    * @param rOtherSet
00295    *   Other TBaseSet
00296    */
00297   virtual void SetIntersection(const TBaseSet& rOtherSet);
00298 
00299 
00300   /**
00301    * Test existence of element
00302    *
00303    * @param rElem
00304    *   Element to test
00305    *
00306    * @return 
00307    *   True if element exists in set
00308    */
00309   bool Exists(const T& rElem) const;
00310 
00311   /**
00312    * Find element and return iterator.
00313    *
00314    * @param rElem
00315    *   Element to find
00316    *
00317    * @return 
00318    *   Iterator to element or End() if nonexistent
00319    */
00320   Iterator Find(const T& rElem) const;
00321 
00322   /**
00323    * Set union operator
00324    *
00325    * @return 
00326    *   Union Set
00327    */
00328    TBaseSet operator+ (const TBaseSet& rOtherSet) const;
00329 
00330   /**
00331    * Set difference operator
00332    *
00333    * @return 
00334    *   Difference Set
00335    */
00336    TBaseSet operator- (const TBaseSet& rOtherSet) const;
00337 
00338   /**
00339    * Set intersection operator
00340    *
00341    * @return 
00342    *   Intersection Set
00343    */
00344   TBaseSet operator* (const TBaseSet& rOtherSet) const;
00345 
00346 
00347   /** Test for subset  */
00348   bool operator<= (const TBaseSet& rOtherSet) const;
00349 
00350   /** Test for superset */
00351   bool operator>= (const TBaseSet& rOtherSet) const;
00352 
00353   /** Order for sorting containers of TBaseSet */
00354   bool operator< (const TBaseSet& rOtherSet) const;
00355 
00356   /** Some validation of deferred copy mechanism (provoke abort)*/
00357   void DValid(const std::string& rMessage="") const;
00358 
00359   /** Detach from extern storage (incl allocation and true copy) */
00360   virtual void Detach(void) const;
00361 
00362   /** Detach and lock any further reallocation */
00363   virtual void Lock(void) const;
00364 
00365   /** 
00366    * Iterator class for high-level api to TBaseSet.
00367    * This class is derived from STL interators to additionally provide
00368    * a reference of the container to iterate on. This feature
00369    * is used to adjust iterators when the actual set gets reallocated due to a Detach()
00370    * operation. Inheritance is private to ensure that all high-level api functions maintain
00371    * iteretor refernces consistently. Currently, high-level api iterators support
00372    * the operators -&gt; ,*,  =, ++, --, ==, !=.
00373    * 
00374    * Technical detail: the private inheritance prohibits the direct use of stl algorithms on
00375    * faudes Iterators. If you need direct access to stl algorithms from outside the faudes set
00376    * class, you may turmn to public inheritance. Make sure to Lock the relevant sets befor
00377    * applying any stl algorithms.
00378    */
00379    class Iterator : private std::set<T,Cmp>::const_iterator {
00380      public: 
00381      /** Default constructor, container unknown */
00382      Iterator() : 
00383        std::set<T,Cmp>::const_iterator() , 
00384        pBaseSet(NULL),
00385        mAttached(false) 
00386      {};
00387 
00388      /** Construct by members, used by TBaseSet to create temporary iterators */
00389      Iterator(
00390        const TBaseSet<T,Cmp>* pBaseSet,
00391        const typename std::set<T,Cmp>::const_iterator& sit) : 
00392        std::set<T,Cmp>::const_iterator(sit), 
00393        pBaseSet(pBaseSet),
00394        mAttached(false)  
00395      {};
00396 
00397      /** Copy constructor, copies container reference, incl attach */
00398      Iterator(const Iterator& fit) : 
00399        std::set<T,Cmp>::const_iterator(fit),
00400        pBaseSet(fit.pBaseSet), 
00401        mAttached(false) 
00402      {
00403        if(pBaseSet) {
00404           pBaseSet->AttachIterator(this);
00405           mAttached=true;
00406        }
00407      };  
00408 
00409      /** Destructor */
00410      ~Iterator(void) { 
00411        if(mAttached) pBaseSet->DetachIterator(this);
00412      }; 
00413 
00414      /** Assigment, tracks container */
00415      const Iterator& operator= (const Iterator& rSrc) {
00416 #ifdef FAUDES_DEBUG_CODE
00417        if(rSrc.pBaseSet==NULL) {
00418          FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator= invalid iterator: no baseset");
00419          abort();
00420        }
00421 #endif
00422        // performance relevant std case 
00423        if(mAttached) if(pBaseSet==rSrc.pBaseSet) {
00424          std::set<T,Cmp>::const_iterator::operator= (rSrc);
00425          return *this;
00426        }
00427        // general case
00428        if(mAttached) pBaseSet->DetachIterator(this);
00429        std::set<T,Cmp>::const_iterator::operator= (rSrc);
00430        pBaseSet = rSrc.pBaseSet;
00431        if(pBaseSet) {
00432          pBaseSet->AttachIterator(this);
00433          mAttached=true;
00434        } else {
00435   mAttached=false;
00436        }
00437        return *this;
00438      };
00439 
00440      /** Assign STL iterator only */
00441      void  StlIterator(const typename std::set<T,Cmp>::const_iterator& sit) {
00442        std::set<T,Cmp>::const_iterator::operator= (sit);
00443      };
00444 
00445      /** Get STL iterator only */
00446      const typename std::set<T,Cmp>::const_iterator& StlIterator(void) const {
00447        return *this;
00448      };
00449 
00450      /** Invalidate */
00451      void  Invalidate(void) {
00452        pBaseSet=NULL;
00453        mAttached=false;
00454      }; 
00455 
00456      /** Detach */
00457      void  Detach(void) {
00458        mAttached=false;
00459      }; 
00460 
00461 
00462      /** Check validity (provoke abort error) */
00463      void DValid(void) const {
00464       if(pBaseSet==NULL) {
00465          FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):DValid(): invalid iterator: no baseset");
00466          abort();
00467        }
00468        pBaseSet->DValid();
00469      }; 
00470 
00471     /** Reimplement dereference */
00472      const T* operator-> (void) const {
00473 #ifdef FAUDES_DEBUG_CODE
00474        if(pBaseSet==NULL) {
00475          FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator->: invalid iterator: no baseset");
00476          abort();
00477        }
00478 #endif
00479        return std::set<T,Cmp>::const_iterator::operator-> ();
00480      };
00481 
00482      /** Reimplement derefernce */
00483      const T& operator* (void) const {
00484 #ifdef FAUDES_DEBUG_CODE
00485        if(pBaseSet==NULL) {
00486          FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator*: invalid iterator: no baseset");
00487          abort();
00488        }
00489 #endif
00490        return std::set<T,Cmp>::const_iterator::operator* ();
00491      };
00492 
00493      /** Reimplement == */
00494      bool operator== (const Iterator& rOther) const {
00495 #ifdef FAUDES_DEBUG_CODE
00496        if(pBaseSet==NULL) {
00497          FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator==: invalid iterator: no baseset");
00498          abort();
00499        }
00500 #endif
00501        return std::set<T,Cmp>::const_iterator::operator== (rOther);
00502      };
00503 
00504      /** Reimplement != */
00505      bool operator!= (const Iterator& rOther) const {
00506 #ifdef FAUDES_DEBUG_CODE
00507        if(pBaseSet==NULL) {
00508          FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator!=: invalid iterator: no baseset");
00509          abort();
00510        }
00511 #endif
00512        return std::set<T,Cmp>::const_iterator::operator!= (rOther);
00513      };
00514 
00515      /** Reimplement postfix ++ */
00516      Iterator operator++ (int step) {
00517 #ifdef FAUDES_DEBUG_CODE
00518        if(pBaseSet==NULL) {
00519          FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator++: invalid iterator: no baseset");
00520          abort();
00521        }
00522 #endif
00523        Iterator old(pBaseSet,*this);
00524        std::set<T,Cmp>::const_iterator::operator++ (step);
00525        return old;
00526      };
00527 
00528      /** Reimplement prefix ++ */
00529      const Iterator& operator++ (void) {
00530 #ifdef FAUDES_DEBUG_CODE
00531        if(pBaseSet==NULL) {
00532          FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator++: invalid iterator: no baseset");
00533          abort();
00534        }
00535 #endif
00536        std::set<T,Cmp>::const_iterator::operator++ ();
00537        return *this;
00538      };
00539 
00540      /** Reimplement postfix -- */
00541      Iterator operator-- (int step) {
00542 #ifdef FAUDES_DEBUG_CODE
00543        if(pBaseSet==NULL) {
00544          FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator--: invalid iterator: no baseset");
00545          abort();
00546        }
00547 #endif
00548        Iterator old(pBaseSet, *this);
00549        std::set<T,Cmp>::const_iterator::operator-- (step);
00550        return old;
00551      };
00552 
00553      /** Reimplement prefix -- */
00554      const Iterator& operator-- (void) {
00555 #ifdef FAUDES_DEBUG_CODE
00556        if(pBaseSet==NULL) {
00557          FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator--: invalid iterator: no baseset");
00558          abort();
00559        }
00560 #endif
00561        std::set<T,Cmp>::const_iterator::operator-- ();
00562        return *this;
00563      };
00564 
00565 
00566      /** Order by reference for containers of Iterators < */
00567      /*
00568      bool operator< (const Iterator& rOther) const {
00569        return this < &rOther;
00570      };
00571      */
00572 
00573      /** Maintaine container reference */
00574      const TBaseSet<T,Cmp>* pBaseSet;
00575 
00576      /** Indocate that this iterator is attached to some baseset */
00577      bool mAttached;
00578    };
00579 
00580 #ifdef DONT_TRACK_REFERENCES
00581 
00582   /** 
00583    * Iterator class for high-level api to TBaseSet.
00584    * This version is a dummy and does not provide any additional features.
00585    */
00586    class Iterator : public std::set<T,Cmp>::const_iterator {
00587      public:
00588 
00589      /** Default contructor */
00590      Iterator(void) : 
00591        std::set<T,Cmp>::const_iterator()  
00592      {}; 
00593 
00594      /** Copy constructor  */
00595      Iterator(const Iterator& fit) : 
00596        std::set<T,Cmp>::const_iterator(fit)
00597      {};
00598 
00599      /** Copy constructor  */
00600      Iterator(const typename std::set<T,Cmp>::const_iterator& sit) : 
00601        std::set<T,Cmp>::const_iterator(sit)
00602      {};
00603 
00604      /** Copy constructor, compatibility  */
00605      Iterator(
00606        const TBaseSet<T,Cmp>* pBaseSet,
00607        const typename std::set<T,Cmp>::const_iterator& sit) : 
00608        std::set<T,Cmp>::const_iterator(sit) 
00609      {};
00610 
00611      /** Assign STL iterator only, compatibility */
00612      void  StlIterator(const typename std::set<T,Cmp>::const_iterator& sit) {
00613        std::set<T,Cmp>::const_iterator::operator= (sit);
00614      }; 
00615 
00616      /** Get STL iterator only, compatibility */
00617      const typename std::set<T,Cmp>::const_iterator& StlIterator(void) const {
00618        return *this;
00619      };
00620 
00621      /** Invalidate, compatibility */
00622      void  Invalidate(void) {};
00623 
00624    };
00625 
00626 #endif
00627 
00628   /** 
00629    * Attribute typeinfo.
00630    * This virtual function provides an interface for derived container classes with attributes 
00631    * eg TaIndexSet. When not re-implemented, it returns an attribute with type AttributeVoid to
00632    * indicate the absence of nontrivial attributes
00633    */
00634   virtual const AttributeVoid* Attributep(void) const;
00635 
00636   /** 
00637    * Attribute typeinfo.
00638    * This virtual function provides an interface for derived container classes with attributes 
00639    * eg TaIndexSet. When not re-implemented, it returns an attribute with type AttributeVoid to
00640    */
00641   virtual const AttributeVoid& Attribute(void) const;
00642 
00643   /** 
00644    * Attribute typeinfo.
00645    * This virtual function provides an interface for derived classes with attributes eg TaIndexSet. 
00646    * It is meant to test whether this set accepts the specified attribute type ie whether it can be casted.
00647    * When not re-implemented, the set accepts any attributes derived from attribute void.
00648    * @param rAttr
00649    *     Attribute type to test.
00650    * @return True, if attribute type is accepted.
00651    */
00652   virtual bool AttributeTry(const Type& rAttr) const {return dynamic_cast< const AttributeVoid* >(&rAttr)!=0;};
00653 
00654   /**
00655    * Attribute access.
00656    * This virtual function provides an interface for derived classes with attributes eg TaIndexSet. 
00657    * It is meant to ignore any attributes. The TBaseSet itself has no attributes, so it calls its
00658    * Assign method that ignores attributes anyway.
00659    *
00660    * @param rSourceSet 
00661    *    Set to copy from
00662    */
00663    virtual TBaseSet& AssignWithoutAttributes(const TBaseSet& rSourceSet) { return TBaseSet::Assign(rSourceSet); };
00664 
00665   /**
00666    * Attributes access. 
00667    * This virtual function provides an interface for derived classes with attributes eg TaIndexSet. 
00668    * It is meant to copy attributes from the specified set.
00669    * The TBaseSet itself has no attributes and thus this function does nothing.
00670    *
00671    * @param rOtherSet
00672    *   Other BaseSet
00673    */
00674   virtual void Attributes(const TBaseSet& rOtherSet) { (void) rOtherSet; };
00675 
00676 
00677   /** 
00678    * Attribute access.
00679    * This virtual function provides an interface for derived classes with attributes eg TaIndexSet. 
00680    * It is meant to provide the number of explicit attributes.
00681    * The TBaseSet itself has no attributes and thus this function returns 0.
00682    */
00683   virtual Idx AttributesSize(void) const { return 0; };
00684 
00685   /** 
00686    * Attribute access.
00687    * This virtual function provides an interface for derived classes with attributes eg TaIndexSet. 
00688    * The TBaseSet itself has no attributes and thus this function does nothing.
00689    */
00690   virtual void ClearAttributes(void) { };
00691 
00692   /**
00693    * Attribute access.
00694    * This virtual function provides an interface for derived classes with attributes eg TaIndexSet. 
00695    * Derived classes that provide attributes are meant to return true if attributes
00696    * match for shared elements. The base set returns true as a default.
00697    * @param rOtherSet 
00698    *    Other object to compare with.
00699    * @return 
00700    *   True on match.
00701    */
00702   virtual bool EqualAttributes(const TBaseSet& rOtherSet) const { 
00703     return typeid(*rOtherSet.Attributep())==typeid(const AttributeVoid);};
00704 
00705   /** 
00706    * Attribute access.
00707    * This virtual function provides an interface for derived classes with attributes eg TaIndexSet. 
00708    * The TBaseSet has no attributes and thus throws an exception. 
00709    * Derived classes that provide attributes are meant to return a pointer to the attribute specified by rElem.
00710    *
00711    * @param rElem
00712    *     Element of which the attribute is requested
00713    * @return 
00714    *     Attribute of specified element
00715    * @exception Exception
00716    *   - No attributes provided (id 63)
00717    */
00718   virtual AttributeVoid* Attributep(const T& rElem);
00719 
00720   /** 
00721    * Attribute access.
00722    * This virtual function provides an interface for derived classes with attributes eg TaIndexSet. 
00723    * The TBaseSet has no attributes and thus returns a void attribute.
00724    * Derived classes that provide attributes are meant to return the attribute specified by rElem.
00725    * @param rElem
00726    *     Element of which the attribute is requested
00727    * @return 
00728    *     Attribute of specified element
00729    */
00730   virtual const AttributeVoid& Attribute(const T& rElem) const;
00731 
00732   /** 
00733    * Attribute access.
00734    * This virtual function provides an interface for derived classes with attributes eg TaIndexSet. 
00735    * The TBaseSet itself has void attributes and thus formally accepts any nontrivial attribute, 
00736    * however, ignoring any value.
00737    * Derived classes that provide attributes are meant to set the attribute as specified. Only if the
00738    * required cast to the actual attribute type fails an exception is thrown.
00739    * @param rElem
00740    *     Element of which the attribute is to be set
00741    * @param rAttr
00742    *     Attribute value to set.
00743    * @exception Exception
00744    *   - Element does not exist (60)
00745    *   - Cannot cast attribute type (63)
00746    */
00747   virtual void Attribute(const T& rElem, const Type& rAttr);
00748 
00749   /** 
00750    * Attribute access.
00751    * This virtual function provides an interface for derived classes with attributes eg TaIndexSet. 
00752    * It is meant to try to set the attribute as specified if the type can be casted. Otherwise it does nothing.
00753    * @param rElem
00754    *     Element of which the attribute is to be set
00755    * @param rAttr
00756    *     Attribute value to set.
00757    */
00758    virtual void AttributeTry(const T& rElem, const Type& rAttr) { (void) rElem; (void) rAttr; };
00759 
00760   /** 
00761    * Attribute access.
00762    * This virtual function provides an interface for derived classes with attributes eg TaIndexSet. 
00763    * It is meant to set the attribute of the specified element to the default value.
00764    * The TBaseSet itself has no attributes and thus this function does nothing.
00765    * @param rElem
00766    *     Element of which the attribute is to be cleared
00767    */
00768    virtual void ClrAttribute(const T& rElem) { (void) rElem; };
00769 
00770 
00771 
00772 protected:
00773 
00774 
00775   /** 
00776    * Token output, see Type::DWrite for public wrappers.
00777    * Reimplement this function in derived classes for specific
00778    * specific template parameters. By convention, the default label ""
00779    * should be translated to a) the name of the set or b) some meaningful default, 
00780    * eg "IndexSet" for a set of indices". The pContext pointer can de type-checked
00781    * and interpreted, ie as a symboltable to provide symbolic names. It is also
00782    * passed on to attributes.
00783    *
00784    * @param rTw
00785    *   Reference to TokenWriter
00786    * @param rLabel
00787    *   Label of section to write, defaults to name of set
00788    * @param pContext
00789    *   Write context to provide contextual information
00790    */
00791   virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="", const Type* pContext=0) const;
00792 
00793   /** 
00794    * Token output, debugging see Type::DWrite for public wrappers.
00795    * Reimplement this function in derived classes for specific
00796    * specific template parameters.
00797    * @param rTw
00798    *   Reference to TokenWriter
00799    * @param rLabel
00800    *   Label of section to write, defaults to name of set
00801    * @param pContext
00802    *   Write context to provide contextual information
00803    */
00804   virtual void DoDWrite(TokenWriter& rTw,const std::string& rLabel="", const Type* pContext=0) const;
00805 
00806   /** 
00807    * Token output, see Type::SWrite for public wrappers.
00808    * Statistics include size, name and attributey type. The latter
00809    * is retrieved from the RTI, if initialized. Dereived sets may reimplement
00810    * this method.
00811    *
00812    * @param rTw
00813    *   Reference to TokenWriter
00814    */
00815   virtual void DoSWrite(TokenWriter& rTw) const;
00816 
00817   /**
00818    * Token input, see Type::Read for public wrappers.
00819    * Reimplement this function in derived classes for specific
00820    * specific template parameters.
00821    * By convention, the default label "" should be translated to some meaningful default, 
00822    * eg "IndexSet" for a set of indices". The pContext pointer can de type-checked
00823    * and interpreted, ie as a symboltable to provide symbolic names. It is also
00824    * passed on to attributes.
00825    *
00826    * @param rTr
00827    *   Reference to TokenReader
00828    * @param rLabel
00829    *   Label of section to read, defaults to name of set
00830    * @param pContext
00831    *   Read context to provide contextual information
00832    */
00833   virtual void DoRead(TokenReader& rTr, const std::string& rLabel = "", const Type* pContext=0);
00834 
00835   /** assign my members */
00836   virtual TBaseSet& DoAssign(const TBaseSet& rSourceSet);
00837 
00838   /** test equality */
00839   virtual bool DoEqual(const TBaseSet& rOtherSet) const;
00840 
00841   /** STL set, if the object owns content (else NULL) */
00842   std::set<T,Cmp>* mpSet;
00843 
00844   /** Attribute map, if this object owns content (else NULL). */
00845   std::map<T,AttributeVoid*>* mpAttributes;
00846 
00847   /** static empty STL set for default constructor */
00848   static std::set<T,Cmp> mEmptySet;
00849 
00850   /** static empty STL map for default constructor */
00851   static std::map<T,AttributeVoid*> mEmptyAttributes;
00852 
00853   /** Pointer on STL set to operate on */
00854   std::set<T,Cmp>* pSet;
00855 
00856   /** Pointer to attribute map to operate on */
00857   std::map<T,AttributeVoid*>* pAttributes;
00858 
00859   /** STL iterator, non-const version */
00860   typedef typename std::set<T,Cmp>::iterator iterator;
00861 
00862   /** STL iterator, const version */
00863   typedef typename std::set<T,Cmp>::const_iterator const_iterator;
00864 
00865   /** Convert STL iterator */
00866   typename TBaseSet<T,Cmp>::Iterator ThisIterator(const typename std::set<T,Cmp>::const_iterator& sit) const;
00867 
00868   /** STL attribute iterator, non-const version */
00869   typedef typename std::map<T,AttributeVoid*>::iterator aiterator;
00870 
00871   /** STL attribute iterator, const version */
00872   typedef typename std::map<T,AttributeVoid*>::const_iterator const_aiterator;
00873 
00874 
00875 protected:
00876 
00877 
00878   /** Name of TBaseSet */
00879   std::string mMyName;
00880 
00881   /** Other BaseSets, that refer to the STL set provided by this TBaseSet */
00882   std::set< TBaseSet<T,Cmp>* > mReferences;
00883 
00884   /** Pointer on BaseSet that owns the STL set this BaseSet referrs to */
00885   TBaseSet<T,Cmp>* pBaseSet;
00886 
00887   /** Indicate "has no references, provides STL set" */
00888   bool mDetached;
00889 
00890   /** Indicate "dont re-allocate the STL set again" */
00891   bool mLocked;
00892 
00893   /** Ensure that we do not serve contents to anyone else */
00894   void RelinkReferences(void);
00895 
00896   /** Record that we serve contents to some other TBaseSet */
00897   void AttachReference(TBaseSet* pRef) const;
00898 
00899   /** Record that we stop serving contents to some TBaseSet */
00900   void DetachReference(TBaseSet* pRef) const;
00901 
00902   /** Iterators that refer to this TBaseSet */
00903   std::set< Iterator* > mIterators;
00904 
00905   /** Record that an iterator refers to this TBaseSet */
00906   void AttachIterator(Iterator* pFit) const;
00907 
00908   /** Record that an iterator stops to refer to this TBaseSet */
00909   void DetachIterator(Iterator* pFit) const;
00910 
00911 };
00912 
00913 
00914 
00915 /* 
00916  * Set union, rti wrapper
00917  *
00918  * @param rSetA
00919  *  Set A
00920  * @param rSetB
00921  *  Set B
00922  * @return
00923  *  Union of set A and set B
00924  */
00925 
00926 template<class T, class Cmp>
00927 void SetUnion(const TBaseSet<T,Cmp>& rSetA, const TBaseSet<T,Cmp>& rSetB, TBaseSet<T,Cmp>& rRes) {
00928   FD_DC("FAUDES_CONTAINER: SetUnion(TBaseSet<T,Cmp>): res at " << &rRes);
00929   // fix name
00930   std::string name=CollapsString(rSetA.Name() + "+" + rSetB.Name());
00931   // all the same
00932   if(&rSetA==&rSetB && &rSetA==&rRes) {rRes.Name(name); return;}
00933   // a and b ths same, res different
00934   if(&rSetA==&rSetB) {rRes.Assign(rSetA); rRes.Name(name); return;}
00935   // a and res the same, b different 
00936   if(&rSetA==&rRes) {rRes.InsertSet(rSetB); rRes.Name(name); return;};
00937   // b and res the same, a different 
00938   if(&rSetB==&rRes) {rRes.InsertSet(rSetA); rRes.Name(name); return;};
00939   // else
00940   rRes.Assign(rSetA);
00941   rRes.InsertSet(rSetB);
00942   rRes.Name(name); 
00943   FD_DC("FAUDES_CONTAINER: SetUnion(TBaseSet<T,Cmp>): done, res at " << &rRes << " #" << rRes.Size());
00944 }
00945 
00946 /* 
00947  * Set difference, rti wrapper
00948  *
00949  * @param rSetA
00950  *  Set A
00951  * @param rSetB
00952  *  Set B
00953  * @return
00954  *  Set A minus set B
00955  */
00956 template< class T, class Cmp >
00957 void SetDifference(const TBaseSet<T,Cmp>& rSetA, const TBaseSet<T,Cmp>& rSetB, TBaseSet<T,Cmp>& rRes) {
00958   // fix name
00959   std::string name=CollapsString(rSetA.Name() + "-" + rSetB.Name());
00960   // a and b the same
00961   if(&rSetA==&rSetB) { rRes.Clear(); rRes.Name(name); return;}
00962   // a and res the same, b different 
00963   if(&rSetA==&rRes) {rRes.EraseSet(rSetB); rRes.Name(name); return;};
00964   // b and res the same, a different ... need buffer?
00965   if(&rSetB==&rRes) {
00966     TBaseSet<T,Cmp>* buffb=rSetB.New();
00967     buffb->Assign(rSetB);
00968     rRes.Assign(rSetA);
00969     rRes.EraseSet(*buffb); 
00970     rRes.Name(name); 
00971     delete buffb;
00972     return;
00973   }; 
00974   // else: std
00975   rRes.Assign(rSetA);
00976   rRes.EraseSet(rSetB);
00977   rRes.Name(name); 
00978 }
00979 
00980 /* 
00981  * Set intersection, rti wrapper
00982  *
00983  * @param rSetA
00984  *  Set A
00985  * @param rSetB
00986  *  Set B
00987  * @return
00988  *  Set A intersected with set B
00989  */
00990 template< class T, class Cmp >
00991 void SetIntersection(const TBaseSet<T,Cmp>& rSetA, const TBaseSet<T,Cmp>& rSetB, TBaseSet<T,Cmp>& rRes) {
00992   // fix name
00993   std::string name=CollapsString(rSetA.Name() + "*" + rSetB.Name());
00994   // all the same
00995   if(&rSetA==&rSetB && &rSetA==&rRes) {rRes.Name(name); return;}
00996   // a and b ths ame, res different
00997   if(&rSetA==&rSetB) { rRes.Assign(rSetA); rRes.Name(name); return;}
00998   // a and res the same, b different 
00999   if(&rSetA==&rRes) {rRes.RestrictSet(rSetB); rRes.Name(name); return;};
01000   // b and res the same, a different 
01001   if(&rSetB==&rRes) {rRes.RestrictSet(rSetA); rRes.Name(name); return;};
01002   // else
01003   rRes.Assign(rSetA);
01004   rRes.RestrictSet(rSetB);
01005   rRes.Name(name); 
01006 }
01007 
01008 
01009 
01010 
01011 /** @} doxygen group */
01012 
01013 
01014 
01015 /*
01016 ******************************************************************************************
01017 ******************************************************************************************
01018 ******************************************************************************************
01019 
01020 Implementation of TBaseSet
01021 
01022 ******************************************************************************************
01023 ******************************************************************************************
01024 ******************************************************************************************
01025 */
01026 
01027 /* convenience access to relevant scopes */
01028 #define THIS TBaseSet<T,Cmp> 
01029 #define TEMP template<class T, class Cmp>
01030 #define BASE Type
01031 
01032 
01033 // faudes type std: new and cast
01034 FAUDES_TYPE_IMPLEMENTATION_NEW(THIS,Type,TEMP)
01035 FAUDES_TYPE_IMPLEMENTATION_COPY(THIS,Type,TEMP)
01036 FAUDES_TYPE_IMPLEMENTATION_CAST(THIS,Type,TEMP)
01037 
01038 // faudes type std: assignemnt (break cast)
01039 //TEMP THIS& THIS::Assign(const Type& rSrc) { this->Clear(); return *this;};
01040 //TEMP THIS& THIS::Assign(const THIS& rSrc) { return DoAssign(rSrc);};
01041 // faudes type std: assignemnt (keep cast)
01042 FAUDES_TYPE_IMPLEMENTATION_ASSIGN(THIS,Type,TEMP)
01043 FAUDES_TYPE_IMPLEMENTATION_EQUAL(THIS,Type,TEMP)
01044 
01045 
01046 // template statics: empty set
01047 TEMP std::set<T,Cmp>  THIS::mEmptySet=std::set<T,Cmp>();
01048 TEMP std::map<T,AttributeVoid*> THIS::mEmptyAttributes=std::map<T,AttributeVoid*>();
01049 
01050 // TBaseSet()
01051 TEMP THIS::TBaseSet(void) :
01052   Type(),
01053   mpSet(NULL),
01054   mpAttributes(NULL),
01055   pSet(&mEmptySet),  
01056   pAttributes(&mEmptyAttributes),
01057   pBaseSet(this),
01058   mDetached(false), 
01059   mLocked(false)
01060 {
01061   FAUDES_OBJCOUNT_INC("BaseSet");
01062   FD_DC("TBaseSet(" << this << ")::TBaseSet()");
01063   // other members
01064   mMyName="BaseSet";
01065 }
01066 
01067 // TBaseSet(filename)
01068 TEMP THIS::TBaseSet(const std::string& rFileName, const std::string& rLabel)  :
01069   Type(),
01070   mpSet(NULL),
01071   mpAttributes(NULL),
01072   pSet(&mEmptySet),  
01073   pAttributes(&mEmptyAttributes),
01074   pBaseSet(this),
01075   mDetached(false), 
01076   mLocked(false) 
01077 {
01078   FAUDES_OBJCOUNT_INC("BaseSet");
01079   FD_DC("TBaseSet(" << this << ")::TBaseSet()");
01080   // other members
01081   mMyName="BaseSet";
01082   // do read etc ... this is a dummy anyway
01083   Read(rFileName,rLabel);  
01084 }
01085 
01086 // TBaseSet(rOtherSet)
01087 TEMP THIS::TBaseSet(const TBaseSet& rOtherSet) : 
01088   Type(rOtherSet),
01089   mpSet(NULL),
01090   mpAttributes(NULL),
01091   pSet(NULL),  
01092   pAttributes(NULL),
01093   pBaseSet(this),
01094   mDetached(false), 
01095   mLocked(false) 
01096 {
01097   FAUDES_OBJCOUNT_INC("BaseSet");
01098   FD_DC("TBaseSet(" << this << ")::TBaseSet(rOtherSet " << &rOtherSet << "): fake copy construct");
01099   // maintain deferred copy 
01100   pBaseSet=rOtherSet.pBaseSet;
01101   pBaseSet->AttachReference(this);
01102   pSet=rOtherSet.pSet;
01103   pAttributes=&mEmptyAttributes;
01104   // other members
01105   mMyName=rOtherSet.mMyName;
01106 #ifdef FAUDES_DEBUG_CONTAINER
01107   DValid();
01108 #endif
01109 }
01110 
01111 // destructor
01112 TEMP THIS::~TBaseSet(void) {
01113   FAUDES_OBJCOUNT_DEC("BaseSet");
01114   FD_DC("TBaseSet(" << this << ")::~TBaseSet()");
01115   // maintain deferred copy 
01116   RelinkReferences();
01117   pBaseSet->DetachReference(this);
01118   // unlink iterators (mandatory, since referenced object will be destructed)
01119   typename std::set< Iterator* >::const_iterator iit;
01120   for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01121     (**iit).Invalidate();
01122   }
01123   // delete if we still own data
01124   if(mpSet) delete mpSet;
01125   if(mpAttributes) {
01126     for(aiterator ait=mpAttributes->begin(); ait!=mpAttributes->end(); ++ait)
01127        delete ait->second;
01128     delete mpAttributes;
01129   }
01130 }
01131 
01132 
01133 // fake copy
01134 TEMP THIS& THIS::DoAssign(const THIS& rSourceSet) {
01135   FD_DC("TBaseSet(" << this << ")::DoAssign(rOtherSet " << &rSourceSet << "): fake copy");
01136   // bail out on selfref
01137   if(this==&rSourceSet) return *this;
01138   // other members 
01139   mMyName=rSourceSet.mMyName;
01140   // bail out on common shared data
01141   if(pBaseSet==rSourceSet.pBaseSet) return *this;
01142   // become independant
01143   RelinkReferences();
01144   pBaseSet->DetachReference(this);
01145   mReferences.clear();
01146   // if we are locked, should do the copy ... not implemented
01147 #ifdef FAUDES_DEBUG_CONTAINER
01148   if(mLocked) {
01149     FD_DC("TBaseSet::DoAssign(): locked target will be unlocked");
01150   }
01151 #endif
01152   // attatch myself to src
01153   pBaseSet=rSourceSet.pBaseSet;
01154   pBaseSet->AttachReference(this);
01155   pSet=rSourceSet.pSet;
01156   pAttributes=&mEmptyAttributes;
01157   // delete own old data
01158   if(mpSet) { 
01159      delete mpSet;
01160      mpSet=NULL;
01161   }
01162   if(mpAttributes) {
01163     delete mpAttributes;
01164     mpAttributes=NULL;
01165   }
01166   // record state
01167   mDetached=false; 
01168   mLocked=false;
01169   // fix iterators (invalidate)
01170   typename std::set< Iterator* >::iterator iit;
01171   for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01172     (**iit).Invalidate();
01173   }
01174   mIterators.clear();
01175 #ifdef FAUDES_DEBUG_CONTAINER
01176   DValid();
01177 #endif
01178   return *this;
01179 }
01180 
01181 // Detach()
01182 TEMP void THIS::Detach(void) const {
01183   FD_DC("TBaseSet(" << this << ")::Detach(void)");
01184 #ifdef FAUDES_DEBUG_CONTAINER
01185   DValid();
01186 #endif
01187 
01188   // nothing todo
01189   if(mDetached) return;
01190 
01191   // provide fake const
01192   THIS* fake_const = const_cast< THIS* >(this);
01193 
01194   // might have overseen reference detach
01195   if(pBaseSet->mReferences.empty() && pBaseSet->mpSet != NULL) {
01196     fake_const->mDetached=true;
01197     return;
01198   }
01199 
01200   // stragie A: references get the copy; thus, the baseset data does
01201   // not get reallocated and we dont need to track iterators. on the
01202   // downside, fixing the references iterators may be more effort.
01203   if(mLocked==true) {
01204    
01205     FD_DC("TBaseSet(" << this << ")::Detach(void): allocate and copy, strategie A");
01206     // do allocation and copy of stl set
01207     std::set<T,Cmp>* scopy = new std::set<T,Cmp>();
01208     *scopy = *pSet;     
01209     // first of my reference gets the new data and the old attributes
01210     THIS* storage = *mReferences.begin();
01211     storage->pBaseSet=storage;
01212     storage->mpSet=scopy; 
01213     storage->pSet=scopy;
01214     storage->mpAttributes=mpAttributes;
01215     storage->pAttributes=pAttributes;
01216     storage->mReferences=mReferences;
01217     storage->DetachReference(storage);
01218     // check whether new storage is detached
01219     if(storage->mReferences.empty()) 
01220        storage->mDetached=true;
01221     // set other users to new storage
01222     typename std::set< THIS* >::const_iterator rit;
01223     for(rit=mReferences.begin(), ++rit ;rit!=mReferences.end(); ++rit) {
01224       (*rit)->pBaseSet=storage;
01225       (*rit)->pSet=storage->pSet;
01226       (*rit)->pAttributes=storage->pAttributes;
01227     }
01228     // fix other users iterators (incl new storage)
01229     for(rit=mReferences.begin(); rit!=mReferences.end(); ++rit) {
01230       typename std::set< Iterator* >::iterator iit;
01231       for(iit=(*rit)->mIterators.begin(); iit!=(*rit)->mIterators.end(); ++iit) {
01232         if((**iit).StlIterator()==pSet->end()) 
01233           **iit=Iterator(this, scopy->end());
01234         else
01235           **iit=Iterator(this, scopy->find(***iit));
01236       }
01237     }
01238     // make myself own the old data and have empty attributes
01239     fake_const->mpSet=pSet;
01240     fake_const->mpAttributes=NULL;
01241     fake_const->pAttributes=&mEmptyAttributes;
01242     fake_const->mReferences.clear();
01243     fake_const->mDetached=true;    
01244     // stop tracking iterators
01245     typename std::set< Iterator* >::const_iterator iit;
01246     for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01247       (**iit).Detach();
01248     }
01249     fake_const->mIterators.clear();
01250 
01251 
01252   // stragie B: this baseset gets the copy; thus, the references iterators
01253   // remain valid and dont need to be fixed; on the downside, we need to
01254   // continue to track iterators.
01255   } else {
01256 
01257 
01258     FD_DC("TBaseSet(" << this << ")::Detach(void): allocate and copy, strategie B");
01259     // make someone else handle original data
01260     fake_const->RelinkReferences();
01261     // do allocation and copy of stl set
01262     fake_const->mpSet = new std::set<T,Cmp>();
01263     *fake_const->mpSet= *pSet;     
01264     // have empty attributes
01265     fake_const->mpAttributes=NULL;
01266     fake_const->pAttributes=&mEmptyAttributes;
01267     // fix iterators
01268     typename std::set< Iterator* >::iterator iit;
01269     for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01270       if((**iit).StlIterator()==pSet->end()) 
01271         **iit=Iterator(this, mpSet->end());
01272       else
01273         **iit=Iterator(this, mpSet->find(***iit));
01274     }
01275     // unlink from old source, link to new source
01276     pBaseSet->DetachReference(fake_const);
01277     if(pBaseSet->pBaseSet->mReferences.empty() && pBaseSet->mpSet != NULL)
01278       pBaseSet->mDetached=true;
01279     fake_const->pBaseSet=fake_const;
01280     fake_const->pSet=mpSet;
01281     fake_const->mDetached=true;
01282   }
01283 
01284 #ifdef FAUDES_DEBUG_CONTAINER
01285   DValid();
01286 #endif
01287   FD_DC("TBaseSet(" << this << ")::Detach(void): done");
01288 }
01289 
01290 // Lock()
01291 TEMP  void THIS::Lock(void) const {
01292   FD_DC("TBaseSet(" << this << ")::Lock(void)");
01293 #ifdef FAUDES_DEBUG_CONTAINER
01294   DValid();
01295 #endif
01296   // if we are locked: fine
01297   if(mLocked) return;
01298 
01299   // trigger actual copy
01300   Detach();
01301 
01302   // provide fake const
01303   THIS* fake_const = const_cast< THIS* >(this);
01304 
01305   // stop tracking iterators
01306   typename std::set< Iterator* >::const_iterator iit;
01307   for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01308     (**iit).Detach();
01309   }
01310   fake_const->mIterators.clear();
01311 
01312   // stop detach from reallocating
01313   fake_const->mLocked=true;
01314 }
01315 
01316 
01317 // if i am a source to others, make someone else source  
01318 TEMP inline void THIS::RelinkReferences(void) {
01319   FD_DC("TBaseSet::RelinkReferences(" << this << ")")
01320 #ifdef FAUDES_DEBUG_CONTAINER
01321   DValid();
01322 #endif
01323   // no references aka this is not a source
01324   if(mReferences.empty()) return;
01325   // make first ref the new storage
01326   THIS* storage = *mReferences.begin();
01327 #ifdef FAUDES_DEBUG_CODE
01328   if(storage->pBaseSet!=this) {
01329     FD_ERR("THIS::RelinkRefernces: old reference must have this as storage provider");
01330     abort();
01331   }
01332 #endif
01333   storage->pBaseSet=storage;
01334   storage->mpSet=mpSet; 
01335   storage->pSet=pSet;
01336   storage->mpAttributes=mpAttributes; 
01337   storage->pAttributes=pAttributes;
01338   storage->mReferences=mReferences;
01339   storage->DetachReference(storage);
01340   // set other users to new storage
01341   typename std::set< THIS* >::const_iterator rit;
01342   for(rit=mReferences.begin(), ++rit;rit!=mReferences.end(); ++rit) {
01343     (*rit)->pBaseSet=storage;
01344   }
01345   // make myself a reference to the new source
01346   pBaseSet=storage;
01347   pSet=storage->pSet;
01348   mpSet=NULL;
01349   pAttributes=storage->pAttributes;
01350   mpAttributes=NULL;
01351   storage->AttachReference(this);
01352   mReferences.clear();
01353 #ifdef FAUDES_DEBUG_CONTAINER
01354   DValid();
01355 #endif
01356   FD_DC("TBaseSet::RelinkReferences(" << this << "): done")
01357 }
01358 
01359 
01360 // record fake copy
01361 TEMP inline void THIS::AttachReference(TBaseSet* pRef) const {
01362    const_cast< THIS* >(this)->mReferences.insert(pRef);
01363    const_cast< THIS* >(this)->mDetached=false;
01364 }
01365 
01366 // discard fake copy
01367 TEMP inline void THIS::DetachReference(TBaseSet* pRef) const {
01368    const_cast< THIS* >(this)->mReferences.erase(pRef);
01369 }
01370 
01371 
01372 // record an iterator
01373 TEMP inline void THIS::AttachIterator(Iterator* pFit) const {
01374   if(mLocked) return;
01375   FD_DC("TBaseSet::AttachIterator(" << this << "):" << pFit)
01376   const_cast< THIS* >(this)->mIterators.insert(pFit);
01377 }
01378 
01379 // discard an iterator
01380 TEMP inline void THIS::DetachIterator(Iterator* pFit) const {
01381   if(mLocked) return;
01382   FD_DC("TBaseSet::DetachIterator(" << this << "):" << pFit)
01383   const_cast< THIS* >(this)->mIterators.erase(pFit);
01384 }
01385 
01386 // test some validity
01387 TEMP void THIS::DValid(const std::string& rMessage) const {
01388   typename std::set< Iterator* >::const_iterator iit;
01389 #ifdef FAUDES_DEBUG_CONTAINER
01390   std::cerr << "TBaseSet(" << this << "):DValid() " << rMessage << " source " 
01391      << pBaseSet << " " << (pBaseSet->pSet==&mEmptySet ? "+e+" : "+f+") << 
01392         (mLocked ? " +l+" : " ") << (mDetached ? " +d+" : " ") << " -- refs ";
01393   typename std::set< THIS* >::const_iterator rit;
01394   for(rit=pBaseSet->mReferences.begin(); rit!=pBaseSet->mReferences.end(); ++rit)
01395     std::cerr << *rit << " ";
01396   std::cerr << "-- its ";
01397   for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit)
01398     std::cerr << *iit << " ";
01399   std::cerr << "-- attr #" << pAttributes->size();
01400   if(mpAttributes) std::cerr << "(" << mpAttributes->size() << ") ";
01401   std::cerr << (pAttributes==&mEmptyAttributes ? "+e+" : "+f+") << std::endl;
01402 #endif
01403   // iterators, that dont refer to me as basset
01404   for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01405     if((*iit)->pBaseSet!=this) {
01406       FD_ERR("THIS("<< this << "," << rMessage <<"): invalid iterator (baseset): "<< *iit);
01407       abort();
01408     }
01409   }
01410   // iterators, that are not marked as attached
01411   for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01412     if(!(*iit)->mAttached) {
01413       FD_ERR("THIS("<< this << "," << rMessage <<"): invalid iterator (attached): "<< *iit);
01414       abort();
01415     }
01416   }
01417   // iterators, that are invalid stl iterators
01418   for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01419     typename std::set<T,Cmp>::const_iterator vit;
01420     for(vit=pSet->begin(); vit!= pSet->end(); ++vit) {
01421       if(vit==(**iit).StlIterator()) break;
01422     }
01423     if(vit!=(**iit).StlIterator()) { // end-iterator is fine, too
01424       FD_ERR("THIS("<< this << "," << rMessage <<"): invalid iterator (stl "<< *iit);
01425       (**iit).StlIterator(pSet->end()); // fix invalid iterator to refer to end()
01426     }
01427   }
01428   // must have some base 
01429   if(pBaseSet==NULL) {
01430     FD_ERR("THIS(" << this << "," << rMessage << "): no base found");
01431     abort();
01432   }
01433   // base must provide data either way
01434   if(pBaseSet->pBaseSet != pBaseSet) {
01435     FD_ERR("THIS(" << this << "," << rMessage << "): no source found");
01436     abort();
01437   }
01438   // refers to other base and own data
01439   if((mpSet!=NULL) && (pBaseSet != this)) {
01440     FD_ERR("THIS(" << this << "," << rMessage << "): double data");
01441     abort();
01442   }
01443   // refers to other base and has references
01444   if(pBaseSet!=this && !mReferences.empty()) {
01445     FD_ERR("THIS(" << this << "," << rMessage << "): cannot have source and refs");
01446     abort();
01447   }
01448   // is base but has no own data
01449   if((pBaseSet == this) && (mpSet==NULL) && (pSet!=&mEmptySet)) {
01450     FD_ERR("THIS(" << this << "," << rMessage << "): no data");
01451     abort();
01452   }
01453   // is base but own data pointer mismatch
01454   if((pBaseSet == this) && (pSet != mpSet) && (pSet!=&mEmptySet)) {
01455     FD_ERR("THIS(" << this << "," << rMessage << "): data pointer mismatch A");
01456     abort();
01457   }
01458   // refers to base with data pointer mismatch
01459   if((pBaseSet != this) && (pSet != pBaseSet->pSet)) {
01460     FD_ERR("THIS(" << this << "," << rMessage << "): data pointer mismatch B");
01461     abort();
01462   }
01463   // error in detached flag
01464   if(mDetached && !pBaseSet->mReferences.empty()) {
01465     FD_ERR("THIS(" << this << "," << rMessage << "): invalid detached flag");
01466     abort();
01467   }
01468   // error in detached flag
01469   if(mDetached && (pSet==&mEmptySet)) {
01470     FD_ERR("THIS(" << this << "," << rMessage << "): detached empty set");
01471     abort();
01472   }
01473   // error in lock flag
01474   if(pBaseSet!=this && mLocked) {
01475     FD_ERR("THIS(" << this << "," << rMessage << "): locked reference");
01476     abort();
01477   }
01478   // invalid emptyset
01479   if(!mEmptySet.empty()) {
01480     FD_ERR("THIS(" << this << "," << rMessage << "): invalid empty set");
01481     abort();
01482   }
01483   // invalid emptyset
01484   if(!mEmptyAttributes.empty()) {
01485     FD_ERR("THIS(" << this << "," << rMessage << "): invalid empty attributes");
01486     abort();
01487   }
01488 }
01489 
01490 
01491 
01492 // Name
01493 TEMP const std::string& THIS::Name(void) const {
01494   return mMyName;
01495 }
01496     
01497 // Name
01498 TEMP void THIS::Name(const std::string& rName) {
01499   mMyName = rName;
01500 }
01501   
01502 // Str
01503 TEMP std::string THIS::Str(const T& rElem) const { 
01504   (void) rElem;
01505   std::string res=""; 
01506   return res; 
01507 }
01508 
01509 // Size()
01510 TEMP Idx THIS::Size(void) const {
01511   return (Idx) pSet->size();
01512 }
01513 
01514 // Empty()
01515 TEMP bool THIS::Empty(void) const {
01516   return pSet->empty();
01517 }
01518 
01519 
01520 // DoWrite(tw,rLabel,cpntext)
01521 TEMP void THIS::DoWrite(TokenWriter& rTw,const std::string& rLabel, const Type* pContext) const {
01522   (void) pContext;
01523   std::string label=rLabel;
01524   if(label=="") label=Name(); 
01525   if(label=="") label="BaseSet"; 
01526   FD_DC("TBaseSet(" << this << ")::DoWrite(..): section " << label << " #" << Size());
01527   rTw.WriteBegin(label);
01528   rTw.WriteEnd(label);
01529 }
01530 
01531 
01532 // DoDWrite(tw, label, context)
01533 TEMP void THIS::DoDWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
01534   (void) pContext;
01535   (void) rLabel;
01536   rTw.WriteComment("");
01537   rTw.WriteComment(" Size/Attributes: " + ToStringInteger(pSet->size()) 
01538         + "/" + ToStringInteger(pBaseSet->pAttributes->size()));
01539   rTw.WriteComment(" Shares/Iterators: " + ToStringInteger(pBaseSet->mReferences.size()) 
01540         + "/" + ToStringInteger(mIterators.size()));
01541   rTw.WriteComment("");
01542 #ifdef FAUDES_DEBUG_CONTAINER
01543   DValid();
01544 #endif
01545 }
01546 
01547 // DoSWrite()
01548 TEMP void THIS::DoSWrite(TokenWriter& rTw) const {
01549   BASE::DoSWrite(rTw);
01550   rTw.WriteComment(" Size: " + ToStringInteger(pSet->size()));
01551   if(!mpSet)
01552     rTw.WriteComment(" Data: shared");
01553   else
01554     rTw.WriteComment(" Data: own");
01555   if(pAttributes->size()!=0)
01556     rTw.WriteComment(" Attributes: " +ToStringInteger(pAttributes->size()));
01557   if(pAttributes->size()!=0) {
01558     AttributeVoid* attr = pAttributes->begin()->second;
01559     rTw.WriteComment(" Attribute Type: " +TypeName(*attr));
01560   } 
01561 }
01562 
01563 // DoRead(rTr, rLabel, pContext)
01564 TEMP void THIS::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
01565   (void) pContext;
01566   std::string label=rLabel;
01567   if(label=="") label=Name(); 
01568   if(label=="") label="BaseSet"; 
01569   Name(label);
01570   rTr.SeekBegin(label); 
01571   rTr.SeekEnd(label); 
01572 }
01573 
01574 // ThisIterator
01575 TEMP typename THIS::Iterator THIS::ThisIterator(const typename std::set<T,Cmp>::const_iterator& sit) const {
01576   return Iterator(this,sit);
01577 }
01578 
01579 // Begin() const
01580 TEMP inline typename THIS::Iterator THIS::Begin(void) const {
01581   return ThisIterator(pSet->begin());
01582 }
01583     
01584 // End() const
01585 TEMP inline typename THIS::Iterator THIS::End(void) const {
01586   return ThisIterator(pSet->end());
01587 }
01588 
01589 
01590 //Clear
01591 TEMP void THIS::Clear(void) {
01592   FD_DC("TBaseSet(" << this << ")::Clear()");
01593 #ifdef FAUDES_DEBUG_CONTAINER
01594   DValid();
01595 #endif
01596   // special case: empty anyway
01597   if(pSet==&mEmptySet) return;
01598   // special case: locked requires a copy (not efficient!)
01599   if(mLocked) Detach();
01600   // make someone else handle the data
01601   if(!mReferences.empty()) RelinkReferences();
01602   // unlink myself from source
01603   if(pBaseSet!=this) {
01604     pBaseSet->DetachReference(this);
01605     pBaseSet=this;
01606   }
01607   // if we hold data, clear it
01608   if(mpSet) {
01609     delete mpSet;
01610     mpSet=NULL;
01611   }
01612   // if we hold data, clear it
01613   if(mpAttributes) {
01614     for(aiterator ait=mpAttributes->begin(); ait!=mpAttributes->end(); ++ait)
01615        delete ait->second;
01616     delete mpAttributes;
01617     mpAttributes=NULL;
01618   }
01619   // set to empty set
01620   pSet=&mEmptySet;
01621   pAttributes=&mEmptyAttributes;
01622   // fix iterators (invalidate)
01623   typename std::set< Iterator* >::iterator iit;
01624   for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
01625     (**iit).Invalidate();
01626   }
01627   mIterators.clear();
01628   mDetached=false;
01629 #ifdef FAUDES_DEBUG_CONTAINER
01630   DValid();
01631 #endif
01632 }
01633 
01634 
01635 //Valid(elem)
01636 TEMP inline bool  THIS::Valid(const T& rElem) const {
01637   (void) rElem;
01638   return true;
01639 }
01640 
01641 //Insert(elem)
01642 TEMP bool THIS::Insert(const T& rElem) {
01643 #ifdef FAUDES_CHECKED
01644   if(!Valid(rElem)) {
01645     std::stringstream errstr;
01646     errstr << "cannot insert invalid element" << std::endl;
01647     throw Exception("THIS::Insert", errstr.str(), 61);
01648   }
01649 #endif
01650   if(!mDetached) Detach();
01651   return pSet->insert(rElem).second;
01652 }
01653 
01654 // InsertSet(set)
01655 TEMP void THIS::InsertSet(const TBaseSet& rOtherSet) {
01656   FD_DC("TBaseSet(" << this << ")::InsertSet(" << &rOtherSet << ")");
01657   if(!mDetached) Detach();
01658   // TODO: test and optimize
01659   iterator it1 = pSet->begin();
01660   iterator it2 = rOtherSet.pSet->begin();
01661   while ((it1 != pSet->end()) && (it2 != rOtherSet.pSet->end())) {
01662     if (*it1 < *it2) {
01663       ++it1;
01664     }
01665     else if (*it1 == *it2) {
01666       ++it1;
01667       ++it2;
01668     }
01669     else { // (*it1 > *it2)
01670       pSet->insert(*it2);
01671       ++it2;
01672     }
01673   }
01674   while (it2 != rOtherSet.pSet->end()) {
01675     pSet->insert(*it2);
01676     ++it2;
01677   }
01678 }
01679     
01680 //Erase(rElem)
01681 TEMP bool THIS::Erase(const T& rElem) {
01682   if(!mDetached) Detach();
01683   return (pSet->erase(rElem)!=0);
01684 }
01685 
01686 
01687 //Erase(pos)
01688 TEMP typename THIS::Iterator THIS::Erase(const Iterator& pos) { 
01689 #ifdef FAUDES_CHECKED
01690   if (pos == End()) {
01691     std::stringstream errstr;
01692     errstr << "iterator out of range " << std::endl;
01693     throw Exception("THIS::Erase", errstr.str(), 62);
01694   }
01695 #endif
01696   Detach();
01697   iterator del= pos.StlIterator(); 
01698   iterator res= del;
01699   res++; 
01700   pSet->erase(del);
01701   return ThisIterator(res); 
01702 }
01703 
01704 
01705 //EraseSet(set)
01706 TEMP void THIS::EraseSet(const TBaseSet& rOtherSet) {
01707   FD_DC("TBaseSet(" << this << ")::EraseSet(" << &rOtherSet << ")");
01708   if(!mDetached) Detach();
01709   // TODO: test and optimize 
01710   iterator tmpit;
01711   iterator it = pSet->begin();
01712   iterator oit = rOtherSet.pSet->begin();
01713   while ((it != pSet->end()) && (oit != rOtherSet.pSet->end())) {
01714     if (*it < *oit) {
01715       it=pSet->lower_bound(*oit); // alt: ++it;
01716     }
01717     else if (*it == *oit) { 
01718       tmpit=it;
01719       ++it;
01720       ++oit;
01721       pSet->erase(tmpit);
01722     }
01723     else { // (*it > *oit)
01724       oit=rOtherSet.pSet->lower_bound(*it); // ++it2;
01725     }
01726   }
01727 }
01728 
01729 
01730 //RestrictSet(set)
01731 TEMP void THIS::RestrictSet(const TBaseSet& rOtherSet) {
01732   FD_DC("TBaseSet(" << this << ")::RestrictSet(" << &rOtherSet << ")");
01733   if(!mDetached) Detach();
01734   // TODO: test and optimize 
01735   iterator tmpit;
01736   iterator it = pSet->begin();
01737   iterator oit = rOtherSet.pSet->begin();
01738   while ((it != pSet->end()) && (oit != rOtherSet.pSet->end())) {
01739     if (*it < *oit) {
01740       tmpit=it;
01741       ++it;
01742       pSet->erase(tmpit);
01743     }
01744     else if (*it == *oit) { 
01745       ++it;
01746       ++oit;
01747     }
01748     else { // (*it > *oit)
01749       oit=rOtherSet.pSet->lower_bound(*it); 
01750     }
01751   }
01752   while(it != pSet->end()) {
01753     tmpit=it;
01754     ++it;
01755     pSet->erase(tmpit);
01756   }
01757 }
01758 
01759 
01760 //Find(elem)
01761 TEMP typename THIS::Iterator THIS::Find(const T& rElem) const {
01762   return ThisIterator(pSet->find(rElem));
01763 }
01764 
01765 //Exists(elem)
01766 TEMP bool  THIS::Exists(const T& rElem) const {
01767   return pSet->find(rElem) != pSet->end();
01768 }
01769 
01770 
01771 // SetUnion(set)
01772 TEMP void THIS::SetUnion(const TBaseSet& rOtherSet) {
01773   if(!mDetached) Detach();
01774   iterator it1 = pSet->begin();
01775   iterator it2 = rOtherSet.pSet->begin();
01776   while ((it1 != pSet->end()) && (it2 != rOtherSet.pSet->end())) {
01777     if (*it1 < *it2) {
01778       ++it1;
01779       continue;
01780     }
01781     if (*it1 == *it2) {
01782       ++it1;
01783       ++it2;
01784       continue;
01785     }
01786     // (*it1 > *it2)
01787     pSet->insert(it1,*it2);
01788     ++it2;
01789   }
01790   while (it2 != rOtherSet.pSet->end()) {
01791     pSet->insert(pSet->end(),*it2);
01792     ++it2;
01793   }
01794 }
01795 
01796 // SetIntersection(set)
01797 TEMP void THIS::SetIntersection(const TBaseSet& rOtherSet) {
01798   if(!mDetached) Detach();
01799   iterator tmpit;
01800   iterator it1 = pSet->begin();
01801   iterator it2 = rOtherSet.pSet->begin();
01802   while ((it1 != pSet->end()) && (it2 != rOtherSet.pSet->end())) {
01803     if (*it1 < *it2) {
01804       tmpit=it1;
01805       ++it1;
01806       pSet->erase(tmpit);
01807       continue;
01808     }
01809     if (*it1 == *it2) {
01810       ++it1;
01811       ++it2;
01812       continue;
01813     }
01814     // if (*it1 > *it2)
01815     ++it2;
01816   }
01817   while(it1 != pSet->end()) {
01818     tmpit=it1;
01819     ++it1;
01820     pSet->erase(tmpit);
01821   }
01822 }
01823 
01824 
01825 // operator+
01826 TEMP THIS THIS::operator+ (const TBaseSet& rOtherSet) const {
01827   FD_DC("TBaseSet(" << this << ")::operator+ (" << &rOtherSet << ")");
01828   TBaseSet res;
01829   res.Detach();
01830   std::insert_iterator< std::set<T,Cmp> > insit(*res.pSet, res.pSet->begin());
01831   std::set_union(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end(), insit);
01832   res.Name(CollapsString(Name() + "+" + rOtherSet.Name()));
01833   return res;
01834 }
01835 
01836 // operator-
01837 TEMP THIS THIS::operator- (const TBaseSet& rOtherSet) const {
01838   FD_DC("TBaseSet(" << this << ")::operator- (" << &rOtherSet << ")");
01839   TBaseSet res;
01840   res.Detach();
01841   std::insert_iterator< std::set<T,Cmp> > insit(*res.pSet, res.pSet->begin());
01842   std::set_difference(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end(), insit);
01843   res.Name(CollapsString(Name() + "-" + rOtherSet.Name()));
01844   return res;
01845 }
01846 
01847      
01848 // operator*
01849 TEMP THIS THIS::operator* (const TBaseSet& rOtherSet) const {
01850   FD_DC("TBaseSet(" << this << ")::operator* (" << &rOtherSet << ")");
01851   TBaseSet res;
01852   res.Detach();
01853   std::insert_iterator< std::set<T,Cmp> > insit(*res.pSet, res.pSet->begin());
01854   std::set_intersection(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end(), insit);
01855   res.Name(CollapsString(Name() + "*" + rOtherSet.Name()));
01856   return res;
01857 }
01858 
01859 
01860 // operator==
01861 TEMP bool THIS::DoEqual(const TBaseSet& rOtherSet) const {
01862   // true if we share anyway
01863   if(pSet == rOtherSet.pSet) return true;
01864   // compare sets
01865   return  ( *pSet == *rOtherSet.pSet );
01866 }
01867 
01868 // operator<=
01869 TEMP bool THIS::operator<= (const TBaseSet& rOtherSet) const {
01870   return ( std::includes(rOtherSet.pSet->begin(), rOtherSet.pSet->end(), pSet->begin(), pSet->end()) ) ;
01871 }
01872 
01873 // operator>=
01874 TEMP bool THIS::operator>= (const TBaseSet& rOtherSet) const {
01875   return ( std::includes(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end()) );
01876 }
01877 
01878 // operator<
01879 TEMP bool THIS::operator< (const TBaseSet& rOtherSet) const {
01880   return *pSet < *rOtherSet.pSet;
01881 }
01882 
01883 
01884 // attribute typeinfo
01885 TEMP const AttributeVoid* THIS::Attributep(void) const { 
01886   static AttributeVoid attr; 
01887   return & attr; 
01888 }
01889 
01890 // attribute typeinfo
01891 TEMP const AttributeVoid& THIS::Attribute(void) const { 
01892   static AttributeVoid attr; 
01893   return attr;
01894 }
01895 
01896 // attribute access
01897 TEMP AttributeVoid* THIS::Attributep(const T& rElem) { 
01898   (void) rElem;
01899   std::stringstream errstr;
01900   errstr << "cannot get attribute for TBaseSet \"" << mMyName  << "\" type " << typeid(*this).name();
01901   throw Exception("TBaseSet::Attributep(rElem)", errstr.str(), 63);  
01902   static AttributeVoid attr; 
01903   return &attr; 
01904 }
01905 
01906 // attribute access
01907 TEMP const AttributeVoid& THIS::Attribute(const T& rElem) const { 
01908   (void) rElem;
01909   static AttributeVoid attr; 
01910   return attr;
01911 }
01912 
01913 // attribute access
01914 TEMP void THIS::Attribute(const T& rElem, const Type& rAttr) {
01915   (void) rElem;
01916   /* its pointless to test existence of the element since we wont set any attribute anyway
01917 #ifdef FAUDES_CHECKED
01918   if (!Exists(rElem)) {
01919     std::stringstream errstr;
01920     errstr << "element not member of set" << std::endl;
01921     throw Exception("TBaseSet::Attribute(elem,attr)", errstr.str(), 60);
01922   }
01923 #endif
01924   */
01925   if(!AttributeTry(rAttr)) {
01926     std::stringstream errstr;
01927     errstr << "cannot cast attribute " << std::endl;
01928     throw Exception("TaBaseSet::Attribute(elem,attr)", errstr.str(), 63);
01929   }
01930   /* alternative approach: 
01931   // silently ignore any value
01932   // set to void is ok for silient ignore
01933   if(typeid(rAttr)==typeid(const AttributeVoid&)) return;
01934   // set to nontrivial attribute: exception
01935   std::stringstream errstr;
01936   errstr << "cannot set attribute type " << typeid(rAttr).name() << " for TBaseSet \"" << mMyName 
01937     << "\" type " << typeid(*this).name();
01938   throw Exception("TBaseSet::Attribute(rElem,rAttr)", errstr.str(), 63);  
01939   */
01940 }
01941 
01942 
01943 
01944 /* undefine local shortcuts */
01945 #undef THIS
01946 #undef TEMP
01947 #undef BASE
01948 
01949 /** @} doxygen group */
01950 
01951 } // namespace faudes
01952 
01953 #endif 

libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6