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