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