libFAUDES

Sections

Index

cfl_abaseset.h

Go to the documentation of this file.
00001 /** @file cfl_abaseset.h @brief Class TaBaseSet */
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_ABASESET_H
00026 #define FAUDES_ABASESET_H
00027 
00028 #include "cfl_baseset.h"
00029 
00030 namespace faudes {
00031 
00032 /** @addtogroup ContainerClasses */
00033 /** @{*/
00034 
00035 /**
00036  * Set with nontrivial attributes.
00037  *
00038  * The TaBaseSet implements the attribute interface introduced
00039  * in TBaseSet. 
00040  *
00041  * Note: while TaBaseSet is indirectly derived from Type, we avoid the FAUDES_TYPE_DECLARATION
00042  * macro and define the Type interface explicitely. This is for cosmetic reasons only.
00043  *
00044  */
00045 
00046 
00047 template<class T, class Attr, class Cmp=std::less<T> >
00048 class TaBaseSet : virtual public TBaseSet<T,Cmp> {
00049 
00050 
00051 public:
00052 
00053   /**
00054    * Constructor. 
00055    */
00056   TaBaseSet(void);
00057 
00058   /**
00059    * Copy-constructor. 
00060    * Uses DoAssign copy the set incl attributes.
00061    *
00062    * @param rOtherSet 
00063    *    Source to copy from
00064    */
00065   TaBaseSet(const TaBaseSet& rOtherSet);
00066 
00067   /**
00068    * Copy-constructor. Sets attributes to default.
00069    * Uses the DoAssign method to convert attributes if possible.
00070    *
00071    * @param rOtherSet 
00072    *    Source to copy from
00073    */
00074   TaBaseSet(const TBaseSet<T,Cmp>& rOtherSet);
00075 
00076   /**
00077    * Constructor from file.
00078    * This constructor indicates the intended interface for derived classes. The base set 
00079    * itself cannot read from token streams.
00080    *
00081    * @param rFilename
00082    *   Name of File
00083    * @param rLabel
00084    *   Section for the set in the file; 
00085    */
00086   TaBaseSet(const std::string& rFilename, const std::string& rLabel = "BaseSet");
00087 
00088   /**
00089    * Virtual destructor
00090    */
00091   virtual ~TaBaseSet(void);
00092 
00093   /**
00094    * Faudes Type interface. Construct object of same type on heap.
00095    */
00096   virtual TaBaseSet* New(void) const 
00097     { return new TaBaseSet(); };
00098 
00099   /**
00100    * Faudes Type interface. Construct copy on heap.
00101    */
00102   virtual TaBaseSet* Copy(void) const 
00103     { return new TaBaseSet(*this); };
00104 
00105   /**
00106    * Faudes Type interface. Cast object to my type.
00107    */
00108   //virtual const TaBaseSet* Cast(const Type* pType) const 
00109   virtual const Type* Cast(const Type* pType) const 
00110     { return dynamic_cast<const TaBaseSet*>(pType); };
00111 
00112   /**
00113    * Copy from a TaBaseSet with matching attributes.
00114    *
00115    * @param rSourceSet 
00116    *    Set to copy from
00117    */
00118   virtual TaBaseSet& Assign(const TaBaseSet& rSourceSet);
00119 
00120   /**
00121    * Copy from a TBaseSet with attributes, provided that they
00122    * can be casted acciordingly.
00123    *
00124    * @param rSourceSet 
00125    *    Set to copy from
00126    */
00127   virtual TaBaseSet& Assign(const TBaseSet<T,Cmp>& rSourceSet);
00128 
00129   /**
00130    * Copy from a TBaseSet without attributes. This method
00131    * clears all attributes even if they cound be casted.
00132    *
00133    * @param rSourceSet 
00134    *    Set to copy from
00135    */
00136   virtual TaBaseSet& AssignWithoutAttributes(const TBaseSet<T,Cmp>& rSourceSet);
00137 
00138   /**
00139    * Faudes Type interface. Assignment operator with strict type matching. 
00140    * @param rSource 
00141    *    Object to assign from
00142    */
00143   virtual TaBaseSet& operator=(const TaBaseSet& rSource) { DoAssign(rSource);return *this; };
00144 
00145   /**
00146    * Faudes Type interface (extension). Assignment operator incl attribute cast.
00147    * @param rSource 
00148    *    Object to assign from
00149    */
00150   virtual TaBaseSet& operator=(const TBaseSet<T,Cmp>& rSource) { return Assign(rSource); }
00151 
00152   /** 
00153    * Clear all set.
00154    */
00155   virtual void Clear(void);
00156       
00157   /**
00158    * Attribute typeinfo.
00159    *
00160    * @return
00161    *    Pointer to some attribute of this sets attribute type.
00162    */
00163   const Attr* Attributep(void) const;
00164 
00165   /**
00166    * Attribute typeinfo
00167    *
00168    * @return
00169    *    Reference to some attribute of this sets attribute type
00170    */
00171   const Attr& Attribute(void) const;
00172 
00173   /** 
00174    * Attribute typeinfo.
00175    * An TaBaseSet accepts all attributes that we can cast to our default attribute's type.
00176    * The implementation uses the virtual function Cast of the default attribute to perform
00177    * the test. Thus, it is crucial that Cast is re-implemented for attribute classes.
00178    * @param rAttr
00179    *     Attribute type to test.
00180    * @return True, if attribute type is accepted.
00181    */
00182   virtual bool AttributeTry(const Type& rAttr) const;
00183 
00184   /**
00185    * Get number of explicit (aka non-default) attributes.
00186    *
00187    * @return 
00188    *   Number of entries in mAttributeMap
00189    */
00190   virtual Idx AttributesSize(void) const ;
00191 
00192   /** 
00193    * Clear all attributes to default value.
00194    *
00195    */
00196   virtual void ClearAttributes(void);
00197 
00198   /**
00199    * Test whether attributes match with other set,
00200    * Return true if attributes match for shared elements. It uses
00201    * the equality test of individual attributes and, hence, requires the type
00202    * match too.
00203    * @param rOtherSet 
00204    *    Other set to compare with.
00205    * @return 
00206    *   True on match.
00207    */
00208   virtual bool EqualAttributes(const TBaseSet<T,Cmp>& rOtherSet) const;
00209 
00210   /**
00211    * Test set equality.
00212    * The test ignores attributes. It is implemented by the virtual method DoEqual().
00213    * @param rOtherSet 
00214    *    Other set to compare with.
00215    * @return 
00216    *   True on match.
00217    */
00218   virtual bool operator==(const TBaseSet<T,Cmp>& rOtherSet) const;
00219 
00220   /**
00221    * Test whether attributes match with other set,
00222    * Return true if attributes match for shared elements. It uses
00223    * the equality test of individual attributes and, hence, requires the type
00224    * match too.
00225    * @param rOtherSet 
00226    *    Other set to compare with.
00227    * @return 
00228    *   True on match.
00229    */
00230   virtual bool EqualAttributes(const TaBaseSet& rOtherSet) const;
00231 
00232   /** 
00233    * Get attribute reference by element. Note that in order to produce a non-const 
00234    * reference this method will insert an explicit default attribute if necessary. 
00235    * If a const reference is sufficient, you should use Attribute(rElem) const instead.
00236    *
00237    * @param rElem
00238    *    Specify element
00239    * @exception Exception
00240    *   - Element does not exist (60)
00241    * @return 
00242    *    Pointer to attribute
00243    */
00244   virtual Attr* Attributep(const T& rElem);
00245 
00246   /** 
00247    * Get attribute by element. This function returns a const reference to the attribute
00248    * of the specified element. 
00249    * @param rElem
00250    *    Specify element
00251    * @exception Exception
00252    *   - Element does not exist (63)
00253    * @return 
00254    *    Reference to attribute
00255    */
00256   virtual const Attr& Attribute(const T& rElem) const;
00257 
00258   /** 
00259    * Set attribute. Provided that the attribute can be casted to the
00260    * appropriate type, this method sets the attribute of the sepcified element to the given value. 
00261    *
00262    * @param rElem
00263    *    Specify element
00264    * @param attr
00265    *    Attribute value.
00266    * @exception Exception
00267    *   - Element does not exist (60)
00268    *   - Cannot cast attribute type (63)
00269    */
00270   virtual void Attribute(const T& rElem, const Type& attr);
00271 
00272   /** 
00273    * Set attribute. This method sets the attribute of the sepcified element to the given value. 
00274    *
00275    * @param rElem
00276    *    Specify element
00277    * @param attr
00278    *    Attribute value.
00279    * @exception Exception
00280    *   - Element does not exist (60)
00281    *   - Cannot cast attribute type (63)
00282    */
00283   virtual void Attribute(const T& rElem, const Attr& attr);
00284 
00285   /** 
00286    * Set attribute. Provided that the attribute can be casted to the
00287    * appropriate type, this method sets the attribute of the sepcified element to the given value. 
00288    * If the cast fails, this method does nothing.
00289    *
00290    * @param rElem
00291    *    Specify element
00292    * @param attr
00293    *    Attribute value.
00294    * @exception Exception
00295    *   - Element does not exist (60)
00296    */
00297   virtual void AttributeTry(const T& rElem, const Type& attr);
00298 
00299   /**
00300    * Set attributes. Provided that rOtherSet has attributes that can be
00301    * casted to the appropriate type, attributes are copied per element from rOtherSet. 
00302    * Elements of this set which are not in rOtherSet maintain their attribute. 
00303    *
00304    * @param rOtherSet
00305    *   Other BaseSet
00306    * @exception Exception
00307    *   - Cannot cast attribute type (63)
00308    */
00309   virtual void Attributes(const TBaseSet<T,Cmp>& rOtherSet);
00310 
00311   /**
00312    * Set attributes. Attributes are copied per element from rOtherSet. 
00313    * Elements of this set which are not in rOtherSet maintain their attribute. 
00314    *
00315    * @param rOtherSet
00316    *   Other BaseSet
00317    */
00318   virtual void Attributes(const TaBaseSet& rOtherSet);
00319 
00320   /** 
00321    * Clear attribute to default value. 
00322    *
00323    * @param rElem
00324    *    Specify element
00325    */
00326   virtual void ClrAttribute(const T& rElem);
00327 
00328   /** 
00329    * Use TBaseSet iterators. 
00330    */
00331   typedef typename TBaseSet<T,Cmp>::Iterator Iterator;
00332 
00333   /**
00334    * Insert element. If the element exists, the attribute is maintained.
00335    * If the element does not exist, it is inserted with default attribute.
00336    *
00337    * @param rElem
00338    *   Specify element
00339    * @return
00340    *   True if element was new to set 
00341    */
00342   bool Insert(const T& rElem);
00343 
00344   /** 
00345    * Insert element with attribute. 
00346    *
00347    * @param rElem
00348    *   Specify element
00349    * @param attr
00350    *   Specify attribute of (new) element
00351    * @return
00352    *   True if element was new to set 
00353    */
00354   bool Insert(const T& rElem, const Attr& attr);
00355 
00356   /**
00357    * Inserts elements of rOtherSet.
00358    * Attributes of this set are maintained, newly inserted elements have default attribute.
00359    *
00360    *
00361    * @param rOtherSet
00362    *   Other BaseSet
00363    */
00364   void InsertSet(const TBaseSet<T,Cmp>& rOtherSet);
00365 
00366   /**
00367    * Inserts elements of rOtherSet.
00368    * Attributes of this set are maintained, new elements are inserted with attribute.
00369    *
00370    * @param rOtherSet
00371    *   Other BaseSet
00372    */
00373    void InsertSet(const TaBaseSet& rOtherSet);
00374 
00375 
00376   /** 
00377    * Erase Element (incl its attribute) 
00378    *
00379    * @param rElem
00380    *    Specify element
00381    * @return
00382    *    True if element used to exist
00383    */
00384   bool Erase(const T& rElem);
00385 
00386   /** 
00387    * Erase element by iterator (incl attribute) 
00388    *
00389    * @param pos
00390    *    Iterator to specify element
00391    * @return 
00392    *    Iterator to next element or End()
00393    */
00394   Iterator Erase(const Iterator& pos); 
00395 
00396 
00397   /** 
00398    * Erase elements given by other set. This function
00399    * ignores the attributes of the other set and maintains the attributes 
00400    * of the remaining elements in this set.
00401    *
00402    * @param rOtherSet 
00403    *    Elements to erase
00404    */
00405   void EraseSet(const TBaseSet<T,Cmp>& rOtherSet);
00406 
00407   /** 
00408    * Restrict to specified subset. Erases any elements no in
00409    * the specified set. This function
00410    * ignores the attributes of the other set and maintains the attributes 
00411    * of the remaining elements in this set.
00412    *
00413    * @param rOtherSet 
00414    *    Elements to erase
00415    */
00416    void RestrictSet(const TBaseSet<T,Cmp>& rOtherSet);
00417 
00418 
00419   /**
00420    * Set union. The union is wrt the set of indices, the result is accumulated in this set.
00421    * Attributes are set to default. See also InsertSet(const TaBaseSet&).
00422    *
00423    * @param rOtherSet
00424    *   Other BaseSet
00425    */
00426   void SetUnion(const TBaseSet<T,Cmp>& rOtherSet);
00427 
00428   /**
00429    * Set intersection. The intersection is  wrt set of indices, the result is stored in this set.
00430    * Attributes are set to default.
00431    * 
00432    * @param rOtherSet
00433    *   Other BaseSet
00434    */
00435   void SetIntersection(const TBaseSet<T,Cmp>& rOtherSet);
00436 
00437 
00438   /** Detach from extern storage (reimplement base) */
00439   virtual void Detach(void) const;
00440 
00441  protected:
00442 
00443   /** use TBaseSet STL iterators */
00444   typedef typename TBaseSet<T,Cmp>::iterator iterator;
00445 
00446   /** use TBaseSet STL iterators */
00447   typedef typename TBaseSet<T,Cmp>::const_iterator const_iterator;
00448 
00449   /** use TBaseSet STL iterators */
00450   typedef typename TBaseSet<T,Cmp>::aiterator aiterator;
00451 
00452   /** use TBaseSet STL iterators */
00453   typedef typename TBaseSet<T,Cmp>::const_aiterator const_aiterator;
00454 
00455 
00456   /** default attribute */ 
00457   Attr* mpDefAttribute; 
00458   
00459   /** assignment from source with matching attributes */
00460   virtual void DoAssign(const TaBaseSet& rSourceSet);
00461 
00462   /** test equality, ignore attributes */
00463   virtual bool DoEqual(const TBaseSet<T,Cmp>& rOtherSet) const;
00464 
00465   /** set attribute in map (assume elem exists in set, NULL <=> set to default) */
00466   virtual void DoAttributep(const T& rElem, const Type* pAttr);
00467 
00468   /** set attribute in map (assume elem exists in set, NULL <=> set to default) */
00469   virtual void DoAttributep(const T& rElem, const Attr* pAttr);
00470 
00471   /** get attribute from map (return null if elem does not exist in map) */
00472   virtual const Attr* DoAttributep(const T& rElem) const;
00473 
00474   /** get attribute from map (insert explicit default if elem does not exist in map) */
00475   virtual Attr* DoAttributep(const T& rElem);
00476 
00477 
00478 };
00479 
00480 
00481 
00482 /** @} doxygen group */
00483 
00484 
00485 
00486 /*
00487 ******************************************************************************************
00488 ******************************************************************************************
00489 ******************************************************************************************
00490 
00491 Implementation of TaBaseSet
00492 
00493 ******************************************************************************************
00494 ******************************************************************************************
00495 ******************************************************************************************
00496 */
00497 
00498 /* convenience access to relevant scopes */
00499 #define THIS TaBaseSet<T,Attr,Cmp> 
00500 #define TEMP template<class T, class Attr, class Cmp>
00501 #define BASE TBaseSet<T,Cmp> 
00502 
00503 // TaBaseSet()
00504 TEMP THIS::TaBaseSet(void) :
00505   BASE(),
00506   mpDefAttribute(new Attr())
00507 {
00508   FD_DC("TaBaseSet(" << this << ")::TaBaseSet()");
00509 }
00510 
00511   
00512 // TaBaseSet(rOtherSet)
00513 TEMP THIS::TaBaseSet(const TaBaseSet& rOtherSet) : 
00514   BASE(),
00515   mpDefAttribute(new Attr())
00516 {
00517   FD_DC("TaBaseSet(" << this << ")::TaBaseSet(TaBaseSet " << &rOtherSet << "): copy construct");
00518   DoAssign(rOtherSet);
00519 }
00520 
00521 // TaBaseSet(rOtherSet)
00522 TEMP THIS::TaBaseSet(const TBaseSet<T,Cmp>& rOtherSet) : 
00523   BASE(NULL),
00524   mpDefAttribute(new Attr())
00525 {
00526   FD_DC("TaBaseSet(" << this << ")::TaBaseSet(TBaseSet " << &rOtherSet << "): copy construct");
00527   Assign(rOtherSet);
00528 }
00529 
00530 // TaBaseSet(filename)
00531 TEMP THIS::TaBaseSet(const std::string& rFileName, const std::string& rLabel)  :
00532   BASE(),
00533   mpDefAttribute(new Attr())
00534 {
00535   FD_DC("TaBaseSet(" << this << ")::TaBaseSet()");
00536   // do read etc ... this is a dummy anyway
00537   BASE::Read(rFileName,rLabel);  
00538 }
00539 
00540 // destructor
00541 TEMP THIS::~TaBaseSet(void) {
00542   FD_DC("TaBaseSet(" << this << ")::~TaBaseSet()");
00543   // free my members
00544   if(mpDefAttribute) delete mpDefAttribute;
00545   // note: attributes will be deleted in BASE after relink
00546 }
00547 
00548 
00549 // copy, matching attributes
00550 TEMP void THIS::DoAssign(const TaBaseSet& rSourceSet) {
00551   FD_DC("TaBaseSet(" << this << ")::DoAssign(TaBaseSet " << &rSourceSet << ")");
00552   // bail out on selfref
00553   if(this==&rSourceSet) return;
00554   // become independant
00555   BASE::RelinkReferences();
00556   BASE::pBaseSet->DetachReference(this);
00557   BASE::mReferences.clear();
00558   // delete own attributes 
00559   if(BASE::mpAttributes) {
00560     for(aiterator ait=BASE::mpAttributes->begin(); ait!=BASE::mpAttributes->end(); ++ait)
00561       delete ait->second;
00562   }
00563   // call base (fake copy, sets to empty attributes)
00564   BASE::DoAssign(rSourceSet);
00565   // link to shared attributes
00566   BASE::pAttributes=rSourceSet.pAttributes;
00567 }  
00568 
00569 
00570 
00571 // public wrapper
00572 TEMP THIS& THIS::Assign(const TaBaseSet<T,Attr,Cmp>& rSourceSet) {
00573   DoAssign(rSourceSet);
00574   return *this;
00575 }
00576 
00577 // assign, try attributes
00578 TEMP THIS& THIS::Assign(const TBaseSet<T,Cmp>& rSourceSet) {
00579   FD_DC("TaBaseSet(" << this << ")::Assign(..)");
00580   FD_DC("TaBaseSet(" << this << ")::Assign(..): dst type " << typeid(*this).name());
00581   FD_DC("TaBaseSet(" << this << ")::Assign(..): src type " << typeid(rSourceSet).name());
00582   // clear incl attributes, attached empty set.
00583   Clear();
00584   Detach();
00585   // call base (fake copy, results in effectively empty attributes)
00586   BASE::DoAssign(rSourceSet);
00587   // detach, since we dont want to share mixed attributes
00588   Detach();
00589   // if there are no attributes, we dont worry
00590   if(rSourceSet.AttributesSize()==0) return *this;
00591   // if we have void attributes, we cannot cast (TODO: known at compiletime!)
00592   FD_DC("TaBaseSet(" << this << ")::Assign(..): dst attribute type " << typeid(*mpDefAttribute).name());
00593   if( typeid(*mpDefAttribute) == typeid(AttributeVoid) ) return  *this;
00594   // if source has void attributes, we cannot cast
00595   FD_DC("TaBaseSet(" << this << ")::Assign(..): src attribute type " << typeid(*rSourceSet.Attributep()).name());
00596   if( typeid(*rSourceSet.Attributep()) == typeid(const AttributeVoid) ) return  *this;
00597   // if attributes cannot be casted, we dont need to loop either
00598   FD_DC("TaBaseSet(" << this << ")::Assign(..): try attribute cast");
00599   if(!mpDefAttribute->Cast(rSourceSet.Attributep())) return  *this;
00600   // try to be smart on attributes 
00601   BASE::mpAttributes= new std::map<T,AttributeVoid*>();
00602   BASE::pAttributes=BASE::mpAttributes;
00603   FD_DC("TaBaseSet(" << this << ")::Assign(..): mind attributes");
00604   const_aiterator ait=rSourceSet.pAttributes->begin();
00605   for(;ait!=rSourceSet.pAttributes->end(); ++ait) {
00606     Attr* attr= new Attr;
00607     attr->Assign(*ait->second);
00608     (*BASE::pAttributes)[ait->first]=attr;
00609   }
00610   // done
00611   FD_DC("TaBaseSet(" << this << ")::Assign(..): done");
00612   return *this;
00613 }
00614 
00615 
00616 
00617 // public wrapper
00618 TEMP THIS& THIS::AssignWithoutAttributes(const TBaseSet<T,Cmp>& rSourceSet) {
00619   // clear incl attributes and detach
00620   Clear();
00621   // call base (fake copy, results in effectively empty attributes)
00622   BASE::DoAssign(rSourceSet);
00623   // detach, since we dont want to share mixed attributes
00624   Detach();
00625   // done
00626   return *this;
00627 }
00628 
00629 // test equality, ignore attributes 
00630 TEMP bool THIS::DoEqual(const TBaseSet<T,Cmp>& rOtherSet) const {
00631   FD_DC("TaBaseSet::DoEqual()");
00632   // require set elements to match
00633   if(!BASE::DoEqual(rOtherSet)) 
00634     return false;
00635   // ok, equal
00636   return true;
00637   /*
00638   For reference: version that requires attributes either to match or 
00639   to be of default value
00640 
00641   // true, if we share attubute data
00642   FD_DC("TaBaseSet::DoEqual(TBaseSet): 2");
00643   if(BASE::pAttributes==rOtherSet.pAttributes)
00644     return true;
00645   // true, if there are no attributes
00646   FD_DC("TaBaseSet::EqualAttributes(TBaseSet): 3");
00647   if(rOtherSet.AttributesSize()==0)
00648   if(this->AttributesSize()==0)
00649     return true;
00650   // iterate over attributes
00651   aiterator ait1 = BASE::pAttributes->begin();
00652   aiterator ait2 = rOtherSet.pAttributes->begin();
00653   while ((ait1 != BASE::pAttributes->end()) && (ait2 != rOtherSet.pAttributes->end())) {
00654     if (ait1->first < ait2->first) {
00655       ++ait1;
00656     }
00657     else if (ait1->first == ait2->first) {
00658       FD_DC("TaBaseSet::EqualAttributes(TBaseSet): cmp " << ait1->second->ToString() 
00659         << " vs " << ait2->second->ToString());
00660       if( (!ait1->second->IsDefault()) || (!ait2->second->IsDefault()))  
00661         if( ! ait1->second->Equal(*ait2->second)) return false;
00662       ++ait1;
00663       ++ait2;
00664     }
00665     else { // (*it1 > *it2)
00666       ++ait2;
00667     }
00668   }
00669   // passed
00670   FD_DC("TaBaseSet::EqualAttributes(TBaseSet): pass");
00671   return true;
00672   */
00673 }
00674 
00675 // operator version of DoEQual
00676 TEMP bool THIS::operator==(const TBaseSet<T,Cmp>& rOtherSet) const {
00677   return DoEqual(rOtherSet);
00678 }
00679 
00680 // Detach()
00681 TEMP void THIS::Detach(void) const {
00682   FD_DC("TaBaseSet(" << this << ")::Detach(void)");
00683 
00684   // nothing todo
00685   if(BASE::mDetached) return;
00686 
00687   // provide fake const
00688   THIS* fake_const = const_cast< THIS* >(this);
00689 
00690   // do allocation and copy of attributes, 
00691   std::map<T,AttributeVoid*>* acopy = new std::map<T,AttributeVoid*>();
00692   for(aiterator ait=BASE::pAttributes->begin(); ait!=BASE::pAttributes->end(); ++ait) {
00693     Attr* attr= new Attr();
00694     attr->Assign(*ait->second);
00695     (*acopy)[ait->first]=attr;
00696   }
00697 
00698   // call base for core set
00699   BASE::Detach();
00700  
00701   // stragie A or B: others got the origianal attributes, i take the copy
00702   fake_const->mpAttributes=acopy;
00703   fake_const->pAttributes=acopy;
00704 
00705 }
00706 
00707 
00708 //Clear
00709 TEMP void THIS::Clear(void) {
00710   FD_DC("TaBaseSet(" << this << ")::Clear()");
00711   // call base (incl streamlined pseudo detach and empty attributes)
00712   BASE::Clear();
00713 }
00714 
00715 
00716 //Insert(elem)
00717 TEMP bool THIS::Insert(const T& rElem) {
00718   FD_DC("TvIndexSet(" << this << ")::Insert(elem)");
00719   bool ret=BASE::Insert(rElem);
00720   return ret;
00721 }
00722 
00723 //Insert(idx,attr)
00724 TEMP bool THIS::Insert(const T& rElem, const Attr& rAttr) {
00725   FD_DC("TaIndexSet(" << this << ")::Insert(elem,attr)");
00726   Detach();
00727   bool ret=BASE::pSet->insert(rElem).second;
00728   DoAttributep(rElem,&rAttr);
00729   return ret;
00730 }
00731 
00732 // InsertSet(set)
00733 TEMP void THIS::InsertSet(const TBaseSet<T,Cmp>& rOtherSet) {
00734   bool doattr=AttributeTry(rOtherSet.Attribute()); 
00735   FD_DC("TaBaseSet(" << this << ")::InsertSet( [v] " << &rOtherSet << "): doattr=" << doattr);
00736   Detach();
00737   iterator it1 = BASE::pSet->begin();
00738   iterator it2 = rOtherSet.pSet->begin();
00739   while ((it1 != BASE::pSet->end()) && (it2 != rOtherSet.pSet->end())) {
00740     if (*it1 < *it2) {
00741       ++it1;
00742     }
00743     else if (*it1 == *it2) {
00744       ++it1;
00745       ++it2;
00746     }
00747     else { // (*it1 > *it2)
00748       Insert(*it2);
00749       if(doattr) DoAttributep(*it2,&rOtherSet.Attribute(*it2));
00750       ++it2;
00751     }
00752   }
00753   while (it2 != rOtherSet.pSet->end()) {
00754     Insert(*it2);
00755     if(doattr) DoAttributep(*it2,&rOtherSet.Attribute(*it2));
00756     ++it2;
00757   }
00758 }
00759 
00760 // InsertSet(set)
00761 TEMP void THIS::InsertSet(const TaBaseSet& rOtherSet) {
00762   FD_DC("TaBaseSet(" << this << ")::InsertSet( [a] " << &rOtherSet << ")");
00763   Detach();
00764   iterator it1 = BASE::pSet->begin();
00765   iterator it2 = rOtherSet.pSet->begin();
00766   while ((it1 != BASE::pSet->end()) && (it2 != rOtherSet.pSet->end())) {
00767     if (*it1 < *it2) {
00768       ++it1;
00769     }
00770     else if (*it1 == *it2) {
00771       ++it1;
00772       ++it2;
00773     }
00774     else { // (*it1 > *it2)
00775       Insert(*it2,rOtherSet.Attribute(*it2));
00776       ++it2;
00777     }
00778   }
00779   while (it2 != rOtherSet.pSet->end()) {
00780     Insert(*it2,rOtherSet.Attribute(*it2));
00781     ++it2;
00782   }
00783 }
00784 
00785 
00786 //Erase(idx)
00787 TEMP bool THIS::Erase(const T& rElem) {
00788   Detach();
00789   DoAttributep(rElem,(const Attr*) 0);
00790   return (BASE::pSet->erase(rElem)!=0);
00791 }
00792 
00793 
00794 //Erase(pos)
00795 TEMP typename THIS::Iterator THIS::Erase(const Iterator& pos) { 
00796 #ifdef FAUDES_CHECKED
00797   if(pos == BASE::End()) {
00798     std::stringstream errstr;
00799     errstr << "iterator out of range " << std::endl;
00800     throw Exception("TaBase::Erase", errstr.str(), 60);
00801   }
00802 #endif
00803   ClrAttribute(*pos);
00804   return BASE::Erase(pos);
00805 }
00806 
00807 
00808 //EraseSet(set)
00809 TEMP void THIS::EraseSet(const TBaseSet<T,Cmp>& rOtherSet) {
00810   FD_DC("TaBaseSet(" << this << ")::EraseSet(" << rOtherSet.ToString() << ")");
00811   Detach();
00812   // todo: test and optimize 
00813   iterator tmpit;
00814   iterator it = BASE::pSet->begin();
00815   iterator oit = rOtherSet.pSet->begin();
00816   while ((it != BASE::pSet->end()) && (oit != rOtherSet.pSet->end())) {
00817     if (*it < *oit) {
00818       it=BASE::pSet->lower_bound(*oit); // alt: ++it;
00819     }
00820     else if (*it == *oit) { 
00821       DoAttributep(*it,(const Attr*) 0);
00822       tmpit=it;
00823       ++it;
00824       ++oit;
00825       BASE::pSet->erase(tmpit);
00826     }
00827     else { // (*it > *oit)
00828       oit=rOtherSet.pSet->lower_bound(*it); // ++it2;
00829     }
00830   }
00831 }
00832 
00833 
00834 //RestrictSet(set)
00835 TEMP void THIS::RestrictSet(const TBaseSet<T,Cmp>& rOtherSet) {
00836   FD_DC("TaIndexSet(" << this << ")::RestrictSet(" << rOtherSet.ToString() << ")");
00837   Detach();
00838   // todo: test and optimize 
00839   iterator tmpit;
00840   iterator it = BASE::pSet->begin();
00841   iterator oit = rOtherSet.pSet->begin();
00842   while ((it != BASE::pSet->end()) && (oit != rOtherSet.pSet->end())) {
00843     if (*it < *oit) {
00844       DoAttributep(*it,(const Attr*) 0);
00845       tmpit=it;
00846       ++it;
00847       BASE::pSet->erase(tmpit);
00848     }
00849     else if (*it == *oit) { 
00850       ++it;
00851       ++oit;
00852     }
00853     else { // (*it > *oit)
00854       ++oit;
00855     }
00856   }
00857   while(it != BASE::pSet->end()) {
00858     DoAttributep(*it,(const Attr*) 0);
00859     tmpit=it;
00860     ++it;
00861     BASE::pSet->erase(tmpit);
00862   }
00863 
00864 }
00865 
00866 
00867 // SetUnion(set)
00868  TEMP void THIS::SetUnion(const TBaseSet<T,Cmp>& rOtherSet) {
00869   BASE::SetUnion(rOtherSet);
00870   ClearAttributes();
00871 }
00872 
00873 // SetUnion(set)
00874 TEMP void THIS::SetIntersection(const TBaseSet<T,Cmp>& rOtherSet) {
00875   BASE::SetIntersection(rOtherSet);
00876   ClearAttributes();
00877 }
00878 
00879 
00880 // attribute typeinfo
00881 TEMP const Attr* THIS::Attributep(void) const { 
00882   return mpDefAttribute; 
00883 }
00884 
00885 // attribute typeinfo
00886 TEMP const Attr& THIS::Attribute(void) const { 
00887   return *mpDefAttribute;
00888 }
00889 
00890 // test attribute type
00891 TEMP bool THIS::AttributeTry(const Type& rAttr) const {
00892   return mpDefAttribute->Cast(&rAttr)!=NULL;
00893 }
00894 
00895 
00896 // get attribute wrapper
00897 TEMP Attr* THIS::Attributep(const T& rElem) {
00898 #ifdef FAUDES_CHECKED
00899   if(!Exists(rElem)) {
00900     std::stringstream errstr;
00901     errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
00902     throw Exception("TaBaseSet::Attributep(elem)", errstr.str(), 60);
00903   }
00904 #endif
00905   // must detach
00906   Detach();
00907   // find in map (incl insert explicit default)
00908   Attr* res=DoAttributep(rElem);
00909   // done
00910   return res;
00911 }
00912 
00913 // get attribute wrapper
00914 TEMP const Attr& THIS::Attribute(const T& rElem) const {
00915 #ifdef FAUDES_CHECKED
00916   if(!Exists(rElem)) {
00917     std::stringstream errstr;
00918     errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
00919     throw Exception("TaBaseSet::Attribute(elem)", errstr.str(), 60);
00920   }
00921 #endif
00922   // find in map
00923   const Attr* res=DoAttributep(rElem);
00924   // use default
00925   if(!res) res=mpDefAttribute;
00926   // done
00927   return *res;
00928 }
00929 
00930 // set attribute wrapper
00931 TEMP void THIS::Attribute(const T& rElem, const Type& attr) {
00932 #ifdef FAUDES_CHECKED
00933   if (!Exists(rElem)) {
00934     std::stringstream errstr;
00935     errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
00936     throw Exception("TaBaseSet::Attribute(elem,attr)", errstr.str(), 60);
00937   }
00938 #endif
00939   if(!AttributeTry(attr)) {
00940     std::stringstream errstr;
00941     errstr << "cannot cast attribute " << std::endl;
00942     throw Exception("TaBaseSet::Attribute(elem,attr)", errstr.str(), 63);
00943   }
00944   Detach();
00945   DoAttributep(rElem, dynamic_cast<const Attr*>(&attr)); 
00946 }
00947 
00948 // set attribute wrapper
00949 TEMP void THIS::AttributeTry(const T& rElem, const Type& attr) {
00950   if(!AttributeTry(attr)) return;
00951 #ifdef FAUDES_CHECKED
00952   if (!Exists(rElem)) {
00953     std::stringstream errstr;
00954     errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
00955     throw Exception("TaBaseSet::Attribute(elem)", errstr.str(), 60);
00956   }
00957 #endif
00958   Detach();
00959   DoAttributep(rElem, dynamic_cast<const Attr*>(&attr)); 
00960 }
00961 
00962 // set attribute wrapper
00963 TEMP void THIS::Attribute(const T& rElem, const Attr& attr) {
00964 #ifdef FAUDES_CHECKED
00965   if (!Exists(rElem)) {
00966     std::stringstream errstr;
00967     errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
00968     throw Exception("TaBaseSet::Attribute(elem)", errstr.str(), 60);
00969   }
00970 #endif
00971   Detach();
00972   DoAttributep(rElem, &attr); 
00973 }
00974 
00975 
00976 // set attribute wrapper
00977 TEMP void THIS::Attributes(const TBaseSet<T,Cmp>& rOtherSet) {
00978   if(!AttributeTry(rOtherSet.Attribute())) {
00979     std::stringstream errstr;
00980     errstr << "cannot cast attribute " << std::endl;
00981     throw Exception("TaBaseSet::Attribute(elem,attr)", errstr.str(), 63);
00982   }
00983   Detach();
00984   iterator it1 = BASE::pSet->begin();
00985   iterator it2 = rOtherSet.pSet->begin();
00986   while ((it1 != BASE::pSet->end()) && (it2 != rOtherSet.pSet->end())) {
00987     if (*it1 < *it2) {
00988       ++it1;
00989     }
00990     else if (*it1 == *it2) {
00991       DoAttributep(*it1,&rOtherSet.Attribute(*it2)); 
00992       ++it1;
00993       ++it2;
00994     }
00995     else { // (*it1 > *it2)
00996       ++it2;
00997     }
00998   }
00999 }
01000 
01001 // set attribute wrapper
01002 TEMP void THIS::Attributes(const TaBaseSet& rOtherSet) {
01003   Detach();
01004   iterator it1 = BASE::pSet->begin();
01005   iterator it2 = rOtherSet.pSet->begin();
01006   while ((it1 != BASE::pSet->end()) && (it2 != rOtherSet.pSet->end())) {
01007     if (*it1 < *it2) {
01008       ++it1;
01009     }
01010     else if (*it1 == *it2) {
01011       DoAttributep(*it1,&rOtherSet.Attribute(*it2)); 
01012       ++it1;
01013       ++it2;
01014     }
01015     else { // (*it1 > *it2)
01016       ++it2;
01017     }
01018   }
01019 }
01020 
01021 // clr attributes wrapper  
01022 TEMP void THIS::ClrAttribute(const T& rElem) {
01023   Detach();
01024   DoAttributep(rElem,(const Attr*) 0);
01025 }
01026 
01027 // Implement attributes: clear
01028 TEMP void THIS::ClearAttributes(void) {
01029   // bail out if there are no attributes anyway
01030   if(BASE::pAttributes->size()==0) return;
01031   // detach (incl empty attributes if used to share)
01032   BASE::Detach();
01033   // clear if we (still) own attributes FIXME ...DOUBLE CHECK
01034   if(BASE::mpAttributes) {
01035     aiterator ait=BASE::mpAttributes->begin();
01036     for(;ait!=BASE::mpAttributes->end();++ait)
01037       delete ait->second;
01038     BASE::mpAttributes->clear();
01039   }
01040 }
01041 
01042 // Implement attributes: equality
01043 TEMP bool THIS::EqualAttributes(const TBaseSet<T,Cmp>& rOtherSet) const {
01044   FD_DC("TaBaseSet::EqualAttributes(TBaseSet)");
01045   // true, if we share attubute data
01046   FD_DC("TaBaseSet::EqualAttributes(TBaseSet): 1");
01047   if(BASE::pAttributes==rOtherSet.pAttributes)
01048     return true;
01049   // false, if type does not match
01050   FD_DC("TaBaseSet::EqualAttributes(TBaseSet): 2");
01051   if(typeid(*rOtherSet.Attributep())!=typeid(*this->Attributep())) 
01052     return false;
01053   // true if there are no attributes
01054   FD_DC("TaBaseSet::EqualAttributes(TBaseSet): 3");
01055   if(rOtherSet.AttributesSize()==0)
01056   if(this->AttributesSize()==0)
01057     return true;
01058   // figure shared elements
01059   aiterator ait1 = BASE::pAttributes->begin();
01060   aiterator ait2 = rOtherSet.pAttributes->begin();
01061   while ((ait1 != BASE::pAttributes->end()) && (ait2 != rOtherSet.pAttributes->end())) {
01062     if (ait1->first < ait2->first) {
01063       ++ait1;
01064     }
01065     else if (ait1->first == ait2->first) {
01066       FD_DC("TaBaseSet::EqualAttributes(TBaseSet): cmp " << ait1->second->ToString() 
01067         << " vs " << ait2->second->ToString());
01068       if( ! ait1->second->Equal(*ait2->second)) return false;
01069       ++ait1;
01070       ++ait2;
01071     }
01072     else { // (*it1 > *it2)
01073       ++ait2;
01074     }
01075   }
01076   // passed
01077   FD_DC("TaBaseSet::EqualAttributes(TBaseSet): pass");
01078   return true;
01079 }
01080 
01081 // Implement attributes: equality
01082 TEMP bool THIS::EqualAttributes(const TaBaseSet& rOtherSet) const {
01083   FD_DC("TaBaseSet::EqualAttributes(TaBaseSet)");
01084   // true, if we share attubute data
01085   if(BASE::pAttributes==rOtherSet.pAttributes)
01086     return true;
01087   // true if there are no attributes
01088   if(rOtherSet.AttributesSize()==0)
01089   if(this->AttributesSize()==0)
01090     return true;
01091   // figure shared elements
01092   aiterator ait1 = BASE::pAttributes->begin();
01093   aiterator ait2 = rOtherSet.pAttributes->begin();
01094   while ((ait1 != BASE::pAttributes->end()) && (ait2 != rOtherSet.pAttributes->end())) {
01095     if (ait1->first < ait2->first) {
01096       ++ait1;
01097     }
01098     else if (ait1->first == ait2->first) {
01099       if( *(static_cast<const Attr*>(ait1->second)) != 
01100     *(static_cast<const Attr*>(ait2->second)) ) return false;
01101       ++ait1;
01102       ++ait2;
01103     }
01104     else { // (*it1 > *it2)
01105       ++ait2;
01106     }
01107   }
01108   // passed
01109   return true;
01110 }
01111 
01112 // Implement attributes: get pointer
01113 TEMP const Attr* THIS::DoAttributep(const T& rElem) const {
01114   const_aiterator ait;
01115   ait=BASE::pAttributes->find(rElem);
01116   if( ait==BASE::pAttributes->end() ) return NULL;
01117   return static_cast<const Attr*>(ait->second);
01118 } 
01119 
01120 // Implement attributes: get pointer (must detach)
01121 TEMP Attr* THIS::DoAttributep(const T& rElem) {
01122   FD_DC("TaBaseSet::DoAttributep(Elem)");
01123 #ifdef FAUDES_DEBUG_CODE
01124   if(BASE::pAttributes!=BASE::mpAttributes) {
01125     FD_ERR("TaBaseSet::DoAttributep(Elem): attributes not detached");
01126     abort();
01127   }
01128 #endif
01129   aiterator ait;
01130   ait=BASE::pAttributes->find(rElem);
01131   // explicit default
01132   if( ait==BASE::pAttributes->end() ) {
01133     Attr* attr = new Attr();
01134     attr->Assign(*mpDefAttribute);
01135     (*BASE::pAttributes)[rElem]=attr;
01136     return attr;
01137   }
01138   return static_cast<Attr*>(ait->second);
01139 } 
01140 
01141 // Implement attributes: set  (must detach)
01142 TEMP void THIS::DoAttributep(const T& rElem, const Type* pAttr) {
01143   FD_DC("TaBaseSet::DoAttributep([v] " << this->Str(rElem) << ", ...)");
01144 #ifdef FAUDES_DEBUG_CODE
01145   if(BASE::pAttributes!=BASE::mpAttributes) {
01146     FD_ERR("TaBaseSet::DoAttributep([v] set): attributes not detached");
01147     abort();
01148   }
01149 #endif
01150   // find element in map  
01151   aiterator ait;
01152   AttributeVoid* oldattr=NULL;
01153   const AttributeVoid* newattr=dynamic_cast<const AttributeVoid*>(pAttr);
01154   ait=BASE::pAttributes->find(rElem);
01155   if(ait!=BASE::pAttributes->end() ) 
01156     oldattr=ait->second;
01157   // set to default, case 1
01158   if(newattr==NULL) {
01159     FD_DC("TaBaseSet::DoAttributep([v] " << this->Str(rElem) << ", ...): default 1");
01160     if(oldattr==NULL) return;
01161     delete oldattr;
01162     BASE::pAttributes->erase(ait);
01163     return;
01164   }  
01165   // set to default, case b
01166   if(newattr->IsDefault()) {
01167     FD_DC("TaBaseSet::DoAttributep([v] " << this->Str(rElem) << ", ...): default 2");
01168     if(oldattr==NULL) return;
01169     delete oldattr;
01170     BASE::pAttributes->erase(ait);
01171     return;
01172   }  
01173   FD_DC("TaBaseSet::DoAttributep([v] " << this->Str(rElem) << ", ...): " << newattr->ToString());
01174   // prepare attribute and set
01175   if(oldattr==NULL) {
01176     Attr* attr = new Attr();
01177     attr->Assign(*newattr);
01178     (*BASE::pAttributes)[rElem]=attr;
01179     return;
01180   }
01181   // plain set     
01182   oldattr->Assign(*pAttr);
01183 }
01184 
01185 // Implement attributes: set (must detach)
01186 TEMP void THIS::DoAttributep(const T& rElem, const Attr* pAttr) {
01187   FD_DC("TaBaseSet::DoAttributep([a] " << this->Str(rElem) << ", ...)");
01188 #ifdef FAUDES_DEBUG_CODE
01189   if(BASE::pAttributes!=BASE::mpAttributes) {
01190     FD_ERR("TaBaseSet::DoAttributep([a] set): attributes not detached");
01191     abort();
01192   }
01193 #endif
01194   // find element in map  
01195   aiterator ait;
01196   AttributeVoid* oldattr=NULL;
01197   ait=BASE::pAttributes->find(rElem);
01198   if(ait!=BASE::pAttributes->end() ) 
01199     oldattr=ait->second;
01200   // set to default, case a
01201   if(pAttr==NULL) {
01202     if(oldattr==NULL) return;
01203     delete oldattr;
01204     BASE::pAttributes->erase(ait);
01205     return;
01206   }  
01207   // set to default, case b
01208   if(pAttr->IsDefault()) {
01209     if(oldattr==NULL) return;
01210     delete oldattr;
01211     BASE::pAttributes->erase(ait);
01212     return;
01213   }  
01214   // prepare attribute and set
01215   if(oldattr==NULL) {
01216     Attr* attr = new Attr();
01217     *attr=*pAttr;
01218     (*BASE::pAttributes)[rElem]=attr;
01219     return;
01220   }
01221   // plain set     
01222   *static_cast<Attr*>(oldattr)=*pAttr;
01223 }
01224 
01225 // Implement attributes
01226 TEMP Idx THIS::AttributesSize(void) const {
01227   return BASE::pAttributes->size();
01228 }
01229 
01230 /* undefine local shortcuts */
01231 #undef THIS
01232 #undef TEMP
01233 #undef BASE
01234 
01235 
01236 } // namespace faudes
01237 
01238 #endif 

libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3