libFAUDES

Sections

Index

abaseset.h

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

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