cfl_abaseset.h
Go to the documentation of this file.
1 /** @file cfl_abaseset.h @brief Class TaBaseSet */
2 
3 
4 /* FAU Discrete Event Systems Library (libfaudes)
5 
6  Copyright (C) 2008 Thomas Moor
7  Exclusive copyright is granted to Klaus Schmidt
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
21 
22 
23 
24 #ifndef FAUDES_ABASESET_H
25 #define FAUDES_ABASESET_H
26 
27 #include "cfl_baseset.h"
28 
29 namespace faudes {
30 
31 /** @addtogroup ContainerClasses */
32 /** @{*/
33 
34 /**
35  * Set with nontrivial attributes.
36  *
37  * The TaBaseSet implements the attribute interface introduced
38  * in TBaseSet.
39  *
40  * Note: while TaBaseSet is indirectly derived from Type, we avoid the FAUDES_TYPE_DECLARATION
41  * macro and define the Type interface explicitely. This is for cosmetic reasons only.
42  *
43  */
44 
45 
46 template<class T, class Attr, class Cmp=std::less<T> >
47 class TaBaseSet : virtual public TBaseSet<T,Cmp> {
48 
49 
50 public:
51 
52  /**
53  * Constructor.
54  */
55  TaBaseSet(void);
56 
57  /**
58  * Copy-constructor.
59  * Uses DoAssign copy the set incl attributes.
60  *
61  * @param rOtherSet
62  * Source to copy from
63  */
64  TaBaseSet(const TaBaseSet& rOtherSet);
65 
66  /**
67  * Copy-constructor. Sets attributes to default.
68  * Uses the DoAssign method to convert attributes if possible.
69  *
70  * @param rOtherSet
71  * Source to copy from
72  */
73  TaBaseSet(const TBaseSet<T,Cmp>& rOtherSet);
74 
75  /**
76  * Constructor from file.
77  * This constructor indicates the intended interface for derived classes. The base set
78  * itself cannot read from token streams.
79  *
80  * @param rFilename
81  * Name of File
82  * @param rLabel
83  * Section for the set in the file;
84  */
85  TaBaseSet(const std::string& rFilename, const std::string& rLabel = "BaseSet");
86 
87  /**
88  * Virtual destructor
89  */
90  virtual ~TaBaseSet(void);
91 
92  /**
93  * Faudes Type interface. Construct object of same type on heap.
94  */
95  //virtual TaBaseSet* New(void) const { return new TaBaseSet(); };
96 
97  /**
98  * Faudes Type interface. Construct copy on heap.
99  */
100  //virtual TaBaseSet* Copy(void) const { return new TaBaseSet(*this); };
101 
102  /**
103  * Faudes Type interface. Cast object to my type.
104  */
105  //virtual const Type* Cast(const Type* pType) const { return dynamic_cast<const TaBaseSet*>(pType); };
106 
107  /**
108  * Copy from a TaBaseSet with matching attributes.
109  *
110  * @param rSourceSet
111  * Set to copy from
112  */
113  virtual TaBaseSet& Assign(const TaBaseSet& rSourceSet);
114 
115  /**
116  * Copy from a TBaseSet with attributes, provided that they
117  * can be casted acciordingly.
118  *
119  * @param rSourceSet
120  * Set to copy from
121  */
122  virtual TaBaseSet& Assign(const TBaseSet<T,Cmp>& rSourceSet);
123 
124  /**
125  * Copy from a TBaseSet without attributes. This method
126  * clears all attributes even if they cound be casted.
127  *
128  * @param rSourceSet
129  * Set to copy from
130  */
131  virtual TaBaseSet& AssignWithoutAttributes(const TBaseSet<T,Cmp>& rSourceSet);
132 
133  /**
134  * Faudes Type interface. Assignment operator with strict type matching.
135  * @param rSource
136  * Object to assign from
137  */
138  virtual TaBaseSet& operator=(const TaBaseSet& rSource) { DoAssign(rSource);return *this; };
139 
140  /**
141  * Faudes Type interface (extension). Assignment operator incl attribute cast.
142  * @param rSource
143  * Object to assign from
144  */
145  virtual TaBaseSet& operator=(const TBaseSet<T,Cmp>& rSource) { return Assign(rSource); }
146 
147  /**
148  * Clear all set.
149  */
150  virtual void Clear(void);
151 
152  /**
153  * Attribute typeinfo.
154  *
155  * @return
156  * Pointer to some attribute of this sets attribute type.
157  */
158  const Attr* Attributep(void) const;
159 
160  /**
161  * Attribute typeinfo
162  *
163  * @return
164  * Reference to some attribute of this sets attribute type
165  */
166  const Attr& Attribute(void) const;
167 
168  /**
169  * Attribute typeinfo.
170  * An TaBaseSet accepts all attributes that we can cast to our default attribute's type.
171  * The implementation uses the virtual function Cast of the default attribute to perform
172  * the test. Thus, it is crucial that Cast is re-implemented for attribute classes.
173  * @param rAttr
174  * Attribute type to test.
175  * @return True, if attribute type is accepted.
176  */
177  virtual bool AttributeTry(const Type& rAttr) const;
178 
179  /**
180  * Get number of explicit (aka non-default) attributes.
181  *
182  * @return
183  * Number of entries in mAttributeMap
184  */
185  virtual Idx AttributesSize(void) const ;
186 
187  /**
188  * Clear all attributes to default value.
189  *
190  */
191  virtual void ClearAttributes(void);
192 
193  /**
194  * Test whether attributes match with other set,
195  * Return true if attributes match for shared elements. It uses
196  * the equality test of individual attributes and, hence, requires the type
197  * match too.
198  * @param rOtherSet
199  * Other set to compare with.
200  * @return
201  * True on match.
202  */
203  virtual bool EqualAttributes(const TBaseSet<T,Cmp>& rOtherSet) const;
204 
205  /**
206  * Test set equality.
207  * The test ignores attributes. It is implemented by the virtual method DoEqual().
208  * @param rOtherSet
209  * Other set to compare with.
210  * @return
211  * True on match.
212  */
213  virtual bool operator==(const TBaseSet<T,Cmp>& rOtherSet) const;
214 
215  /**
216  * Test whether attributes match with other set,
217  * Return true if attributes match for shared elements. It uses
218  * the equality test of individual attributes and, hence, requires the type
219  * match too.
220  * @param rOtherSet
221  * Other set to compare with.
222  * @return
223  * True on match.
224  */
225  virtual bool EqualAttributes(const TaBaseSet& rOtherSet) const;
226 
227  /**
228  * Get attribute reference by element. Note that in order to produce a non-const
229  * reference this method will insert an explicit default attribute if necessary.
230  * If a const reference is sufficient, you should use Attribute(rElem) const instead.
231  *
232  * @param rElem
233  * Specify element
234  * @exception Exception
235  * - Element does not exist (60)
236  * @return
237  * Pointer to attribute
238  */
239  virtual Attr* Attributep(const T& rElem);
240 
241  /**
242  * Get attribute by element. This function returns a const reference to the attribute
243  * of the specified element.
244  * @param rElem
245  * Specify element
246  * @exception Exception
247  * - Element does not exist (63)
248  * @return
249  * Reference to attribute
250  */
251  virtual const Attr& Attribute(const T& rElem) const;
252 
253  /**
254  * Set attribute. Provided that the attribute can be casted to the
255  * appropriate type, this method sets the attribute of the sepcified element to the given value.
256  *
257  * @param rElem
258  * Specify element
259  * @param attr
260  * Attribute value.
261  * @exception Exception
262  * - Element does not exist (60)
263  * - Cannot cast attribute type (63)
264  */
265  virtual void Attribute(const T& rElem, const Type& attr);
266 
267  /**
268  * Set attribute. This method sets the attribute of the sepcified element to the given value.
269  *
270  * @param rElem
271  * Specify element
272  * @param attr
273  * Attribute value.
274  * @exception Exception
275  * - Element does not exist (60)
276  * - Cannot cast attribute type (63)
277  */
278  virtual void Attribute(const T& rElem, const Attr& attr);
279 
280  /**
281  * Set attribute. Provided that the attribute can be casted to the
282  * appropriate type, this method sets the attribute of the sepcified element to the given value.
283  * If the cast fails, this method does nothing.
284  *
285  * @param rElem
286  * Specify element
287  * @param attr
288  * Attribute value.
289  * @exception Exception
290  * - Element does not exist (60)
291  */
292  virtual void AttributeTry(const T& rElem, const Type& attr);
293 
294  /**
295  * Set attributes. Provided that rOtherSet has attributes that can be
296  * casted to the appropriate type, attributes are copied per element from rOtherSet.
297  * Elements of this set which are not in rOtherSet maintain their attribute.
298  *
299  * @param rOtherSet
300  * Other BaseSet
301  * @exception Exception
302  * - Cannot cast attribute type (63)
303  */
304  virtual void Attributes(const TBaseSet<T,Cmp>& rOtherSet);
305 
306  /**
307  * Set attributes. Attributes are copied per element from rOtherSet.
308  * Elements of this set which are not in rOtherSet maintain their attribute.
309  *
310  * @param rOtherSet
311  * Other BaseSet
312  */
313  virtual void Attributes(const TaBaseSet& rOtherSet);
314 
315  /**
316  * Clear attribute to default value.
317  *
318  * @param rElem
319  * Specify element
320  */
321  virtual void ClrAttribute(const T& rElem);
322 
323  /**
324  * Use TBaseSet iterators.
325  */
326  using typename TBaseSet<T,Cmp>::Iterator;
327 
328  /**
329  * Insert element. If the element exists, the attribute is maintained.
330  * If the element does not exist, it is inserted with default attribute.
331  *
332  * @param rElem
333  * Specify element
334  * @return
335  * True if element was new to set
336  */
337  bool Insert(const T& rElem);
338 
339  /**
340  * Insert element with attribute.
341  *
342  * @param rElem
343  * Specify element
344  * @param attr
345  * Specify attribute of (new) element
346  * @return
347  * True if element was new to set
348  */
349  bool Insert(const T& rElem, const Attr& attr);
350 
351  /**
352  * Inserts elements of rOtherSet.
353  * Attributes of this set are maintained, newly inserted elements have default attribute.
354  *
355  *
356  * @param rOtherSet
357  * Other BaseSet
358  */
359  void InsertSet(const TBaseSet<T,Cmp>& rOtherSet);
360 
361  /**
362  * Inserts elements of rOtherSet.
363  * Attributes of this set are maintained, new elements are inserted with attribute.
364  *
365  * @param rOtherSet
366  * Other BaseSet
367  */
368  void InsertSet(const TaBaseSet& rOtherSet);
369 
370 
371  /**
372  * Erase Element (incl its attribute)
373  *
374  * @param rElem
375  * Specify element
376  * @return
377  * True if element used to exist
378  */
379  bool Erase(const T& rElem);
380 
381  /**
382  * Erase element by iterator (incl attribute)
383  *
384  * @param pos
385  * Iterator to specify element
386  * @return
387  * Iterator to next element or End()
388  */
389  // declare&define for cl_win issues
391  ClrAttribute(*pos);
392  return TBaseSet<T,Cmp>::Erase(pos);
393  };
394 
395 
396  /**
397  * Erase elements given by other set. This function
398  * ignores the attributes of the other set and maintains the attributes
399  * of the remaining elements in this set.
400  *
401  * @param rOtherSet
402  * Elements to erase
403  */
404  void EraseSet(const TBaseSet<T,Cmp>& rOtherSet);
405 
406  /**
407  * Restrict to specified subset. Erases any elements no in
408  * the specified set. This function
409  * ignores the attributes of the other set and maintains the attributes
410  * of the remaining elements in this set.
411  *
412  * @param rOtherSet
413  * Elements to erase
414  */
415  void RestrictSet(const TBaseSet<T,Cmp>& rOtherSet);
416 
417 
418  /**
419  * Set union. The union is wrt the set of indices, the result is accumulated in this set.
420  * Attributes are set to default. See also InsertSet(const TaBaseSet&).
421  *
422  * @param rOtherSet
423  * Other BaseSet
424  */
425  void SetUnion(const TBaseSet<T,Cmp>& rOtherSet);
426 
427  /**
428  * Set intersection. The intersection is wrt set of indices, the result is stored in this set.
429  * Attributes are set to default.
430  *
431  * @param rOtherSet
432  * Other BaseSet
433  */
434  void SetIntersection(const TBaseSet<T,Cmp>& rOtherSet);
435 
436 
437  /** Detach from extern storage (reimplement base) */
438  virtual void Detach(void) const;
439 
440  protected:
441 
442  /** use TBaseSet STL iterators */
444 
445  /** use TBaseSet STL iterators */
447 
448  /** use TBaseSet STL iterators */
450 
451  /** use TBaseSet STL iterators */
453 
454 
455  /** default attribute */
457 
458  /** assignment from source with matching attributes */
459  virtual void DoAssign(const TaBaseSet& rSourceSet);
460 
461  /** test equality, ignore attributes */
462  virtual bool DoEqual(const TBaseSet<T,Cmp>& rOtherSet) const;
463 
464  /** set attribute in map (assume elem exists in set, NULL <=> set to default) */
465  virtual void DoAttributep(const T& rElem, const Type* pAttr);
466 
467  /** set attribute in map (assume elem exists in set, NULL <=> set to default) */
468  virtual void DoAttributep(const T& rElem, const Attr* pAttr);
469 
470  /** get attribute from map (return null if elem does not exist in map) */
471  virtual const Attr* DoAttributep(const T& rElem) const;
472 
473  /** get attribute from map (insert explicit default if elem does not exist in map) */
474  virtual Attr* DoAttributep(const T& rElem);
475 
476 
477 };
478 
479 
480 
481 /** @} doxygen group */
482 
483 
484 
485 /*
486 ******************************************************************************************
487 ******************************************************************************************
488 ******************************************************************************************
489 
490 Implementation of TaBaseSet
491 
492 ******************************************************************************************
493 ******************************************************************************************
494 ******************************************************************************************
495 */
496 
497 /* convenience access to relevant scopes */
498 #define THIS TaBaseSet<T,Attr,Cmp>
499 #define TEMP template<class T, class Attr, class Cmp>
500 #define BASE TBaseSet<T,Cmp>
501 
502 // TaBaseSet()
503 TEMP THIS::TaBaseSet(void) :
504  BASE(),
505  mpDefAttribute(new Attr())
506 {
507  FD_DC("TaBaseSet(" << this << ")::TaBaseSet()");
508 }
509 
510 
511 // TaBaseSet(rOtherSet)
512 TEMP THIS::TaBaseSet(const TaBaseSet& rOtherSet) :
513  BASE(),
514  mpDefAttribute(new Attr())
515 {
516  FD_DC("TaBaseSet(" << this << ")::TaBaseSet(TaBaseSet " << &rOtherSet << "): copy construct");
517  DoAssign(rOtherSet);
518 }
519 
520 // TaBaseSet(rOtherSet)
521 TEMP THIS::TaBaseSet(const TBaseSet<T,Cmp>& rOtherSet) :
522  BASE(),
523  mpDefAttribute(new Attr())
524 {
525  FD_DC("TaBaseSet(" << this << ")::TaBaseSet(TBaseSet " << &rOtherSet << "): copy construct");
526  Assign(rOtherSet);
527 }
528 
529 // TaBaseSet(filename)
530 TEMP THIS::TaBaseSet(const std::string& rFileName, const std::string& rLabel) :
531  BASE(),
532  mpDefAttribute(new Attr())
533 {
534  FD_DC("TaBaseSet(" << this << ")::TaBaseSet()");
535  // do read etc ... this is a dummy anyway
536  BASE::Read(rFileName,rLabel);
537 }
538 
539 // destructor
540 TEMP THIS::~TaBaseSet(void) {
541  FD_DC("TaBaseSet(" << this << ")::~TaBaseSet()");
542  // free my members
543  if(mpDefAttribute) delete mpDefAttribute;
544  // note: attributes will be deleted in BASE after relink
545 }
546 
547 
548 // copy, matching attributes
549 TEMP void THIS::DoAssign(const TaBaseSet& rSourceSet) {
550  FD_DC("TaBaseSet(" << this << ")::DoAssign(TaBaseSet " << &rSourceSet << ")");
551  // bail out on selfref
552  if(this==&rSourceSet) return;
553  // call base (fake copy, sets to empty attributes)
554  BASE::DoAssign(rSourceSet);
555  // link to shared attributes
556  BASE::pAttributes=rSourceSet.pAttributes;
557 }
558 
559 
560 
561 // public wrapper
562 TEMP THIS& THIS::Assign(const TaBaseSet<T,Attr,Cmp>& rSourceSet) {
563  DoAssign(rSourceSet);
564  return *this;
565 }
566 
567 // assign, try attributes
568 TEMP THIS& THIS::Assign(const TBaseSet<T,Cmp>& rSourceSet) {
569  FD_DC("TaBaseSet(" << this << ")::Assign(..)");
570  FD_DC("TaBaseSet(" << this << ")::Assign(..): dst type " << typeid(*this).name());
571  FD_DC("TaBaseSet(" << this << ")::Assign(..): src type " << typeid(rSourceSet).name());
572  // call base (fake copy, results in effectively empty attributes)
573  BASE::DoAssign(rSourceSet);
574  // detach, since we dont want to share mixed attributes
575  Detach();
576  // if there are no attributes, we dont worry
577  if(rSourceSet.AttributesSize()==0) return *this;
578  // if we have void attributes, we cannot cast (TODO: known at compiletime!)
579  FD_DC("TaBaseSet(" << this << ")::Assign(..): dst attribute type " << typeid(*mpDefAttribute).name());
580  if( typeid(*mpDefAttribute) == typeid(AttributeVoid) ) return *this;
581  // if source has void attributes, we cannot cast
582  FD_DC("TaBaseSet(" << this << ")::Assign(..): src attribute type " << typeid(*rSourceSet.Attributep()).name());
583  if( typeid(*rSourceSet.Attributep()) == typeid(const AttributeVoid) ) return *this;
584  // if attributes cannot be casted, we dont need to loop either
585  FD_DC("TaBaseSet(" << this << ")::Assign(..): try attribute cast");
586  if(!mpDefAttribute->Cast(rSourceSet.Attributep())) return *this;
587  // try to be smart on attributes
588  BASE::mpAttributes= new std::map<T,AttributeVoid*>();
589  BASE::pAttributes=BASE::mpAttributes;
590  FD_DC("TaBaseSet(" << this << ")::Assign(..): mind attributes");
591  const_aiterator ait=rSourceSet.pAttributes->begin();
592  for(;ait!=rSourceSet.pAttributes->end(); ++ait) {
593  Attr* attr= new Attr;
594  attr->Assign(*ait->second);
595  (*BASE::pAttributes)[ait->first]=attr;
596  }
597  // done
598  FD_DC("TaBaseSet(" << this << ")::Assign(..): done");
599  return *this;
600 }
601 
602 
603 
604 // public wrapper
605 TEMP THIS& THIS::AssignWithoutAttributes(const TBaseSet<T,Cmp>& rSourceSet) {
606  // call base (fake copy, results in effectively empty attributes)
607  BASE::DoAssign(rSourceSet);
608  // detach, since we dont want to share mixed attributes
609  Detach();
610  // done
611  return *this;
612 }
613 
614 // test equality, ignore attributes
615 TEMP bool THIS::DoEqual(const TBaseSet<T,Cmp>& rOtherSet) const {
616  FD_DC("TaBaseSet::DoEqual()");
617  // require set elements to match
618  if(!BASE::DoEqual(rOtherSet))
619  return false;
620  // ok, equal
621  return true;
622  /*
623  For reference: version that requires attributes either to match or
624  to be of default value
625 
626  // true, if we share attubute data
627  FD_DC("TaBaseSet::DoEqual(TBaseSet): 2");
628  if(BASE::pAttributes==rOtherSet.pAttributes)
629  return true;
630  // true, if there are no attributes
631  FD_DC("TaBaseSet::EqualAttributes(TBaseSet): 3");
632  if(rOtherSet.AttributesSize()==0)
633  if(this->AttributesSize()==0)
634  return true;
635  // iterate over attributes
636  aiterator ait1 = BASE::pAttributes->begin();
637  aiterator ait2 = rOtherSet.pAttributes->begin();
638  while ((ait1 != BASE::pAttributes->end()) && (ait2 != rOtherSet.pAttributes->end())) {
639  if (ait1->first < ait2->first) {
640  ++ait1;
641  }
642  else if (ait1->first == ait2->first) {
643  FD_DC("TaBaseSet::EqualAttributes(TBaseSet): cmp " << ait1->second->ToString()
644  << " vs " << ait2->second->ToString());
645  if( (!ait1->second->IsDefault()) || (!ait2->second->IsDefault()))
646  if( ! ait1->second->Equal(*ait2->second)) return false;
647  ++ait1;
648  ++ait2;
649  }
650  else { // (*it1 > *it2)
651  ++ait2;
652  }
653  }
654  // passed
655  FD_DC("TaBaseSet::EqualAttributes(TBaseSet): pass");
656  return true;
657  */
658 }
659 
660 // operator version of DoEqual
661 TEMP bool THIS::operator==(const TBaseSet<T,Cmp>& rOtherSet) const {
662  return DoEqual(rOtherSet);
663 }
664 
665 // Detach()
666 TEMP void THIS::Detach(void) const {
667  FD_DC("TaBaseSet(" << this << ")::Detach(void)");
668 
669  // nothing todo
670  if(BASE::mDetached) return;
671 
672  // provide fake const
673  THIS* fake_const = const_cast< THIS* >(this);
674 
675  // do allocation and copy of attributes,
676  std::map<T,AttributeVoid*>* acopy = new std::map<T,AttributeVoid*>();
677  for(aiterator ait=BASE::pAttributes->begin(); ait!=BASE::pAttributes->end(); ++ait) {
678  Attr* attr= new Attr();
679  attr->Assign(*ait->second);
680  (*acopy)[ait->first]=attr;
681  }
682 
683  // call base for core set, effectively empty attributes
684  BASE::Detach();
685 
686  // stragie A or B: others got the origianal attributes, i take the copy
687  fake_const->mpAttributes=acopy;
688  fake_const->pAttributes=acopy;
689 
690 }
691 
692 
693 //Clear
694 TEMP void THIS::Clear(void) {
695  FD_DC("TaBaseSet(" << this << ")::Clear()");
696  // call base (incl streamlined pseudo detach and empty attributes)
697  BASE::Clear();
698 }
699 
700 
701 //Insert(elem)
702 TEMP bool THIS::Insert(const T& rElem) {
703  FD_DC("TvIndexSet(" << this << ")::Insert(elem)");
704  bool ret=BASE::Insert(rElem);
705  return ret;
706 }
707 
708 //Insert(idx,attr)
709 TEMP bool THIS::Insert(const T& rElem, const Attr& rAttr) {
710  FD_DC("TaIndexSet(" << this << ")::Insert(elem,attr)");
711  Detach();
712  bool ret=BASE::pSet->insert(rElem).second;
713  DoAttributep(rElem,&rAttr);
714  return ret;
715 }
716 
717 // InsertSet(set)
718 TEMP void THIS::InsertSet(const TBaseSet<T,Cmp>& rOtherSet) {
719  bool doattr=AttributeTry(rOtherSet.Attribute());
720  FD_DC("TaBaseSet(" << this << ")::InsertSet( [v] " << &rOtherSet << "): doattr=" << doattr);
721  Detach();
722  iterator it1 = BASE::pSet->begin();
723  iterator it2 = rOtherSet.pSet->begin();
724  while ((it1 != BASE::pSet->end()) && (it2 != rOtherSet.pSet->end())) {
725  if (*it1 < *it2) {
726  ++it1;
727  }
728  else if (*it1 == *it2) {
729  ++it1;
730  ++it2;
731  }
732  else { // (*it1 > *it2)
733  Insert(*it2);
734  if(doattr) DoAttributep(*it2,&rOtherSet.Attribute(*it2));
735  ++it2;
736  }
737  }
738  while (it2 != rOtherSet.pSet->end()) {
739  Insert(*it2);
740  if(doattr) DoAttributep(*it2,&rOtherSet.Attribute(*it2));
741  ++it2;
742  }
743 }
744 
745 // InsertSet(set)
746 TEMP void THIS::InsertSet(const TaBaseSet& rOtherSet) {
747  FD_DC("TaBaseSet(" << this << ")::InsertSet( [a] " << &rOtherSet << ")");
748  Detach();
749  iterator it1 = BASE::pSet->begin();
750  iterator it2 = rOtherSet.pSet->begin();
751  while ((it1 != BASE::pSet->end()) && (it2 != rOtherSet.pSet->end())) {
752  if (*it1 < *it2) {
753  ++it1;
754  }
755  else if (*it1 == *it2) {
756  ++it1;
757  ++it2;
758  }
759  else { // (*it1 > *it2)
760  Insert(*it2,rOtherSet.Attribute(*it2));
761  ++it2;
762  }
763  }
764  while (it2 != rOtherSet.pSet->end()) {
765  Insert(*it2,rOtherSet.Attribute(*it2));
766  ++it2;
767  }
768 }
769 
770 
771 //Erase(idx)
772 TEMP bool THIS::Erase(const T& rElem) {
773  Detach();
774  DoAttributep(rElem,(const Attr*) 0);
775  return (BASE::pSet->erase(rElem)!=0);
776 }
777 
778 
779 //Erase(pos)
780 /*
781 // cl_win issue: has been moved to declaration
782 TEMP typename BASE::Iterator THIS::Erase(const typename BASE::Iterator& pos) {
783 #ifdef FAUDES_CHECKED
784  if(pos == BASE::End()) {
785  std::stringstream errstr;
786  errstr << "iterator out of range " << std::endl;
787  throw Exception("TaBase::Erase", errstr.str(), 60);
788  }
789 #endif
790  ClrAttribute(*pos);
791  return BASE::Erase(pos);
792 }
793 */
794 
795 //EraseSet(set)
796 TEMP void THIS::EraseSet(const TBaseSet<T,Cmp>& rOtherSet) {
797  FD_DC("TaBaseSet(" << this << ")::EraseSet(" << rOtherSet.ToString() << ")");
798  Detach();
799  // todo: test and optimize
800  iterator tmpit;
801  iterator it = BASE::pSet->begin();
802  iterator oit = rOtherSet.pSet->begin();
803  while ((it != BASE::pSet->end()) && (oit != rOtherSet.pSet->end())) {
804  if (*it < *oit) {
805  it=BASE::pSet->lower_bound(*oit); // alt: ++it;
806  }
807  else if (*it == *oit) {
808  DoAttributep(*it,(const Attr*) 0);
809  tmpit=it;
810  ++it;
811  ++oit;
812  BASE::pSet->erase(tmpit);
813  }
814  else { // (*it > *oit)
815  oit=rOtherSet.pSet->lower_bound(*it); // ++it2;
816  }
817  }
818 }
819 
820 
821 //RestrictSet(set)
822 TEMP void THIS::RestrictSet(const TBaseSet<T,Cmp>& rOtherSet) {
823  FD_DC("TaIndexSet(" << this << ")::RestrictSet(" << rOtherSet.ToString() << ")");
824  Detach();
825  // todo: test and optimize
826  iterator tmpit;
827  iterator it = BASE::pSet->begin();
828  iterator oit = rOtherSet.pSet->begin();
829  while ((it != BASE::pSet->end()) && (oit != rOtherSet.pSet->end())) {
830  if (*it < *oit) {
831  DoAttributep(*it,(const Attr*) 0);
832  tmpit=it;
833  ++it;
834  BASE::pSet->erase(tmpit);
835  }
836  else if (*it == *oit) {
837  ++it;
838  ++oit;
839  }
840  else { // (*it > *oit)
841  ++oit;
842  }
843  }
844  while(it != BASE::pSet->end()) {
845  DoAttributep(*it,(const Attr*) 0);
846  tmpit=it;
847  ++it;
848  BASE::pSet->erase(tmpit);
849  }
850 
851 }
852 
853 
854 // SetUnion(set)
855  TEMP void THIS::SetUnion(const TBaseSet<T,Cmp>& rOtherSet) {
856  BASE::SetUnion(rOtherSet);
857  ClearAttributes();
858 }
859 
860 // SetUnion(set)
862  BASE::SetIntersection(rOtherSet);
863  ClearAttributes();
864 }
865 
866 
867 // attribute typeinfo
868 TEMP const Attr* THIS::Attributep(void) const {
869  return mpDefAttribute;
870 }
871 
872 // attribute typeinfo
873 TEMP const Attr& THIS::Attribute(void) const {
874  return *mpDefAttribute;
875 }
876 
877 // test attribute type
878 TEMP bool THIS::AttributeTry(const Type& rAttr) const {
879  return mpDefAttribute->Cast(&rAttr)!=NULL;
880 }
881 
882 
883 // get attribute wrapper
884 TEMP Attr* THIS::Attributep(const T& rElem) {
885 #ifdef FAUDES_CHECKED
886  if(!THIS::Exists(rElem)) {
887  std::stringstream errstr;
888  errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
889  throw Exception("TaBaseSet::Attributep(elem)", errstr.str(), 60);
890  }
891 #endif
892  // must detach
893  Detach();
894  // find in map (incl insert explicit default)
895  Attr* res=DoAttributep(rElem);
896  // done
897  return res;
898 }
899 
900 // get attribute wrapper
901 TEMP const Attr& THIS::Attribute(const T& rElem) const {
902 #ifdef FAUDES_CHECKED
903  if(!THIS::Exists(rElem)) {
904  std::stringstream errstr;
905  errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
906  throw Exception("TaBaseSet::Attribute(elem)", errstr.str(), 60);
907  }
908 #endif
909  // find in map
910  const Attr* res=DoAttributep(rElem);
911  // use default
912  if(!res) res=mpDefAttribute;
913  // done
914  return *res;
915 }
916 
917 // set attribute wrapper
918 TEMP void THIS::Attribute(const T& rElem, const Type& attr) {
919 #ifdef FAUDES_CHECKED
920  if (!THIS::Exists(rElem)) {
921  std::stringstream errstr;
922  errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
923  throw Exception("TaBaseSet::Attribute(elem,attr)", errstr.str(), 60);
924  }
925 #endif
926  if(!AttributeTry(attr)) {
927  std::stringstream errstr;
928  errstr << "cannot cast attribute " << std::endl;
929  throw Exception("TaBaseSet::Attribute(elem,attr)", errstr.str(), 63);
930  }
931  Detach();
932  DoAttributep(rElem, dynamic_cast<const Attr*>(&attr));
933 }
934 
935 // set attribute wrapper
936 TEMP void THIS::AttributeTry(const T& rElem, const Type& attr) {
937  if(!AttributeTry(attr)) return;
938 #ifdef FAUDES_CHECKED
939  if (!THIS::Exists(rElem)) {
940  std::stringstream errstr;
941  errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
942  throw Exception("TaBaseSet::Attribute(elem)", errstr.str(), 60);
943  }
944 #endif
945  Detach();
946  DoAttributep(rElem, dynamic_cast<const Attr*>(&attr));
947 }
948 
949 // set attribute wrapper
950 TEMP void THIS::Attribute(const T& rElem, const Attr& attr) {
951 #ifdef FAUDES_CHECKED
952  if (!THIS::Exists(rElem)) {
953  std::stringstream errstr;
954  errstr << "element \"" << this->Str(rElem) << "\" not member of set " << this->Name() << std::endl;
955  throw Exception("TaBaseSet::Attribute(elem)", errstr.str(), 60);
956  }
957 #endif
958  Detach();
959  DoAttributep(rElem, &attr);
960 }
961 
962 
963 // set attribute wrapper
964 TEMP void THIS::Attributes(const TBaseSet<T,Cmp>& rOtherSet) {
965  if(!AttributeTry(rOtherSet.Attribute())) {
966  std::stringstream errstr;
967  errstr << "cannot cast attribute " << std::endl;
968  throw Exception("TaBaseSet::Attribute(elem,attr)", errstr.str(), 63);
969  }
970  Detach();
971  iterator it1 = BASE::pSet->begin();
972  iterator it2 = rOtherSet.pSet->begin();
973  while ((it1 != BASE::pSet->end()) && (it2 != rOtherSet.pSet->end())) {
974  if (*it1 < *it2) {
975  ++it1;
976  }
977  else if (*it1 == *it2) {
978  DoAttributep(*it1,&rOtherSet.Attribute(*it2));
979  ++it1;
980  ++it2;
981  }
982  else { // (*it1 > *it2)
983  ++it2;
984  }
985  }
986 }
987 
988 // set attribute wrapper
989 TEMP void THIS::Attributes(const TaBaseSet& rOtherSet) {
990  Detach();
991  iterator it1 = BASE::pSet->begin();
992  iterator it2 = rOtherSet.pSet->begin();
993  while ((it1 != BASE::pSet->end()) && (it2 != rOtherSet.pSet->end())) {
994  if (*it1 < *it2) {
995  ++it1;
996  }
997  else if (*it1 == *it2) {
998  DoAttributep(*it1,&rOtherSet.Attribute(*it2));
999  ++it1;
1000  ++it2;
1001  }
1002  else { // (*it1 > *it2)
1003  ++it2;
1004  }
1005  }
1006 }
1007 
1008 // clr attributes wrapper
1009 TEMP void THIS::ClrAttribute(const T& rElem) {
1010  Detach();
1011  DoAttributep(rElem,(const Attr*) 0);
1012 }
1013 
1014 // Implement attributes: clear
1015 TEMP void THIS::ClearAttributes(void) {
1016  // bail out if there are no attributes anyway
1017  if(BASE::pAttributes->size()==0) return;
1018  // detach (incl empty attributes if used to share)
1019  BASE::Detach();
1020  // clear if we (still) own attributes FIXME ...DOUBLE CHECK
1021  if(BASE::mpAttributes) {
1022  aiterator ait=BASE::mpAttributes->begin();
1023  for(;ait!=BASE::mpAttributes->end();++ait)
1024  delete ait->second;
1025  BASE::mpAttributes->clear();
1026  }
1027 }
1028 
1029 // Implement attributes: equality
1030 TEMP bool THIS::EqualAttributes(const TBaseSet<T,Cmp>& rOtherSet) const {
1031  FD_DC("TaBaseSet::EqualAttributes(TBaseSet)");
1032  // true, if we share attubute data
1033  FD_DC("TaBaseSet::EqualAttributes(TBaseSet): 1");
1034  if(BASE::pAttributes==rOtherSet.pAttributes)
1035  return true;
1036  // false, if type does not match
1037  FD_DC("TaBaseSet::EqualAttributes(TBaseSet): 2");
1038  if(typeid(*rOtherSet.Attributep())!=typeid(*this->Attributep()))
1039  return false;
1040  // true if there are no attributes
1041  FD_DC("TaBaseSet::EqualAttributes(TBaseSet): 3");
1042  if(rOtherSet.AttributesSize()==0)
1043  if(this->AttributesSize()==0)
1044  return true;
1045  // figure shared elements
1046  aiterator ait1 = BASE::pAttributes->begin();
1047  aiterator ait2 = rOtherSet.pAttributes->begin();
1048  while ((ait1 != BASE::pAttributes->end()) && (ait2 != rOtherSet.pAttributes->end())) {
1049  if (ait1->first < ait2->first) {
1050  ++ait1;
1051  }
1052  else if (ait1->first == ait2->first) {
1053  FD_DC("TaBaseSet::EqualAttributes(TBaseSet): cmp " << ait1->second->ToString()
1054  << " vs " << ait2->second->ToString());
1055  if( ! ait1->second->Equal(*ait2->second)) return false;
1056  ++ait1;
1057  ++ait2;
1058  }
1059  else { // (*it1 > *it2)
1060  ++ait2;
1061  }
1062  }
1063  // passed
1064  FD_DC("TaBaseSet::EqualAttributes(TBaseSet): pass");
1065  return true;
1066 }
1067 
1068 // Implement attributes: equality
1069 TEMP bool THIS::EqualAttributes(const TaBaseSet& rOtherSet) const {
1070  FD_DC("TaBaseSet::EqualAttributes(TaBaseSet)");
1071  // true, if we share attubute data
1072  if(BASE::pAttributes==rOtherSet.pAttributes)
1073  return true;
1074  // true if there are no attributes
1075  if(rOtherSet.AttributesSize()==0)
1076  if(this->AttributesSize()==0)
1077  return true;
1078  // figure shared elements
1079  aiterator ait1 = BASE::pAttributes->begin();
1080  aiterator ait2 = rOtherSet.pAttributes->begin();
1081  while ((ait1 != BASE::pAttributes->end()) && (ait2 != rOtherSet.pAttributes->end())) {
1082  if (ait1->first < ait2->first) {
1083  ++ait1;
1084  }
1085  else if (ait1->first == ait2->first) {
1086  if( *(static_cast<const Attr*>(ait1->second)) !=
1087  *(static_cast<const Attr*>(ait2->second)) ) return false;
1088  ++ait1;
1089  ++ait2;
1090  }
1091  else { // (*it1 > *it2)
1092  ++ait2;
1093  }
1094  }
1095  // passed
1096  return true;
1097 }
1098 
1099 // Implement attributes: get pointer
1100 TEMP const Attr* THIS::DoAttributep(const T& rElem) const {
1101  const_aiterator ait;
1102  ait=BASE::pAttributes->find(rElem);
1103  if(ait==BASE::pAttributes->end()) return NULL;
1104  return static_cast<const Attr*>(ait->second);
1105 }
1106 
1107 // Implement attributes: get pointer (must detach)
1108 TEMP Attr* THIS::DoAttributep(const T& rElem) {
1109  FD_DC("TaBaseSet::DoAttributep(Elem)");
1110 #ifdef FAUDES_DEBUG_CODE
1111  if(BASE::pAttributes!=BASE::mpAttributes) {
1112  FD_ERR("TaBaseSet::DoAttributep(Elem): attributes not detached");
1113  abort();
1114  }
1115 #endif
1116  aiterator ait;
1117  ait=BASE::pAttributes->find(rElem);
1118  // explicit default
1119  if( ait==BASE::pAttributes->end() ) {
1120  Attr* attr = new Attr();
1121  attr->Assign(*mpDefAttribute);
1122  (*BASE::pAttributes)[rElem]=attr;
1123  return attr;
1124  }
1125  return static_cast<Attr*>(ait->second);
1126 }
1127 
1128 // Implement attributes: set (must detach)
1129 TEMP void THIS::DoAttributep(const T& rElem, const Type* pAttr) {
1130  FD_DC("TaBaseSet::DoAttributep([v] " << this->Str(rElem) << ", ...)");
1131 #ifdef FAUDES_DEBUG_CODE
1132  if(BASE::pAttributes!=BASE::mpAttributes) {
1133  FD_ERR("TaBaseSet::DoAttributep([v] set): attributes not detached");
1134  abort();
1135  }
1136 #endif
1137  // find element in map
1138  aiterator ait;
1139  AttributeVoid* oldattr=NULL;
1140  const AttributeVoid* newattr=dynamic_cast<const AttributeVoid*>(pAttr);
1141  ait=BASE::pAttributes->find(rElem);
1142  if(ait!=BASE::pAttributes->end() )
1143  oldattr=ait->second;
1144  // set to default, case 1
1145  if(newattr==NULL) {
1146  FD_DC("TaBaseSet::DoAttributep([v] " << this->Str(rElem) << ", ...): default 1");
1147  if(oldattr==NULL) return;
1148  delete oldattr;
1149  BASE::pAttributes->erase(ait);
1150  return;
1151  }
1152  // set to default, case b
1153  if(newattr->IsDefault()) {
1154  FD_DC("TaBaseSet::DoAttributep([v] " << this->Str(rElem) << ", ...): default 2");
1155  if(oldattr==NULL) return;
1156  delete oldattr;
1157  BASE::pAttributes->erase(ait);
1158  return;
1159  }
1160  FD_DC("TaBaseSet::DoAttributep([v] " << this->Str(rElem) << ", ...): " << newattr->ToString());
1161  // prepare attribute and set
1162  if(oldattr==NULL) {
1163  Attr* attr = new Attr();
1164  attr->Assign(*newattr);
1165  (*BASE::pAttributes)[rElem]=attr;
1166  return;
1167  }
1168  // plain set
1169  oldattr->Assign(*pAttr);
1170 }
1171 
1172 // Implement attributes: set (must detach)
1173 TEMP void THIS::DoAttributep(const T& rElem, const Attr* pAttr) {
1174  FD_DC("TaBaseSet::DoAttributep([a] " << this->Str(rElem) << ", ...)");
1175 #ifdef FAUDES_DEBUG_CODE
1176  if(BASE::pAttributes!=BASE::mpAttributes) {
1177  FD_ERR("TaBaseSet::DoAttributep([a] set): attributes not detached");
1178  abort();
1179  }
1180 #endif
1181  // find element in map
1182  aiterator ait;
1183  AttributeVoid* oldattr=NULL;
1184  ait=BASE::pAttributes->find(rElem);
1185  if(ait!=BASE::pAttributes->end() )
1186  oldattr=ait->second;
1187  // set to default, case a
1188  if(pAttr==NULL) {
1189  if(oldattr==NULL) return;
1190  delete oldattr;
1191  BASE::pAttributes->erase(ait);
1192  return;
1193  }
1194  // set to default, case b
1195  if(pAttr->IsDefault()) {
1196  if(oldattr==NULL) return;
1197  delete oldattr;
1198  BASE::pAttributes->erase(ait);
1199  return;
1200  }
1201  // prepare attribute and set
1202  if(oldattr==NULL) {
1203  Attr* attr = new Attr();
1204  *attr=*pAttr;
1205  (*BASE::pAttributes)[rElem]=attr;
1206  return;
1207  }
1208  // plain set
1209  *static_cast<Attr*>(oldattr)=*pAttr;
1210 }
1211 
1212 // Implement attributes
1213 TEMP Idx THIS::AttributesSize(void) const {
1214  return BASE::pAttributes->size();
1215 }
1216 
1217 /* undefine local shortcuts */
1218 #undef THIS
1219 #undef TEMP
1220 #undef BASE
1221 
1222 
1223 } // namespace faudes
1224 
1225 #endif

libFAUDES 2.26g --- 2015.08.17 --- c++ api documentaion by doxygen