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

libFAUDES 2.24g --- 2014.09.15 --- c++ api documentaion by doxygen