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 y
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(!THIS::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(!THIS::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 (!THIS::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 (!THIS::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 (!THIS::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.23h --- 2014.04.03 --- c++ api documentaion by doxygen