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