About
User Reference
C++ API
luafaudes
Developer
Links
libFAUDES online
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(),
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   // call base (fake copy, sets to empty attributes)
00555   BASE::DoAssign(rSourceSet);
00556   // link to shared attributes
00557   BASE::pAttributes=rSourceSet.pAttributes;
00558 }  
00559 
00560 
00561 
00562 // public wrapper
00563 TEMP THIS& THIS::Assign(const TaBaseSet<T,Attr,Cmp>& rSourceSet) {
00564   DoAssign(rSourceSet);
00565   return *this;
00566 }
00567 
00568 // assign, try attributes
00569 TEMP THIS& THIS::Assign(const TBaseSet<T,Cmp>& rSourceSet) {
00570   FD_DC("TaBaseSet(" << this << ")::Assign(..)");
00571   FD_DC("TaBaseSet(" << this << ")::Assign(..): dst type " << typeid(*this).name());
00572   FD_DC("TaBaseSet(" << this << ")::Assign(..): src type " << typeid(rSourceSet).name());
00573   // call base (fake copy, results in effectively empty attributes)
00574   BASE::DoAssign(rSourceSet);
00575   // detach, since we dont want to share mixed attributes
00576   Detach();
00577   // if there are no attributes, we dont worry
00578   if(rSourceSet.AttributesSize()==0) return *this;
00579   // if we have void attributes, we cannot cast (TODO: known at compiletime!)
00580   FD_DC("TaBaseSet(" << this << ")::Assign(..): dst attribute type " << typeid(*mpDefAttribute).name());
00581   if( typeid(*mpDefAttribute) == typeid(AttributeVoid) ) return  *this;
00582   // if source has void attributes, we cannot cast
00583   FD_DC("TaBaseSet(" << this << ")::Assign(..): src attribute type " << typeid(*rSourceSet.Attributep()).name());
00584   if( typeid(*rSourceSet.Attributep()) == typeid(const AttributeVoid) ) return  *this;
00585   // if attributes cannot be casted, we dont need to loop either
00586   FD_DC("TaBaseSet(" << this << ")::Assign(..): try attribute cast");
00587   if(!mpDefAttribute->Cast(rSourceSet.Attributep())) return  *this;
00588   // try to be smart on attributes 
00589   BASE::mpAttributes= new std::map<T,AttributeVoid*>();
00590   BASE::pAttributes=BASE::mpAttributes;
00591   FD_DC("TaBaseSet(" << this << ")::Assign(..): mind attributes");
00592   const_aiterator ait=rSourceSet.pAttributes->begin();
00593   for(;ait!=rSourceSet.pAttributes->end(); ++ait) {
00594     Attr* attr= new Attr;
00595     attr->Assign(*ait->second);
00596     (*BASE::pAttributes)[ait->first]=attr;
00597   }
00598   // done
00599   FD_DC("TaBaseSet(" << this << ")::Assign(..): done");
00600   return *this;
00601 }
00602 
00603 
00604 
00605 // public wrapper
00606 TEMP THIS& THIS::AssignWithoutAttributes(const TBaseSet<T,Cmp>& rSourceSet) {
00607   // call base (fake copy, results in effectively empty attributes)
00608   BASE::DoAssign(rSourceSet);
00609   // detach, since we dont want to share mixed attributes
00610   Detach();
00611   // done
00612   return *this;
00613 }
00614 
00615 // test equality, ignore attributes 
00616 TEMP bool THIS::DoEqual(const TBaseSet<T,Cmp>& rOtherSet) const {
00617   FD_DC("TaBaseSet::DoEqual()");
00618   // require set elements to match
00619   if(!BASE::DoEqual(rOtherSet)) 
00620     return false;
00621   // ok, equal
00622   return true;
00623   /*
00624   For reference: version that requires attributes either to match or 
00625   to be of default value
00626 
00627   // true, if we share attubute data
00628   FD_DC("TaBaseSet::DoEqual(TBaseSet): 2");
00629   if(BASE::pAttributes==rOtherSet.pAttributes)
00630     return true;
00631   // true, if there are no attributes
00632   FD_DC("TaBaseSet::EqualAttributes(TBaseSet): 3");
00633   if(rOtherSet.AttributesSize()==0)
00634   if(this->AttributesSize()==0)
00635     return true;
00636   // iterate over attributes
00637   aiterator ait1 = BASE::pAttributes->begin();
00638   aiterator ait2 = rOtherSet.pAttributes->begin();
00639   while ((ait1 != BASE::pAttributes->end()) && (ait2 != rOtherSet.pAttributes->end())) {
00640     if (ait1->first < ait2->first) {
00641       ++ait1;
00642     }
00643     else if (ait1->first == ait2->first) {
00644       FD_DC("TaBaseSet::EqualAttributes(TBaseSet): cmp " << ait1->second->ToString() 
00645         << " vs " << ait2->second->ToString());
00646       if( (!ait1->second->IsDefault()) || (!ait2->second->IsDefault()))  
00647         if( ! ait1->second->Equal(*ait2->second)) return false;
00648       ++ait1;
00649       ++ait2;
00650     }
00651     else { // (*it1 > *it2)
00652       ++ait2;
00653     }
00654   }
00655   // passed
00656   FD_DC("TaBaseSet::EqualAttributes(TBaseSet): pass");
00657   return true;
00658   */
00659 }
00660 
00661 // operator version of DoEQual
00662 TEMP bool THIS::operator==(const TBaseSet<T,Cmp>& rOtherSet) const {
00663   return DoEqual(rOtherSet);
00664 }
00665 
00666 // Detach()
00667 TEMP void THIS::Detach(void) const {
00668   FD_DC("TaBaseSet(" << this << ")::Detach(void)");
00669 
00670   // nothing todo
00671   if(BASE::mDetached) return;
00672 
00673   // provide fake const
00674   THIS* fake_const = const_cast< THIS* >(this);
00675 
00676   // do allocation and copy of attributes, 
00677   std::map<T,AttributeVoid*>* acopy = new std::map<T,AttributeVoid*>();
00678   for(aiterator ait=BASE::pAttributes->begin(); ait!=BASE::pAttributes->end(); ++ait) {
00679     Attr* attr= new Attr();
00680     attr->Assign(*ait->second);
00681     (*acopy)[ait->first]=attr;
00682   }
00683 
00684   // call base for core set, effectively empty attributes
00685   BASE::Detach();
00686  
00687   // stragie A or B: others got the origianal attributes, i take the copy
00688   fake_const->mpAttributes=acopy;
00689   fake_const->pAttributes=acopy;
00690 
00691 }
00692 
00693 
00694 //Clear
00695 TEMP void THIS::Clear(void) {
00696   FD_DC("TaBaseSet(" << this << ")::Clear()");
00697   // call base (incl streamlined pseudo detach and empty attributes)
00698   BASE::Clear();
00699 }
00700 
00701 
00702 //Insert(elem)
00703 TEMP bool THIS::Insert(const T& rElem) {
00704   FD_DC("TvIndexSet(" << this << ")::Insert(elem)");
00705   bool ret=BASE::Insert(rElem);
00706   return ret;
00707 }
00708 
00709 //Insert(idx,attr)
00710 TEMP bool THIS::Insert(const T& rElem, const Attr& rAttr) {
00711   FD_DC("TaIndexSet(" << this << ")::Insert(elem,attr)");
00712   Detach();
00713   bool ret=BASE::pSet->insert(rElem).second;
00714   DoAttributep(rElem,&rAttr);
00715   return ret;
00716 }
00717 
00718 // InsertSet(set)
00719 TEMP void THIS::InsertSet(const TBaseSet<T,Cmp>& rOtherSet) {
00720   bool doattr=AttributeTry(rOtherSet.Attribute()); 
00721   FD_DC("TaBaseSet(" << this << ")::InsertSet( [v] " << &rOtherSet << "): doattr=" << doattr);
00722   Detach();
00723   iterator it1 = BASE::pSet->begin();
00724   iterator it2 = rOtherSet.pSet->begin();
00725   while ((it1 != BASE::pSet->end()) && (it2 != rOtherSet.pSet->end())) {
00726     if (*it1 < *it2) {
00727       ++it1;
00728     }
00729     else if (*it1 == *it2) {
00730       ++it1;
00731       ++it2;
00732     }
00733     else { // (*it1 > *it2)
00734       Insert(*it2);
00735       if(doattr) DoAttributep(*it2,&rOtherSet.Attribute(*it2));
00736       ++it2;
00737     }
00738   }
00739   while (it2 != rOtherSet.pSet->end()) {
00740     Insert(*it2);
00741     if(doattr) DoAttributep(*it2,&rOtherSet.Attribute(*it2));
00742     ++it2;
00743   }
00744 }
00745 
00746 // InsertSet(set)
00747 TEMP void THIS::InsertSet(const TaBaseSet& rOtherSet) {
00748   FD_DC("TaBaseSet(" << this << ")::InsertSet( [a] " << &rOtherSet << ")");
00749   Detach();
00750   iterator it1 = BASE::pSet->begin();
00751   iterator it2 = rOtherSet.pSet->begin();
00752   while ((it1 != BASE::pSet->end()) && (it2 != rOtherSet.pSet->end())) {
00753     if (*it1 < *it2) {
00754       ++it1;
00755     }
00756     else if (*it1 == *it2) {
00757       ++it1;
00758       ++it2;
00759     }
00760     else { // (*it1 > *it2)
00761       Insert(*it2,rOtherSet.Attribute(*it2));
00762       ++it2;
00763     }
00764   }
00765   while (it2 != rOtherSet.pSet->end()) {
00766     Insert(*it2,rOtherSet.Attribute(*it2));
00767     ++it2;
00768   }
00769 }
00770 
00771 
00772 //Erase(idx)
00773 TEMP bool THIS::Erase(const T& rElem) {
00774   Detach();
00775   DoAttributep(rElem,(const Attr*) 0);
00776   return (BASE::pSet->erase(rElem)!=0);
00777 }
00778 
00779 
00780 //Erase(pos)
00781 TEMP typename THIS::Iterator THIS::Erase(const Iterator& pos) { 
00782 #ifdef FAUDES_CHECKED
00783   if(pos == BASE::End()) {
00784     std::stringstream errstr;
00785     errstr << "iterator out of range " << std::endl;
00786     throw Exception("TaBase::Erase", errstr.str(), 60);
00787   }
00788 #endif
00789   ClrAttribute(*pos);
00790   return BASE::Erase(pos);
00791 }
00792 
00793 
00794 //EraseSet(set)
00795 TEMP void THIS::EraseSet(const TBaseSet<T,Cmp>& rOtherSet) {
00796   FD_DC("TaBaseSet(" << this << ")::EraseSet(" << rOtherSet.ToString() << ")");
00797   Detach();
00798   // todo: test and optimize 
00799   iterator tmpit;
00800   iterator it = BASE::pSet->begin();
00801   iterator oit = rOtherSet.pSet->begin();
00802   while ((it != BASE::pSet->end()) && (oit != rOtherSet.pSet->end())) {
00803     if (*it < *oit) {
00804       it=BASE::pSet->lower_bound(*oit); // alt: ++it;
00805     }
00806     else if (*it == *oit) { 
00807       DoAttributep(*it,(const Attr*) 0);
00808       tmpit=it;
00809       ++it;
00810       ++oit;
00811       BASE::pSet->erase(tmpit);
00812     }
00813     else { // (*it > *oit)
00814       oit=rOtherSet.pSet->lower_bound(*it); // ++it2;
00815     }
00816   }
00817 }
00818 
00819 
00820 //RestrictSet(set)
00821 TEMP void THIS::RestrictSet(const TBaseSet<T,Cmp>& rOtherSet) {
00822   FD_DC("TaIndexSet(" << this << ")::RestrictSet(" << rOtherSet.ToString() << ")");
00823   Detach();
00824   // todo: test and optimize 
00825   iterator tmpit;
00826   iterator it = BASE::pSet->begin();
00827   iterator oit = rOtherSet.pSet->begin();
00828   while ((it != BASE::pSet->end()) && (oit != rOtherSet.pSet->end())) {
00829     if (*it < *oit) {
00830       DoAttributep(*it,(const Attr*) 0);
00831       tmpit=it;
00832       ++it;
00833       BASE::pSet->erase(tmpit);
00834     }
00835     else if (*it == *oit) { 
00836       ++it;
00837       ++oit;
00838     }
00839     else { // (*it > *oit)
00840       ++oit;
00841     }
00842   }
00843   while(it != BASE::pSet->end()) {
00844     DoAttributep(*it,(const Attr*) 0);
00845     tmpit=it;
00846     ++it;
00847     BASE::pSet->erase(tmpit);
00848   }
00849 
00850 }
00851 
00852 
00853 // SetUnion(set)
00854  TEMP void THIS::SetUnion(const TBaseSet<T,Cmp>& rOtherSet) {
00855   BASE::SetUnion(rOtherSet);
00856   ClearAttributes();
00857 }
00858 
00859 // SetUnion(set)
00860 TEMP void THIS::SetIntersection(const TBaseSet<T,Cmp>& rOtherSet) {
00861   BASE::SetIntersection(rOtherSet);
00862   ClearAttributes();
00863 }
00864 
00865 
00866 // attribute typeinfo
00867 TEMP const Attr* THIS::Attributep(void) const { 
00868   return mpDefAttribute; 
00869 }
00870 
00871 // attribute typeinfo
00872 TEMP const Attr& THIS::Attribute(void) const { 
00873   return *mpDefAttribute;
00874 }
00875 
00876 // test attribute type
00877 TEMP bool THIS::AttributeTry(const Type& rAttr) const {
00878   return mpDefAttribute->Cast(&rAttr)!=NULL;
00879 }
00880 
00881 
00882 // get attribute wrapper
00883 TEMP Attr* THIS::Attributep(const T& rElem) {
00884 #ifdef FAUDES_CHECKED
00885   if(!Exists(rElem)) {
00886     std::stringstream errstr;
00887     errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
00888     throw Exception("TaBaseSet::Attributep(elem)", errstr.str(), 60);
00889   }
00890 #endif
00891   // must detach
00892   Detach();
00893   // find in map (incl insert explicit default)
00894   Attr* res=DoAttributep(rElem);
00895   // done
00896   return res;
00897 }
00898 
00899 // get attribute wrapper
00900 TEMP const Attr& THIS::Attribute(const T& rElem) const {
00901 #ifdef FAUDES_CHECKED
00902   if(!Exists(rElem)) {
00903     std::stringstream errstr;
00904     errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
00905     throw Exception("TaBaseSet::Attribute(elem)", errstr.str(), 60);
00906   }
00907 #endif
00908   // find in map
00909   const Attr* res=DoAttributep(rElem);
00910   // use default
00911   if(!res) res=mpDefAttribute;
00912   // done
00913   return *res;
00914 }
00915 
00916 // set attribute wrapper
00917 TEMP void THIS::Attribute(const T& rElem, const Type& attr) {
00918 #ifdef FAUDES_CHECKED
00919   if (!Exists(rElem)) {
00920     std::stringstream errstr;
00921     errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
00922     throw Exception("TaBaseSet::Attribute(elem,attr)", errstr.str(), 60);
00923   }
00924 #endif
00925   if(!AttributeTry(attr)) {
00926     std::stringstream errstr;
00927     errstr << "cannot cast attribute " << std::endl;
00928     throw Exception("TaBaseSet::Attribute(elem,attr)", errstr.str(), 63);
00929   }
00930   Detach();
00931   DoAttributep(rElem, dynamic_cast<const Attr*>(&attr)); 
00932 }
00933 
00934 // set attribute wrapper
00935 TEMP void THIS::AttributeTry(const T& rElem, const Type& attr) {
00936   if(!AttributeTry(attr)) return;
00937 #ifdef FAUDES_CHECKED
00938   if (!Exists(rElem)) {
00939     std::stringstream errstr;
00940     errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
00941     throw Exception("TaBaseSet::Attribute(elem)", errstr.str(), 60);
00942   }
00943 #endif
00944   Detach();
00945   DoAttributep(rElem, dynamic_cast<const Attr*>(&attr)); 
00946 }
00947 
00948 // set attribute wrapper
00949 TEMP void THIS::Attribute(const T& rElem, const Attr& attr) {
00950 #ifdef FAUDES_CHECKED
00951   if (!Exists(rElem)) {
00952     std::stringstream errstr;
00953     errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
00954     throw Exception("TaBaseSet::Attribute(elem)", errstr.str(), 60);
00955   }
00956 #endif
00957   Detach();
00958   DoAttributep(rElem, &attr); 
00959 }
00960 
00961 
00962 // set attribute wrapper
00963 TEMP void THIS::Attributes(const TBaseSet<T,Cmp>& rOtherSet) {
00964   if(!AttributeTry(rOtherSet.Attribute())) {
00965     std::stringstream errstr;
00966     errstr << "cannot cast attribute " << std::endl;
00967     throw Exception("TaBaseSet::Attribute(elem,attr)", errstr.str(), 63);
00968   }
00969   Detach();
00970   iterator it1 = BASE::pSet->begin();
00971   iterator it2 = rOtherSet.pSet->begin();
00972   while ((it1 != BASE::pSet->end()) && (it2 != rOtherSet.pSet->end())) {
00973     if (*it1 < *it2) {
00974       ++it1;
00975     }
00976     else if (*it1 == *it2) {
00977       DoAttributep(*it1,&rOtherSet.Attribute(*it2)); 
00978       ++it1;
00979       ++it2;
00980     }
00981     else { // (*it1 > *it2)
00982       ++it2;
00983     }
00984   }
00985 }
00986 
00987 // set attribute wrapper
00988 TEMP void THIS::Attributes(const TaBaseSet& rOtherSet) {
00989   Detach();
00990   iterator it1 = BASE::pSet->begin();
00991   iterator it2 = rOtherSet.pSet->begin();
00992   while ((it1 != BASE::pSet->end()) && (it2 != rOtherSet.pSet->end())) {
00993     if (*it1 < *it2) {
00994       ++it1;
00995     }
00996     else if (*it1 == *it2) {
00997       DoAttributep(*it1,&rOtherSet.Attribute(*it2)); 
00998       ++it1;
00999       ++it2;
01000     }
01001     else { // (*it1 > *it2)
01002       ++it2;
01003     }
01004   }
01005 }
01006 
01007 // clr attributes wrapper  
01008 TEMP void THIS::ClrAttribute(const T& rElem) {
01009   Detach();
01010   DoAttributep(rElem,(const Attr*) 0);
01011 }
01012 
01013 // Implement attributes: clear
01014 TEMP void THIS::ClearAttributes(void) {
01015   // bail out if there are no attributes anyway
01016   if(BASE::pAttributes->size()==0) return;
01017   // detach (incl empty attributes if used to share)
01018   BASE::Detach();
01019   // clear if we (still) own attributes FIXME ...DOUBLE CHECK
01020   if(BASE::mpAttributes) {
01021     aiterator ait=BASE::mpAttributes->begin();
01022     for(;ait!=BASE::mpAttributes->end();++ait)
01023       delete ait->second;
01024     BASE::mpAttributes->clear();
01025   }
01026 }
01027 
01028 // Implement attributes: equality
01029 TEMP bool THIS::EqualAttributes(const TBaseSet<T,Cmp>& rOtherSet) const {
01030   FD_DC("TaBaseSet::EqualAttributes(TBaseSet)");
01031   // true, if we share attubute data
01032   FD_DC("TaBaseSet::EqualAttributes(TBaseSet): 1");
01033   if(BASE::pAttributes==rOtherSet.pAttributes)
01034     return true;
01035   // false, if type does not match
01036   FD_DC("TaBaseSet::EqualAttributes(TBaseSet): 2");
01037   if(typeid(*rOtherSet.Attributep())!=typeid(*this->Attributep())) 
01038     return false;
01039   // true if there are no attributes
01040   FD_DC("TaBaseSet::EqualAttributes(TBaseSet): 3");
01041   if(rOtherSet.AttributesSize()==0)
01042   if(this->AttributesSize()==0)
01043     return true;
01044   // figure shared elements
01045   aiterator ait1 = BASE::pAttributes->begin();
01046   aiterator ait2 = rOtherSet.pAttributes->begin();
01047   while ((ait1 != BASE::pAttributes->end()) && (ait2 != rOtherSet.pAttributes->end())) {
01048     if (ait1->first < ait2->first) {
01049       ++ait1;
01050     }
01051     else if (ait1->first == ait2->first) {
01052       FD_DC("TaBaseSet::EqualAttributes(TBaseSet): cmp " << ait1->second->ToString() 
01053         << " vs " << ait2->second->ToString());
01054       if( ! ait1->second->Equal(*ait2->second)) return false;
01055       ++ait1;
01056       ++ait2;
01057     }
01058     else { // (*it1 > *it2)
01059       ++ait2;
01060     }
01061   }
01062   // passed
01063   FD_DC("TaBaseSet::EqualAttributes(TBaseSet): pass");
01064   return true;
01065 }
01066 
01067 // Implement attributes: equality
01068 TEMP bool THIS::EqualAttributes(const TaBaseSet& rOtherSet) const {
01069   FD_DC("TaBaseSet::EqualAttributes(TaBaseSet)");
01070   // true, if we share attubute data
01071   if(BASE::pAttributes==rOtherSet.pAttributes)
01072     return true;
01073   // true if there are no attributes
01074   if(rOtherSet.AttributesSize()==0)
01075   if(this->AttributesSize()==0)
01076     return true;
01077   // figure shared elements
01078   aiterator ait1 = BASE::pAttributes->begin();
01079   aiterator ait2 = rOtherSet.pAttributes->begin();
01080   while ((ait1 != BASE::pAttributes->end()) && (ait2 != rOtherSet.pAttributes->end())) {
01081     if (ait1->first < ait2->first) {
01082       ++ait1;
01083     }
01084     else if (ait1->first == ait2->first) {
01085       if( *(static_cast<const Attr*>(ait1->second)) != 
01086     *(static_cast<const Attr*>(ait2->second)) ) return false;
01087       ++ait1;
01088       ++ait2;
01089     }
01090     else { // (*it1 > *it2)
01091       ++ait2;
01092     }
01093   }
01094   // passed
01095   return true;
01096 }
01097 
01098 // Implement attributes: get pointer
01099 TEMP const Attr* THIS::DoAttributep(const T& rElem) const {
01100   const_aiterator ait;
01101   ait=BASE::pAttributes->find(rElem);
01102   if(ait==BASE::pAttributes->end()) return NULL;
01103   return static_cast<const Attr*>(ait->second);
01104 } 
01105 
01106 // Implement attributes: get pointer (must detach)
01107 TEMP Attr* THIS::DoAttributep(const T& rElem) {
01108   FD_DC("TaBaseSet::DoAttributep(Elem)");
01109 #ifdef FAUDES_DEBUG_CODE
01110   if(BASE::pAttributes!=BASE::mpAttributes) {
01111     FD_ERR("TaBaseSet::DoAttributep(Elem): attributes not detached");
01112     abort();
01113   }
01114 #endif
01115   aiterator ait;
01116   ait=BASE::pAttributes->find(rElem);
01117   // explicit default
01118   if( ait==BASE::pAttributes->end() ) {
01119     Attr* attr = new Attr();
01120     attr->Assign(*mpDefAttribute);
01121     (*BASE::pAttributes)[rElem]=attr;
01122     return attr;
01123   }
01124   return static_cast<Attr*>(ait->second);
01125 } 
01126 
01127 // Implement attributes: set  (must detach)
01128 TEMP void THIS::DoAttributep(const T& rElem, const Type* pAttr) {
01129   FD_DC("TaBaseSet::DoAttributep([v] " << this->Str(rElem) << ", ...)");
01130 #ifdef FAUDES_DEBUG_CODE
01131   if(BASE::pAttributes!=BASE::mpAttributes) {
01132     FD_ERR("TaBaseSet::DoAttributep([v] set): attributes not detached");
01133     abort();
01134   }
01135 #endif
01136   // find element in map  
01137   aiterator ait;
01138   AttributeVoid* oldattr=NULL;
01139   const AttributeVoid* newattr=dynamic_cast<const AttributeVoid*>(pAttr);
01140   ait=BASE::pAttributes->find(rElem);
01141   if(ait!=BASE::pAttributes->end() ) 
01142     oldattr=ait->second;
01143   // set to default, case 1
01144   if(newattr==NULL) {
01145     FD_DC("TaBaseSet::DoAttributep([v] " << this->Str(rElem) << ", ...): default 1");
01146     if(oldattr==NULL) return;
01147     delete oldattr;
01148     BASE::pAttributes->erase(ait);
01149     return;
01150   }  
01151   // set to default, case b
01152   if(newattr->IsDefault()) {
01153     FD_DC("TaBaseSet::DoAttributep([v] " << this->Str(rElem) << ", ...): default 2");
01154     if(oldattr==NULL) return;
01155     delete oldattr;
01156     BASE::pAttributes->erase(ait);
01157     return;
01158   }  
01159   FD_DC("TaBaseSet::DoAttributep([v] " << this->Str(rElem) << ", ...): " << newattr->ToString());
01160   // prepare attribute and set
01161   if(oldattr==NULL) {
01162     Attr* attr = new Attr();
01163     attr->Assign(*newattr);
01164     (*BASE::pAttributes)[rElem]=attr;
01165     return;
01166   }
01167   // plain set     
01168   oldattr->Assign(*pAttr);
01169 }
01170 
01171 // Implement attributes: set (must detach)
01172 TEMP void THIS::DoAttributep(const T& rElem, const Attr* pAttr) {
01173   FD_DC("TaBaseSet::DoAttributep([a] " << this->Str(rElem) << ", ...)");
01174 #ifdef FAUDES_DEBUG_CODE
01175   if(BASE::pAttributes!=BASE::mpAttributes) {
01176     FD_ERR("TaBaseSet::DoAttributep([a] set): attributes not detached");
01177     abort();
01178   }
01179 #endif
01180   // find element in map  
01181   aiterator ait;
01182   AttributeVoid* oldattr=NULL;
01183   ait=BASE::pAttributes->find(rElem);
01184   if(ait!=BASE::pAttributes->end() ) 
01185     oldattr=ait->second;
01186   // set to default, case a
01187   if(pAttr==NULL) {
01188     if(oldattr==NULL) return;
01189     delete oldattr;
01190     BASE::pAttributes->erase(ait);
01191     return;
01192   }  
01193   // set to default, case b
01194   if(pAttr->IsDefault()) {
01195     if(oldattr==NULL) return;
01196     delete oldattr;
01197     BASE::pAttributes->erase(ait);
01198     return;
01199   }  
01200   // prepare attribute and set
01201   if(oldattr==NULL) {
01202     Attr* attr = new Attr();
01203     *attr=*pAttr;
01204     (*BASE::pAttributes)[rElem]=attr;
01205     return;
01206   }
01207   // plain set     
01208   *static_cast<Attr*>(oldattr)=*pAttr;
01209 }
01210 
01211 // Implement attributes
01212 TEMP Idx THIS::AttributesSize(void) const {
01213   return BASE::pAttributes->size();
01214 }
01215 
01216 /* undefine local shortcuts */
01217 #undef THIS
01218 #undef TEMP
01219 #undef BASE
01220 
01221 
01222 } // namespace faudes
01223 
01224 #endif 

libFAUDES 2.20s --- 2011.10.12 --- c++ source docu by doxygen