|
libFAUDES
Sections
Index
|
cfl_abaseset.hGo 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 { 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.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3