cfl_baseset.h
Go to the documentation of this file.
1 /** @file cfl_baseset.h @brief Class TBaseSet */
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 
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_BASESET_H
26 #define FAUDES_BASESET_H
27 
28 #include "cfl_definitions.h"
29 #include "cfl_tokenwriter.h"
30 #include "cfl_tokenreader.h"
31 #include "cfl_registry.h"
32 #include "cfl_types.h"
33 #include "cfl_attributes.h"
34 #include <set>
35 #include <algorithm>
36 
37 // fix mingw toochain
38 #ifdef THIS
39 #undef THIS
40 #endif
41 
42 namespace faudes {
43 
44 /** @addtogroup ContainerClasses */
45 /** @{*/
46 
47 // Forward declaration for the attribute interface class
48 template<class T, class Attr, class Cmp> class TAttrMap;
49 
50 /**
51  * STL style set template.
52  * This class template is built on top of the STL set template. It provides essentials of
53  * the STL interface relevant to libFAUDES plus a deferred copy mechanism, aka copy-on-write.
54  * TBaseSet serves as a base class for all libFaudes containers:
55  * - IndexSet (indices),
56  * - TaIndexSet (indices with attributes),
57  * - SymbolSet (symbolic names),
58  * - NameSet (indices with symbolic names),
59  * - TaNameSet (indices with attributes and symbolic names),
60  * - TTransSet (transitions in a sepcific order),
61  * - TaTransSet (transitions in std order with attribute).
62  *
63  * The public functions of a TBaseSet provide the high-level api, with the intention
64  * to organize the deferred copy machanism in a transparent manner. Since STL iterators
65  * refer to a particular STL container, they become invalid when the internal container
66  * is copied. Therefor, TBaseSet tracks iterators and fixes them when the actual copy takes place.
67  * This introduces some runtime overhead, in particular when your application represents
68  * subsets as sets of iterators. You may use the public method Lock() to enforce
69  * a full copy and to prevent any further re-allocation.
70  *
71  * Alternatively to the high-level api, a protected low-level api is provided with direct
72  * access to the internal STL set. When using this api, it is up to the derived class to ensure
73  * that the BaseSet gets detached from its refernces befor write operations can take
74  * place.
75  *
76  * The virtual function TBaseSet<T>::Valid() is used to indicate whether a candidate
77  * element is valid as a set member. If the macro FAUDES_CHECKED
78  * is defined, the attempt to insert an invalid element triggers an exception (id 61). Invalid
79  * iterators throw an exception (id 62) when used as an argument to a BaseSet function.
80  *
81  * The TBaseSet also hosts a container to associate an attribute with each set element. However,
82  * in the plain TBAseSey the attribute type is set to void and member methods only deal
83  * with attributes when this does not invilve too much overhead. To make effective use of attributes,
84  * one is meant to derive a class from TBaseSet that encodes the actual attribute type and
85  * that provides appropriate access methods. This is facilitated by the class TAttrMap.
86  *
87  * Note on a boring technical detail:
88  * since STL sets are sorted, effectively all set iterators should be const.
89  * However, there is a minor issue whether or not the erase function should use a
90  * const iterator as argument. SGI derived STL implementations (as used on most GNU systems)
91  * avoid this issue by defining const and non-const iterators on sets as identical types.
92  * MS implementation (used in VS C++ by default, as of 2006) differ in this aspect. The class
93  * TBaseSet::Iterator hides the issue from the faudes API but it is still present internaly.
94  *
95  */
96 
97 template<class T, class Cmp=std::less<T> >
98 class FAUDES_TAPI TBaseSet : public Type {
99 
101 
102 public:
103 
104  using Type::operator=;
105  using Type::operator==;
106  using Type::operator!=;
107 
108  /** allow access to attribute interface class */
109  template<class TP, class AP, class CP> friend class TAttrMap;
110 
111 
112  /**
113  * Constructor.
114  */
115  TBaseSet(void);
116 
117  /**
118  * Copy-constructor.
119  *
120  * @param rOtherSet
121  * Source to copy from
122  */
123  TBaseSet(const TBaseSet& rOtherSet);
124 
125  /**
126  * Constructor from file.
127  * This constructor indicates the intended interface for derived classes. The base set
128  * itself cannot read from token streams.
129  *
130  * @param rFilename
131  * Name of File
132  * @param rLabel
133  * Section for the set in the file;
134  */
135  TBaseSet(const std::string& rFilename, const std::string& rLabel = "BaseSet");
136 
137  /**
138  * Virtual destructor
139  */
140  virtual ~TBaseSet(void);
141 
142  /**
143  * Return name of TBaseSet
144  *
145  * @return
146  * Name of TBaseSet
147  */
148  const std::string& Name(void) const;
149 
150  /**
151  * Set name of TBaseSet
152  *
153  * @param rName
154  * Name to set
155  */
156  void Name(const std::string& rName);
157 
158 
159  /**
160  * Clear all set
161  */
162  virtual void Clear(void);
163 
164  /**
165  * Get Size of TBaseSet
166  *
167  * @return
168  * Number of indices in TBaseSet
169  */
170  Idx Size(void) const;
171 
172  /**
173  * Test whether if the TBaseSet is Empty
174  *
175  * @return
176  * True if empty
177  */
178  bool Empty(void) const;
179 
180  /**
181  * Return pretty printable element.
182  * Reimplement this method for derived classes.
183  *
184  * @param rElem
185  * Element to print
186  *
187  * @return
188  * String
189  */
190  virtual std::string Str(const T& rElem) const;
191 
192  /**
193  * Iterator class for high-level api to TBaseSet.
194  *
195  */
196  class Iterator;
197 
198  /**
199  * Iterator to the begin of set
200  *
201  * @return
202  * Iterator
203  */
204  Iterator Begin(void) const;
205 
206  /**
207  * Iterator to the end of set
208  *
209  * @return
210  * Iterator
211  */
212  Iterator End(void) const;
213 
214  /**
215  * Test validty of candidate element.
216  *
217  * Reimplement this function for particular type T of elements,
218  * eg for an index set with T=Idx indicate 0 an invalid index.
219  *
220  * @param rElem
221  * Candidate to test
222  * @return
223  * True if element is valid
224  */
225  virtual bool Valid(const T& rElem) const;
226 
227 
228  /**
229  * Erase element by reference
230  *
231  * @param rElem
232  * Element to erase
233  * @return
234  * True if element used to exist
235  */
236  virtual bool Erase(const T& rElem);
237 
238 
239  /**
240  * Erase element by iterator
241  *
242  * @param pos
243  * Iterator to specify element
244  * @return
245  * Iterator to next element (or End if no such)
246  */
247  virtual Iterator Erase(const Iterator& pos);
248 
249 
250  /**
251  * Erase elements given by other set
252  *
253  * @param rOtherSet
254  * Set of elements to erase
255  */
256  virtual void EraseSet(const TBaseSet& rOtherSet);
257 
258  /**
259  * Restrict elements given by other set
260  *
261  * @param rOtherSet
262  * Set of elements to keep
263  */
264  virtual void RestrictSet(const TBaseSet& rOtherSet);
265 
266  /**
267  * Test for this set to be disjoint witg other set
268  *
269  * @param rOtherSet
270  * Set of elements to keep
271  */
272  virtual bool Disjoint(const TBaseSet& rOtherSet) const;
273 
274  /**
275  * Insert specified element
276  *
277  * @param rElem
278  * Element to insert
279  * @return
280  * True if index was new to set
281  */
282  virtual bool Insert(const T& rElem);
283 
284  /**
285  * Insert specified element
286  *
287  * @param pos
288  * Insertion hint passed to STL
289  * @param rElem
290  * Element to insert
291  * @return
292  * Insertion position
293  *
294  */
295  virtual Iterator Inject(const Iterator& pos, const T& rElem);
296 
297  /**
298  * Insert specified element
299  *
300  * @param rElem
301  * Element to insert
302  *
303  */
304  virtual void Inject(const T& rElem);
305 
306  /**
307  * Insert elements given by rOtherSet
308  *
309  *
310  * @param rOtherSet
311  * Set of elements to insert
312  */
313  virtual void InsertSet(const TBaseSet& rOtherSet);
314 
315 
316  /**
317  * Test existence of element
318  *
319  * @param rElem
320  * Element to test
321  *
322  * @return
323  * True if element exists in set
324  */
325  bool Exists(const T& rElem) const;
326 
327  /**
328  * Find element and return iterator.
329  *
330  * @param rElem
331  * Element to find
332  *
333  * @return
334  * Iterator to element or End() if nonexistent
335  */
336  Iterator Find(const T& rElem) const;
337 
338  /**
339  * Set union operator
340  *
341  * @return
342  * Union Set
343  */
344  TBaseSet operator+ (const TBaseSet& rOtherSet) const;
345 
346  /**
347  * Set difference operator
348  *
349  * @return
350  * Difference Set
351  */
352  TBaseSet operator- (const TBaseSet& rOtherSet) const;
353 
354  /**
355  * Set intersection operator
356  *
357  * @return
358  * Intersection Set
359  */
360  TBaseSet operator* (const TBaseSet& rOtherSet) const;
361 
362 
363  /** Test for subset */
364  bool operator<= (const TBaseSet& rOtherSet) const;
365 
366  /** Test for superset */
367  bool operator>= (const TBaseSet& rOtherSet) const;
368 
369  /** Order for sorting containers of TBaseSet */
370  bool operator< (const TBaseSet& rOtherSet) const;
371 
372  /** Some validation of deferred copy mechanism (provoke abort)*/
373  void DValid(const std::string& rMessage="") const;
374 
375  /** Detach from extern storage (incl allocation and true copy) */
376  enum DetachMode { SetOnly, AttrIncl };
377  void Detach(DetachMode flag=AttrIncl) const;
378 
379  /** Detach and lock any further reallocation */
380  void Lock(void) const;
381 
382  /**
383  * Iterator class for high-level api to TBaseSet.
384  * This class is derived from STL iterators to additionally provide
385  * a reference of the container to iterate on. This feature
386  * is used to adjust iterators when the actual set gets reallocated due to a Detach()
387  * operation. Inheritance is private to ensure that all high-level api functions maintain
388  * iteretor refernces consistently. Currently, high-level api iterators support
389  * the operators -&gt; ,*, =, ++, --, ==, !=.
390  *
391  * Technical detail: the private inheritance prohibits the direct use of stl algorithms on
392  * faudes Iterators. If you need direct access to stl algorithms from outside the faudes set
393  * class, you may turn to public inheritance. Make sure to Lock the relevant sets befor
394  * applying any stl algorithms.
395  */
396  class Iterator : private std::set<T,Cmp>::const_iterator {
397  public:
398  /** Default constructor, container unknown */
399  Iterator() :
400  std::set<T,Cmp>::const_iterator() ,
401  pBaseSet(NULL),
402  mAttached(false)
403  {};
404 
405  /** Construct by members (used by TBaseSet to create temporary iterators) */
407  const TBaseSet<T,Cmp>* pBaseSet,
408  const typename std::set<T,Cmp>::const_iterator& sit,
409  bool att=false) :
410  std::set<T,Cmp>::const_iterator(sit),
411  pBaseSet(pBaseSet),
412  mAttached(false)
413  {
414  if(pBaseSet && att) {
415  pBaseSet->AttachIterator(this);
416  mAttached=true;
417  }
418  };
419 
420  /** Copy constructor, copies container reference, incl attach */
421  Iterator(const Iterator& fit) :
422  std::set<T,Cmp>::const_iterator(fit),
423  pBaseSet(fit.pBaseSet),
424  mAttached(false)
425  {
426  if(pBaseSet) {
427  pBaseSet->AttachIterator(this);
428  mAttached=true;
429  }
430  };
431 
432  /** Destructor */
433  ~Iterator(void) {
434  if(mAttached) pBaseSet->DetachIterator(this);
435  };
436 
437  /** report (debugging) */
438  std::string DStr(void) const {
439  std::stringstream rstr;
440  rstr << "[dit base " << pBaseSet << " a" << mAttached << " data " << pBaseSet->pSet;
441  if(pBaseSet) rstr << " elem " << pBaseSet->Str(**this);
442  rstr << "]";
443  return rstr.str();
444  }
445 
446  /** Assigment, tracks container */
447  const Iterator& operator= (const Iterator& rSrc) {
448 #ifdef FAUDES_DEBUG_CODE
449  if(rSrc.pBaseSet==NULL) {
450  FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator= invalid iterator: no baseset");
451  abort();
452  }
453 #endif
454  // performance relevant std case
455  if(mAttached) if(pBaseSet==rSrc.pBaseSet) {
456  std::set<T,Cmp>::const_iterator::operator= (rSrc);
457  return *this;
458  }
459  // general case
460  if(mAttached) pBaseSet->DetachIterator(this);
461  std::set<T,Cmp>::const_iterator::operator= (rSrc);
462  pBaseSet = rSrc.pBaseSet;
463  if(pBaseSet) {
464  pBaseSet->AttachIterator(this);
465  mAttached=true;
466  } else {
467  mAttached=false;
468  }
469  return *this;
470  };
471 
472  /** Assign STL iterator only */
473  void StlIterator(const typename std::set<T,Cmp>::const_iterator& sit) {
474  std::set<T,Cmp>::const_iterator::operator= (sit);
475  };
476 
477  /** Get STL iterator only */
478  const typename std::set<T,Cmp>::const_iterator& StlIterator(void) const {
479  return *this;
480  };
481 
482  /** Invalidate */
483  void Invalidate(void) {
484  pBaseSet=NULL;
485  mAttached=false;
486  };
487 
488  /** Detach */
489  void Detach(void) {
490  mAttached=false;
491  };
492 
493 
494  /** Check validity (provoke abort error) */
495  void DValid(void) const {
496  if(pBaseSet==NULL) {
497  FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):DValid(): invalid iterator: no baseset");
498  abort();
499  }
500  pBaseSet->DValid("Iterator");
501  };
502 
503  /** Reimplement dereference */
504  const T* operator-> (void) const {
505 #ifdef FAUDES_DEBUG_CODE
506  if(pBaseSet==NULL) {
507  FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator->: invalid iterator: no baseset");
508  abort();
509  }
510 #endif
511  return std::set<T,Cmp>::const_iterator::operator-> ();
512  };
513 
514  /** Reimplement derefernce */
515  const T& operator* (void) const {
516 #ifdef FAUDES_DEBUG_CODE
517  if(pBaseSet==NULL) {
518  FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator*: invalid iterator: no baseset");
519  abort();
520  }
521 #endif
522  return std::set<T,Cmp>::const_iterator::operator* ();
523  };
524 
525  /** Reimplement == */
526  bool operator== (const Iterator& rOther) const {
527 #ifdef FAUDES_DEBUG_CODE
528  if(pBaseSet==NULL) {
529  FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator==: invalid iterator: no baseset");
530  abort();
531  }
532 #endif
533  return *static_cast< const typename std::set<T,Cmp>::const_iterator *>(this) == rOther;
534  };
535 
536  /** Reimplement != */
537  bool operator!= (const Iterator& rOther) const {
538 #ifdef FAUDES_DEBUG_CODE
539  if(pBaseSet==NULL) {
540  FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator!=: invalid iterator: no baseset");
541  abort();
542  }
543 #endif
544  return *static_cast< const typename std::set<T,Cmp>::const_iterator *>(this) != rOther;
545  };
546 
547  /** Reimplement postfix ++ */
548  Iterator operator++ (int step) {
549 #ifdef FAUDES_DEBUG_CODE
550  if(pBaseSet==NULL) {
551  FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator++: invalid iterator: no baseset");
552  abort();
553  }
554 #endif
555  Iterator old(pBaseSet,*this, true); // (tmoor 201308: very tricky issue in "erase(it++)" construct)
556  std::set<T,Cmp>::const_iterator::operator++ (step);
557  return old;
558  };
559 
560  /** Reimplement prefix ++ */
561  const Iterator& operator++ (void) {
562 #ifdef FAUDES_DEBUG_CODE
563  if(pBaseSet==NULL) {
564  FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator++: invalid iterator: no baseset");
565  abort();
566  }
567 #endif
568  std::set<T,Cmp>::const_iterator::operator++ ();
569  return *this;
570  };
571 
572  /** Reimplement postfix -- */
573  Iterator operator-- (int step) {
574 #ifdef FAUDES_DEBUG_CODE
575  if(pBaseSet==NULL) {
576  FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator--: invalid iterator: no baseset");
577  abort();
578  }
579 #endif
580  Iterator old(pBaseSet, *this, true);
581  std::set<T,Cmp>::const_iterator::operator-- (step);
582  return old;
583  };
584 
585  /** Reimplement prefix -- */
586  const Iterator& operator-- (void) {
587 #ifdef FAUDES_DEBUG_CODE
588  if(pBaseSet==NULL) {
589  FD_ERR("TBaseSet<T,Cmp>::Iterator(" << this << "):operator--: invalid iterator: no baseset");
590  abort();
591  }
592 #endif
593  std::set<T,Cmp>::const_iterator::operator-- ();
594  return *this;
595  };
596 
597 
598  /** Order by reference for containers of Iterators < */
599  /*
600  bool operator< (const Iterator& rOther) const {
601  return this < &rOther;
602  };
603  */
604 
605  /** Maintaine container reference */
607 
608  /** Indicate that this iterator is attached to some baseset */
609  bool mAttached;
610  };
611 
612 #ifdef DONT_TRACK_REFERENCES
613 
614  /**
615  * Iterator class for high-level api to TBaseSet.
616  * This version is a dummy and does not provide any additional features.
617  */
618  class Iterator : public std::set<T,Cmp>::const_iterator {
619  public:
620 
621  /** Default contructor */
622  Iterator(void) :
623  std::set<T,Cmp>::const_iterator()
624  {};
625 
626  /** Copy constructor */
627  Iterator(const Iterator& fit) :
628  std::set<T,Cmp>::const_iterator(fit)
629  {};
630 
631  /** Copy constructor */
632  Iterator(const typename std::set<T,Cmp>::const_iterator& sit) :
633  std::set<T,Cmp>::const_iterator(sit)
634  {};
635 
636  /** Copy constructor, compatibility */
637  Iterator(
638  const TBaseSet<T,Cmp>* pBaseSet,
639  const typename std::set<T,Cmp>::const_iterator& sit) :
640  std::set<T,Cmp>::const_iterator(sit)
641  {};
642 
643  /** Assign STL iterator only, compatibility */
644  void StlIterator(const typename std::set<T,Cmp>::const_iterator& sit) {
645  std::set<T,Cmp>::const_iterator::operator= (sit);
646  };
647 
648  /** Get STL iterator only, compatibility */
649  const typename std::set<T,Cmp>::const_iterator& StlIterator(void) const {
650  return *this;
651  };
652 
653  /** Invalidate, compatibility */
654  void Invalidate(void) {};
655 
656  };
657 
658 #endif
659 
660 
661  /**
662  * Attribute typeinfo.
663  * This virtual function provides an interface for derived container classes with attributes
664  * eg TaIndexSet. When not re-implemented, it returns an attribute with type AttributeVoid to
665  * indicate the absence of nontrivial attributes
666  */
667  virtual const AttributeVoid* AttributeType(void) const;
668 
669  /**
670  * Attribute typeinfo.
671  * This virtual function provides an interface for derived classes with attributes eg TaIndexSet.
672  * It tests whether this set accepts the specified attribute type ie whether it can be casted.
673  * The test is performned by the Cast function of the attribute type returned by AttributeType().
674  * @param rAttr
675  * Attribute type to test.
676  * @return True, if attribute type is accepted.
677  */
678  virtual bool AttributeTest(const Type& rAttr) const;
679 
680  /**
681  * Attribute access.
682  * This virtual function provides an interface for derived classes with attributes eg TaIndexSet.
683  * The current implementation uses the DoAssign method and clears any attributes afterwards.
684  * Future implementations may be more efficient.
685  *
686  * @param rSourceSet
687  * Set to copy from
688  */
689  virtual TBaseSet& AssignWithoutAttributes(const TBaseSet& rSourceSet);
690 
691  /**
692  * Attributes access.
693  * This virtual function provides an interface for derived classes with attributes eg TaIndexSet.
694  * It copies attributes from the specified set, provided that they can be casted appropriately.
695  * Elements of this set which are not in rOtherSet maintain their attribute.
696  *
697  * @param rOtherSet
698  * Other BaseSet
699  * @exception Exception
700  * - Cannot cast attribute type (63)
701  */
702  virtual void Attributes(const TBaseSet& rOtherSet);
703 
704 
705 
706  /**
707  * Attribute access.
708  * This virtual function provides an interface for derived classes with attributes eg TaIndexSet.
709  * Provide the number of explicit attributes.
710  * The TBaseSet itself has no attributes and thus this function returns 0.
711  */
712  Idx AttributesSize(void) const;
713 
714  /**
715  * Attribute access.
716  * This virtual function provides an interface for derived classes with attributes eg TaIndexSet.
717  * The TBaseSet itself has no attributes and thus this function does nothing.
718  */
719  void ClearAttributes(void);
720 
721  /**
722  * Attribute access.
723  * Test whether attributes match with other set,
724  * and return true if attributes match for shared elements. It uses
725  * the equality test of individual attributes and, hence, requires the attribute type
726  * match too.
727  * @param rOtherSet
728  * Other set to compare with.
729  * @return
730  * True on match.
731  */
732  bool EqualAttributes(const TBaseSet& rOtherSet) const;
733 
734  /**
735  * Attribute access.
736  * This virtual function provides an interface for derived classes with attributes eg TaIndexSet.
737  * The TBaseSet has no attributes and thus throws an exception.
738  * Derived classes that provide attributes are meant to return a pointer to the attribute specified by rElem.
739  *
740  * @param rElem
741  * Element of which the attribute is requested
742  * @return
743  * Attribute of specified element
744  * @exception Exception
745  * - No attributes provided (id 63)
746  */
747  virtual AttributeVoid* Attributep(const T& rElem);
748 
749  /**
750  * Attribute access.
751  * This virtual function provides an interface for derived classes with attributes eg TaIndexSet.
752  * The TBaseSet has no attributes and thus returns a void attribute.
753  * Derived classes that provide attributes are meant to return the attribute specified by rElem.
754  * @param rElem
755  * Element of which the attribute is requested
756  * @return
757  * Attribute of specified element
758  */
759  virtual const AttributeVoid& Attribute(const T& rElem) const;
760 
761  /**
762  * Attribute access.
763  * This virtual function provides an interface for derived classes with attributes eg TaIndexSet.
764  * The TBaseSet itself has void attributes and thus formally accepts any nontrivial attribute,
765  * however, ignoring any value.
766  * Derived classes that provide attributes are meant to set the attribute as specified. Only if the
767  * required cast to the actual attribute type fails an exception is thrown.
768  * @param rElem
769  * Element of which the attribute is to be set
770  * @param rAttr
771  * Attribute value to set.
772  * @exception Exception
773  * - Element does not exist (60)
774  * - Cannot cast attribute type (63)
775  */
776  virtual void Attribute(const T& rElem, const Type& rAttr);
777 
778  /**
779  * Attribute access.
780  * This virtual function provides an interface for derived classes with attributes eg TaIndexSet.
781  * It is meant to try to set the attribute as specified if the type can be casted. Otherwise it does nothing.
782  * @param rElem
783  * Element of which the attribute is to be set
784  * @param rAttr
785  * Attribute value to set.
786  */
787  virtual void AttributeTry(const T& rElem, const Type& rAttr) { (void) rElem; (void) rAttr; };
788 
789  /**
790  * Attribute access.
791  * Cleras an explicit attribute associated with the specified element if sucht attribute exists.
792  * The TBaseSet itself has no attributes and thus this function will do nothing.
793  * @param rElem
794  * Element of which the attribute is to be cleared
795  */
796  virtual void ClrAttribute(const T& rElem);
797 
798  /**
799  * Configure the element name tag.
800  * This method allows to overwrite the tag used for elements
801  * in XML IO. For usual, you will register derived class with
802  * the run-time-interface and set the elemen tag for XML IO.
803  *
804  * @param rTag
805  * Name to set
806  */
807  virtual void XElementTag(const std::string& rTag);
808 
809  /**
810  * Get objects's type name.
811  *
812  * Retrieve the faudes-type name from the type registry.
813  * Sets allow to overwrite the faudes-type identifier. This is allows
814  * for light-weight derived classes that do not need to be registered.
815  *
816  * @return
817  * Faudes-type name or empty string.
818  */
819  virtual const std::string& TypeName(void) const;
820 
821  /**
822  * Overwrite faudes-type name.
823  * This method is used to overwrite the faudes-type identifyer.
824  *
825  * @param rType
826  * Faudes-type name to set
827  */
828  virtual void TypeName(const std::string& rType);
829 
830 
831 
832 
833 protected:
834 
835 
836  /**
837  * Token output, see Type::DWrite for public wrappers.
838  * Reimplement this function in derived classes for specific
839  * specific template parameters. By convention, the default label ""
840  * should be translated to a) the name of the set or b) some meaningful default,
841  * eg "IndexSet" for a set of indices. The pContext pointer can de type-checked
842  * and interpreted, ie as a symboltable to provide symbolic names. It is also
843  * passed on to attributes.
844  *
845  * @param rTw
846  * Reference to TokenWriter
847  * @param rLabel
848  * Label of section to write, defaults to name of set
849  * @param pContext
850  * Write context to provide contextual information
851  */
852  virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="", const Type* pContext=0) const;
853 
854  /**
855  * Token output, debugging see Type::DWrite for public wrappers.
856  * Reimplement this function in derived classes for specific
857  * specific template parameters.
858  * @param rTw
859  * Reference to TokenWriter
860  * @param rLabel
861  * Label of section to write, defaults to name of set
862  * @param pContext
863  * Write context to provide contextual information
864  */
865  virtual void DoDWrite(TokenWriter& rTw,const std::string& rLabel="", const Type* pContext=0) const;
866 
867  /**
868  * Token output, see Type::SWrite for public wrappers.
869  * Statistics include size, name and attributey type. The latter
870  * is retrieved from the RTI, if initialized. Dereived sets may reimplement
871  * this method.
872  *
873  * @param rTw
874  * Reference to TokenWriter
875  */
876  virtual void DoSWrite(TokenWriter& rTw) const;
877 
878  /**
879  * Token input, see Type::Read for public wrappers.
880  * Reimplement this function in derived classes for specific
881  * specific template parameters.
882  * By convention, the default label "" should be translated to some meaningful default,
883  * eg "IndexSet" for a set of indices". The pContext pointer can de type-checked
884  * and interpreted, ie as a symboltable to provide symbolic names. It is also
885  * passed on to attributes.
886  *
887  * @param rTr
888  * Reference to TokenReader
889  * @param rLabel
890  * Label of section to read, defaults to name of set
891  * @param pContext
892  * Read context to provide contextual information
893  */
894  virtual void DoRead(TokenReader& rTr, const std::string& rLabel = "", const Type* pContext=0);
895 
896  /** assign my members */
897  void DoAssign(const TBaseSet& rSourceSet);
898 
899  /** test equality */
900  bool DoEqual(const TBaseSet& rOtherSet) const;
901 
902 
903  /** set attribute in map (assume elem exists in set, NULL <=> set to default) */
904  void DoAttribute(const T& rElem, const Type* pAttr);
905 
906  /** get attribute from map (return null if elem does not exist in map) */
907  const AttributeVoid* DoAttribute(const T& rElem) const;
908 
909  /** get attribute from map (insert explicit default if elem does not exist in map) */
911 
912 protected:
913 
914 
915  /** Name of this BaseSet */
916  std::string mMyName;
917 
918  /** Pointer on STL set to operate on */
919  std::set<T,Cmp>* pSet;
920 
921  /** STL set, if this object hosts data (else NULL) */
922  std::set<T,Cmp>* mpSet;
923 
924  /** STL iterator, non-const version */
925  typedef typename std::set<T,Cmp>::iterator iterator;
926 
927  /** STL iterator, const version */
928  typedef typename std::set<T,Cmp>::const_iterator const_iterator;
929 
930  /** Convert STL iterator to API iterator*/
931  typename TBaseSet<T,Cmp>::Iterator ThisIterator(const typename std::set<T,Cmp>::const_iterator& sit) const;
932 
933 
934 
935  /** Pointer to attribute map to operate on */
936  std::map<T,AttributeVoid*>* pAttributes;
937 
938  /** Attribute map, if this object hosts data (else NULL). */
939  std::map<T,AttributeVoid*>* mpAttributes;
940 
941  /** STL attribute iterator, non-const version */
942  typedef typename std::map<T,AttributeVoid*>::iterator aiterator;
943 
944  /** STL attribute iterator, const version */
945  typedef typename std::map<T,AttributeVoid*>::const_iterator const_aiterator;
946 
947 
948 
949 
950  /** Pointer on BaseSet that hosts our data (THIS if we host) */
952 
953  /** Iterator to the client list that hosts our data (maintained by host)*/
954  typename std::list< TBaseSet<T,Cmp>* >::iterator mClientRecord;
955 
956  /** BaseSets, that use data hosted by us (NULL if we dont host data, emptyset if we host to ourself excl.) */
957  std::list< TBaseSet<T,Cmp>* >* mpClients;
958 
959  /** Indicate "hosts data to myself only" */
960  bool mDetached;
961 
962  /** Indicate "dont re-allocate the STL set ever again" */
963  bool mLocked;
964 
965  /** Ensure that we do not host contents to anyone else */
966  void RelinkClients(void);
967 
968  /** Record that we provide contents to some other BaseSet */
969  void AttachClient(TBaseSet* pRef) const;
970 
971  /** Record that we stop providing data for some TBaseSet */
972  void DetachClient(TBaseSet* pRef) const;
973 
974  /** Iterators that refer to this TBaseSet */
975  std::set< Iterator* > mIterators;
976 
977  /** Record that an iterator refers to this TBaseSet */
978  void AttachIterator(Iterator* pFit) const;
979 
980  /** Record that an iterator stops to refer to this TBaseSet */
981  void DetachIterator(Iterator* pFit) const;
982 
983 
984 
985  /** Reimplment from type to use chache */
986  virtual const TypeDefinition* TypeDefinitionp(void) const;
987 
988  /** Get name of elements (used for XML IO) */
989  virtual const std::string& XElementTag(void) const;
990 
991  /** static empty STL set for default constructor */
992  static std::set<T,Cmp> msEmptySet;
993 
994  /** static empty STL map for default constructor */
995  static std::map<T,AttributeVoid*> msEmptyAttributes;
996 
997  /** static empty STL client list */
998  // std::list< TBaseSet<T,Cmp>* >* msEmptyClients;
999 
1000 private:
1001 
1002  /** TypeDefinition cache (should use guarded pointer here) */
1004 
1005  /** Current/cached faudes type-name */
1006  std::string mFaudesTypeName;
1007 
1008  /** Current/cached name of elements (use protected accessor methods for caching) */
1009  std::string mXElementTag;
1010 
1011 protected:
1012 
1013  /** Defauft name of elements (if not over written by registry) */
1014  std::string mXElementTagDef;
1015 
1016 
1017 };
1018 
1019 
1020 
1021 /*
1022  * Set union, rti wrapper
1023  *
1024  * @param rSetA
1025  * Set A
1026  * @param rSetB
1027  * Set B
1028  * @return
1029  * Union of set A and set B
1030  */
1031 
1032 template<class T, class Cmp>
1033 void SetUnion(const TBaseSet<T,Cmp>& rSetA, const TBaseSet<T,Cmp>& rSetB, TBaseSet<T,Cmp>& rRes) {
1034  FD_DC("FAUDES_DEBUG_CONTAINER: SetUnion(TBaseSet<T,Cmp>): res at " << &rRes);
1035  // fix name
1036  std::string name=CollapsString(rSetA.Name() + "+" + rSetB.Name());
1037  // all the same
1038  if(&rSetA==&rSetB && &rSetA==&rRes) {rRes.Name(name); return;}
1039  // a and b ths same, res different
1040  if(&rSetA==&rSetB) {rRes.Assign(rSetA); rRes.Name(name); return;}
1041  // a and res the same, b different
1042  if(&rSetA==&rRes) {rRes.InsertSet(rSetB); rRes.Name(name); return;};
1043  // b and res the same, a different
1044  if(&rSetB==&rRes) {rRes.InsertSet(rSetA); rRes.Name(name); return;};
1045  // else
1046  rRes.Assign(rSetA);
1047  rRes.InsertSet(rSetB);
1048  rRes.Name(name);
1049  FD_DC("FAUDES_DEBUG_CONTAINER: SetUnion(TBaseSet<T,Cmp>): done, res at " << &rRes << " #" << rRes.Size());
1050 }
1051 
1052 /*
1053  * Set intersection, rti wrapper
1054  *
1055  * @param rSetA
1056  * Set A
1057  * @param rSetB
1058  * Set B
1059  * @return
1060  * Set A intersected with set B
1061  */
1062 template< class T, class Cmp >
1063 void SetIntersection(const TBaseSet<T,Cmp>& rSetA, const TBaseSet<T,Cmp>& rSetB, TBaseSet<T,Cmp>& rRes) {
1064  // fix name
1065  std::string name=CollapsString(rSetA.Name() + "*" + rSetB.Name());
1066  // all the same
1067  if(&rSetA==&rSetB && &rSetA==&rRes) {rRes.Name(name); return;}
1068  // a and b ths ame, res different
1069  if(&rSetA==&rSetB) { rRes.Assign(rSetA); rRes.Name(name); return;}
1070  // a and res the same, b different
1071  if(&rSetA==&rRes) {rRes.RestrictSet(rSetB); rRes.Name(name); return;};
1072  // b and res the same, a different
1073  if(&rSetB==&rRes) {rRes.RestrictSet(rSetA); rRes.Name(name); return;};
1074  // else
1075  rRes.Assign(rSetA);
1076  rRes.RestrictSet(rSetB);
1077  rRes.Name(name);
1078 }
1079 
1080 
1081 /*
1082  * Set difference, rti wrapper
1083  *
1084  * @param rSetA
1085  * Set A
1086  * @param rSetB
1087  * Set B
1088  * @return
1089  * Set A minus set B
1090  */
1091 template< class T, class Cmp >
1092 void SetDifference(const TBaseSet<T,Cmp>& rSetA, const TBaseSet<T,Cmp>& rSetB, TBaseSet<T,Cmp>& rRes) {
1093  // fix name
1094  std::string name=CollapsString(rSetA.Name() + "-" + rSetB.Name());
1095  // a and b the same
1096  if(&rSetA==&rSetB) { rRes.Clear(); rRes.Name(name); return;}
1097  // a and res the same, b different
1098  if(&rSetA==&rRes) {rRes.EraseSet(rSetB); rRes.Name(name); return;};
1099  // b and res the same, a different ... need buffer?
1100  if(&rSetB==&rRes) {
1101  TBaseSet<T,Cmp>* buffb=rSetB.Copy();
1102  rRes.Assign(rSetA);
1103  rRes.EraseSet(*buffb);
1104  rRes.Name(name);
1105  delete buffb;
1106  return;
1107  };
1108  // else: std
1109  rRes.Assign(rSetA);
1110  rRes.EraseSet(rSetB);
1111  rRes.Name(name);
1112 }
1113 
1114 /*
1115  * Set equality, rti wrapper
1116  * This method ignores attributes.
1117  *
1118  * @param rSetA
1119  * Set A
1120  * @param rSetB
1121  * Set B
1122  * @return
1123  * True for matching sets.
1124  */
1125 template< class T, class Cmp >
1126 bool SetEquality(const TBaseSet<T,Cmp>& rSetA, const TBaseSet<T,Cmp>& rSetB) {
1127  return rSetA==rSetB;
1128 }
1129 
1130 /*
1131  * Set inclusion, rti wrapper
1132  * This method ignores attributes.
1133  *
1134  * @param rSetA
1135  * Set A
1136  * @param rSetB
1137  * Set B
1138  * @return
1139  * True for matching sets.
1140  */
1141 template< class T, class Cmp >
1142 bool SetInclusion(const TBaseSet<T,Cmp>& rSetA, const TBaseSet<T,Cmp>& rSetB) {
1143  return rSetA<=rSetB;
1144 }
1145 
1146 
1147 
1148 
1149 
1150 
1151 
1152 /*
1153 ******************************************************************************************
1154 ******************************************************************************************
1155 ******************************************************************************************
1156 
1157 Implementation of TBaseSet
1158 
1159 ******************************************************************************************
1160 ******************************************************************************************
1161 ******************************************************************************************
1162 */
1163 
1164 /* convenience access to relevant scopes */
1165 #define THIS TBaseSet<T,Cmp>
1166 #define TEMP template<class T, class Cmp>
1167 #define BASE Type
1168 
1169 
1170 // faudes type std: new and cast
1174 
1175 // faudes type std: assignemnt (break cast)
1176 //TEMP THIS& THIS::Assign(const Type& rSrc) { this->Clear(); return *this;};
1177 //TEMP THIS& THIS::Assign(const THIS& rSrc) { DoAssign(rSrc); return *this;};
1178 
1179 // faudes type std: assignemnt (keep cast)
1182 
1183 
1184 // template statics: empty set
1185 TEMP std::set<T,Cmp> THIS::msEmptySet=std::set<T,Cmp>();
1186 TEMP std::map<T,AttributeVoid*> THIS::msEmptyAttributes=std::map<T,AttributeVoid*>();
1187 
1188 // TBaseSet()
1189 TEMP THIS::TBaseSet(void) :
1190  Type(),
1191  pSet(&msEmptySet),
1192  mpSet(NULL),
1193  pAttributes(&msEmptyAttributes),
1194  mpAttributes(NULL),
1195  pHostSet(this),
1196  mpClients(new std::list< TBaseSet<T,Cmp>* >),
1197  mDetached(false),
1198  mLocked(false),
1199  pTypeDefinition(NULL),
1200  mXElementTagDef("Element")
1201 {
1202  FAUDES_OBJCOUNT_INC("BaseSet");
1203  FD_DC("TBaseSet(" << this << ")::TBaseSet()");
1204  // other members
1205  mMyName="BaseSet";
1206 }
1207 
1208 // TBaseSet(filename)
1209 TEMP THIS::TBaseSet(const std::string& rFileName, const std::string& rLabel) :
1210  Type(),
1211  pSet(&msEmptySet),
1212  mpSet(NULL),
1213  pAttributes(&msEmptyAttributes),
1214  mpAttributes(NULL),
1215  pHostSet(this),
1216  mpClients(new std::list< TBaseSet<T,Cmp>* >),
1217  mDetached(false),
1218  mLocked(false),
1219  pTypeDefinition(NULL),
1220  mXElementTagDef("Element")
1221 {
1222  FAUDES_OBJCOUNT_INC("BaseSet");
1223  FD_DC("TBaseSet(" << this << ")::TBaseSet()");
1224  // other members
1225  mMyName="BaseSet";
1226  // do read etc ... this is a dummy anyway
1227  Read(rFileName,rLabel);
1228 }
1229 
1230 // TBaseSet(rOtherSet)
1231 TEMP THIS::TBaseSet(const TBaseSet& rOtherSet) :
1232  Type(rOtherSet),
1233  pSet(&msEmptySet),
1234  mpSet(NULL),
1235  pAttributes(&msEmptyAttributes),
1236  mpAttributes(NULL),
1237  pHostSet(this),
1238  mpClients(new std::list< TBaseSet<T,Cmp>* >), // small detour ... for readability
1239  mDetached(false),
1240  mLocked(false),
1241  pTypeDefinition(NULL),
1242  mXElementTagDef("Element")
1243 {
1244  FAUDES_OBJCOUNT_INC("BaseSet");
1245  FD_DC("TBaseSet(" << this << ")::TBaseSet(rOtherSet " << &rOtherSet << "): fake copy construct");
1246  // run assignment
1247  DoAssign(rOtherSet);
1248 #ifdef FAUDES_DEBUG_CODE
1249  DValid("CopyConstruct");
1250 #endif
1251 }
1252 
1253 // destructor
1254 TEMP THIS::~TBaseSet(void) {
1255  FAUDES_OBJCOUNT_DEC("BaseSet");
1256  FD_DC("TBaseSet(" << this << ")::~TBaseSet()");
1257  // maintain deferred copy
1258  RelinkClients();
1259  pHostSet->DetachClient(this);
1260  if(mpClients) delete mpClients;
1261  mpClients=NULL;
1262  // unlink iterators (mandatory, since referenced object will be destructed)
1263  typename std::set< Iterator* >::const_iterator iit;
1264  for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1265  (**iit).Invalidate();
1266  }
1267  // delete if we still own data
1268  if(mpSet) delete mpSet;
1269  if(mpAttributes) {
1270  for(aiterator ait=mpAttributes->begin(); ait!=mpAttributes->end(); ++ait)
1271  delete ait->second;
1272  delete mpAttributes;
1273  }
1274 }
1275 
1276 
1277 // fake copy
1278 TEMP void THIS::DoAssign(const THIS& rSourceSet) {
1279  FD_DC("TBaseSet(" << this << "/" << this->Name() << ")::DoAssign(rOtherSet " << &rSourceSet << "): shallow copy -- src attr# " << rSourceSet.pAttributes->size());
1280  FD_DC("TBaseSet():DoAssign(): " << typeid(*this->AttributeType()).name() << " <== " << typeid(*rSourceSet.AttributeType()).name());
1281  // bail out on selfref
1282  if(this==&rSourceSet) return;
1283  // other members
1284  mMyName=rSourceSet.mMyName;
1285  // bail out on common shared data
1286  if(pHostSet==rSourceSet.pHostSet) return;
1287  // become independant
1288  RelinkClients();
1289  pHostSet->DetachClient(this);
1290  // delete own old data
1291  if(mpSet) {
1292  delete mpSet;
1293  mpSet=NULL;
1294  }
1295  if(mpAttributes) {
1296  for(aiterator ait=mpAttributes->begin(); ait!=mpAttributes->end(); ++ait)
1297  delete ait->second;
1298  delete mpAttributes;
1299  mpAttributes=NULL;
1300  }
1301  if(mpClients) {
1302  delete mpClients;
1303  mpClients=NULL;
1304  }
1305 
1306  // if attribute type matches, use source as host
1307  if(typeid(*rSourceSet.AttributeType())==typeid(*this->AttributeType())) {
1308  pHostSet=rSourceSet.pHostSet;
1309  pHostSet->AttachClient(this);
1310  pSet=rSourceSet.pSet;
1311  pAttributes=rSourceSet.pAttributes;
1312  }
1313  // else do a deep copy (avoid mixed typed attributeb maps)
1314  else {
1315  mpSet = new std::set<T,Cmp>();
1316  *mpSet = *rSourceSet.pSet;
1317  pSet = mpSet;
1318  mpAttributes = new std::map<T,AttributeVoid*>();
1319  if(typeid(*this->AttributeType()) != typeid(const AttributeVoid)) {
1320  for(aiterator ait=rSourceSet.pAttributes->begin(); ait!=rSourceSet.pAttributes->end(); ++ait) {
1321  AttributeVoid* attr= ait->second->Copy();
1322  (*mpAttributes)[ait->first]=attr;
1323  }
1324  }
1325  pAttributes = mpAttributes;
1326  pHostSet = this;
1327  }
1328  // fix iterators (invalidate)
1329  typename std::set< Iterator* >::iterator iit;
1330  for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1331  (**iit).Invalidate();
1332  }
1333  mIterators.clear();
1334  // record state
1335  mDetached=false;
1336  // if we were locked, relock (i.e. do the copy)
1337  if(mLocked) {
1338  mLocked=false;
1339  Lock();
1340  };
1341 #ifdef FAUDES_DEBUG_CODE
1342  DValid("PostFakeAssignment");
1343 #endif
1344  FD_DC("TBaseSet(" << this << ")::DoAssign(rOtherSet " << &rSourceSet << "): fake copy -- done with attr# " << pAttributes->size());
1345 }
1346 
1347 // Detach()
1348 TEMP void THIS::Detach(DetachMode flag) const {
1349  FD_DC("TBaseSet(" << this << ")::Detach(void)");
1350 #ifdef FAUDES_DEBUG_CODE
1351  DValid("PreDetach");
1352 #endif
1353 
1354  // clear attributes for consistent behaviour
1355  if(mDetached) {
1356  if(flag==SetOnly) pAttributes->clear();
1357  return;
1358  }
1359 
1360  // provide fake const
1361  THIS* fake_const = const_cast< THIS* >(this);
1362 
1363 #ifdef FAUDES_DEBUG_CODE
1364  // might have missed reference detach
1365  if(pHostSet==this)
1366  if(pSet!=&msEmptySet)
1367  if(mpClients)
1368  if(mpClients->empty()) {
1369  FD_ERR("TBaseSet(" << this << ")::Detach(): missed detach (?)");
1370  abort(); // strict
1371  fake_const->mDetached=true; // fix
1372  }
1373 #endif
1374 
1375  // prepare: construct a copy of my data -- the set
1376  std::set<T,Cmp>* scopy = new std::set<T,Cmp>();
1377  *scopy = *pSet;
1378 
1379  // prepare: construct a copy of my data -- the attribute map (optional)
1380  std::map<T,AttributeVoid*>* acopy = new std::map<T,AttributeVoid*>();
1381  if(flag==AttrIncl) {
1382  for(aiterator ait=pAttributes->begin(); ait!=pAttributes->end(); ++ait) {
1383  AttributeVoid* attr= ait->second->Copy();
1384  (*acopy)[ait->first]=attr;
1385  }
1386  }
1387 
1388  // stragie A: clients get the new copy; thus, the baseset data does
1389  // not get reallocated and we dont need to track iterators; on the
1390  // downside, fixing the references iterators may be more effort.
1391  if(mLocked==true) {
1392 
1393  FD_DC("TBaseSet(" << this << ")::Detach(): allocate and copy, strategie A");
1394  // first of my clients gets the new data
1395  THIS* newhost = *mpClients->begin();
1396 #ifdef FAUDES_DEBUG_CODE
1397  if(newhost->mpClients)
1398  FD_ERR("TBaseSet(" << this << ")::Detach(): new host used to heve clients (?)");
1399 #endif
1400  newhost->pHostSet=newhost;
1401  newhost->mpSet=scopy;
1402  newhost->pSet=scopy;
1403  newhost->mpAttributes=acopy;
1404  newhost->pAttributes=acopy;
1405  newhost->mpClients=mpClients;
1406  newhost->DetachClient(newhost);
1407  // set other users to use the new host
1408  typename std::list< THIS* >::const_iterator rit;
1409  for(rit=newhost->mpClients->begin();rit!=newhost->mpClients->end(); ++rit) {
1410  (*rit)->pHostSet=newhost;
1411  (*rit)->pSet=newhost->pSet;
1412  (*rit)->pAttributes=newhost->pAttributes;
1413  }
1414  // fix newhost clients iterators
1415  typename std::set< Iterator* >::iterator iit;
1416  for(rit=newhost->mpClients->begin(); rit!=newhost->mpClients->end(); ++rit) {
1417  for(iit=(*rit)->mIterators.begin(); iit!=(*rit)->mIterators.end(); ++iit) {
1418  if((**iit).StlIterator()==pSet->end())
1419  **iit=Iterator(this, scopy->end());
1420  else
1421  **iit=Iterator(this, scopy->find(***iit));
1422  }
1423  }
1424  // fix newhost iterators
1425  for(iit=newhost->mIterators.begin(); iit!=newhost->mIterators.end(); ++iit) {
1426  if((**iit).StlIterator()==pSet->end())
1427  **iit=Iterator(this, scopy->end());
1428  else
1429  **iit=Iterator(this, scopy->find(***iit));
1430  }
1431  // make myself own the old data
1432  fake_const->mpSet=pSet;
1433  fake_const->mpAttributes=pAttributes;
1434  fake_const->mpClients= new std::list< TBaseSet<T,Cmp>* >;
1435  fake_const->mDetached=true;
1436  // stop tracking my iterators
1437  for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit)
1438  (**iit).Detach();
1439  fake_const->mIterators.clear();
1440 
1441 
1442  // stragie B: this baseset gets the copy; thus, the clients iterators
1443  // remain valid and dont need to be fixed; on the downside, we need to
1444  // continue to track our iterators.
1445  } else {
1446 
1447  FD_DC("TBaseSet(" << this << ")::Detach(): allocate and copy, strategie B");
1448  // make someone else handle original data
1449  fake_const->RelinkClients();
1450  pHostSet->DetachClient(fake_const);
1451  // own the copied data
1452  fake_const->mpSet = scopy;
1453  fake_const->mpAttributes=acopy;
1454  // fix my iterators
1455  typename std::set< Iterator* >::iterator iit;
1456  for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1457  if((**iit).StlIterator()==pSet->end())
1458  **iit=Iterator(this, mpSet->end());
1459  else
1460  **iit=Iterator(this, mpSet->find(***iit));
1461  }
1462  // record myself as my newhost
1463  fake_const->pHostSet=fake_const;
1464  fake_const->pSet=mpSet;
1465  fake_const->pAttributes=mpAttributes;
1466  fake_const->mDetached=true;
1467  if(fake_const->mpClients) delete fake_const->mpClients; // memeory leak fixed 20121004
1468  fake_const->mpClients= new std::list< TBaseSet<T,Cmp>* >;
1469  }
1470 
1471 
1472 #ifdef FAUDES_DEBUG_CODE
1473  DValid("PostDetach");
1474 #endif
1475  FD_DC("TBaseSet(" << this << ")::Detach(): done");
1476 }
1477 
1478 // Lock()
1479 TEMP void THIS::Lock(void) const {
1480  FD_DC("TBaseSet(" << this << ")::Lock(void)");
1481 #ifdef FAUDES_DEBUG_CODE
1482  DValid("PreLock");
1483 #endif
1484  // if we are locked: fine
1485  if(mLocked) return;
1486 
1487  // trigger actual copy (this set getting the copy)
1488  Detach(AttrIncl);
1489 
1490  // provide fake const
1491  THIS* fake_const = const_cast< THIS* >(this);
1492 
1493  // stop tracking iterators
1494  typename std::set< Iterator* >::const_iterator iit;
1495  for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1496  (**iit).Detach();
1497  }
1498  fake_const->mIterators.clear();
1499 
1500  // stop detach from reallocating
1501  fake_const->mLocked=true;
1502 
1503 #ifdef FAUDES_DEBUG_CODE
1504  DValid("PostLock");
1505 #endif
1506 }
1507 
1508 
1509 // if i am a host to others, make someone else the host
1510 TEMP inline void THIS::RelinkClients(void) {
1511  FD_DC("TBaseSet::RelinkClients(" << this << ")")
1512 #ifdef FAUDES_DEBUG_CODE
1513  DValid("PreRelink");
1514 #endif
1515 
1516  // no clients record, so i dont host any data
1517  if(!mpClients) return;
1518  // empty clients, so i only host to myself
1519  if(mpClients->empty()) return;
1520 
1521  FD_DC("TBaseSet::RelinkClients(" << this << "): doit")
1522 
1523  // make first client the new host
1524  THIS* newhost = *mpClients->begin();
1525 #ifdef FAUDES_DEBUG_CODE
1526  if(newhost->pHostSet!=this)
1527  FD_ERR("BaseSet::RelinkRefernces: old reference must have this as provider");
1528  if(newhost->mpClients)
1529  FD_ERR("TBaseSet(" << this << ")::RelinkClients(void): client is a host (?)");
1530 #endif
1531  newhost->pHostSet=newhost;
1532  newhost->mpSet=mpSet;
1533  newhost->pSet=pSet;
1534  newhost->mpAttributes=mpAttributes;
1535  newhost->pAttributes=pAttributes;
1536  newhost->mpClients=mpClients;
1537  newhost->DetachClient(newhost);
1538  // set other users to new newhost
1539  typename std::list< THIS* >::const_iterator rit;
1540  for(rit=newhost->mpClients->begin();rit!=newhost->mpClients->end(); ++rit) {
1541  (*rit)->pHostSet=newhost;
1542  }
1543  // make myself a reference to the new source
1544  pHostSet=newhost;
1545  pSet=newhost->pSet;
1546  mpSet=NULL;
1547  pAttributes=newhost->pAttributes;
1548  mpAttributes=NULL;
1549  newhost->AttachClient(this);
1550  mpClients=NULL;
1551 #ifdef FAUDES_DEBUG_CODE
1552  DValid("PostRelink");
1553 #endif
1554  FD_DC("TBaseSet::RelinkClients(" << this << "): done")
1555 }
1556 
1557 
1558 // record fake copy
1559 TEMP inline void THIS::AttachClient(TBaseSet* pRef) const {
1560  if(!mpClients) const_cast< THIS* >(this)->mpClients=new std::list< TBaseSet<T,Cmp>* >;
1561  const_cast< THIS* >(this)->mpClients->push_back(pRef);
1562  pRef->mClientRecord= -- mpClients->end();
1563  const_cast< THIS* >(this)->mDetached=false;
1564 }
1565 
1566 // discard fake copy
1567 TEMP inline void THIS::DetachClient(TBaseSet* pRef) const {
1568  FD_DC("TBaseSet::DetachClient(" << this << "):" << pRef);
1569  // bail out on trivials
1570  if(!mpClients) return;
1571  if(mpClients->empty()) return;
1572  if(pRef->pHostSet!=this) return;
1573  // provide fake const
1574  THIS* fake_const = const_cast< THIS* >(this);
1575 #ifdef FAUDES_DEBUG_CODE
1576  // find and remove that client
1577  typename std::list< TBaseSet<T,Cmp>* >::iterator cit;
1578  bool cf=false;
1579  for(cit=fake_const->mpClients->begin(); cit!=fake_const->mpClients->end(); ++cit) {
1580  if(*cit==pRef) cf=true;
1581  }
1582  if(!cf) {
1583  FD_ERR("TBaseSet::DetachClient(" << this << "): client not found " << pRef);
1584  abort();
1585  }
1586 #endif
1587  /*
1588  use recorded client index: performant, and fine when last tested ...
1589  ... however, this really is asking for segfaults.
1590 
1591  // remove from client list
1592  FD_DC("TBaseSet::DetachClient(" << this << "):" << pRef << " must match " << *pRef->mClientRecord);
1593  fake_const->mpClients->erase(pRef->mClientRecord);
1594  */
1595  // remove from client list
1596  typename std::list< TBaseSet<T,Cmp>* >::iterator rit;
1597  for(rit=fake_const->mpClients->begin(); rit!=fake_const->mpClients->end(); ++rit) {
1598  if(*rit!=pRef) continue;
1599  fake_const->mpClients->erase(rit);
1600  break;
1601  }
1602  // figure detached status
1603  if(mpClients->empty() && (pSet!=&msEmptySet)) fake_const->mDetached=true;
1604  FD_DC("TBaseSet::DetachClient(" << this << "): done.");
1605 }
1606 
1607 
1608 // record an iterator
1609 TEMP inline void THIS::AttachIterator(Iterator* pFit) const {
1610  if(mLocked) return;
1611  FD_DC("TBaseSet::AttachIterator(" << this << "):" << pFit)
1612  const_cast< THIS* >(this)->mIterators.insert(pFit);
1613 }
1614 
1615 // discard an iterator
1616 TEMP inline void THIS::DetachIterator(Iterator* pFit) const {
1617  if(mLocked) return;
1618  FD_DC("TBaseSet::DetachIterator(" << this << "):" << pFit)
1619  const_cast< THIS* >(this)->mIterators.erase(pFit);
1620 }
1621 
1622 // test some validity
1623 TEMP void THIS::DValid(const std::string& rMessage) const {
1624  typename std::set< Iterator* >::const_iterator iit;
1625  typename std::list< THIS* >::const_iterator rit;
1626 #ifdef FAUDES_DEBUG_CONTAINER
1627  std::cerr << "TBaseSet(" << this << ")::DValid(): " << rMessage << " source "
1628  << pHostSet << " " << (pHostSet->pSet==&msEmptySet ? "+e+" : "+f+") <<
1629  (mLocked ? " +l+" : " ") << (mDetached ? " +d+" : " ") << " -- refs ";
1630  if(pHostSet->mpClients)
1631  for(rit=pHostSet->mpClients->begin(); rit!=pHostSet->mpClients->end(); ++rit)
1632  std::cerr << *rit << " ";
1633  std::cerr << "-- its ";
1634  for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit)
1635  std::cerr << *iit << " ";
1636  std::cerr << "-- attr #" << pAttributes->size();
1637  if(mpAttributes) std::cerr << "(" << mpAttributes->size() << ") ";
1638  else std::cerr << " ";
1639  std::cerr << (pAttributes==&msEmptyAttributes ? "+e+ " : "+f+ ") << std::endl;
1640 #endif
1641  // iterators, that dont refer to me as basset
1642  for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1643  if((*iit)->pBaseSet!=this) {
1644  FD_WARN("BaseSet("<< this << "," << rMessage <<"): invalid iterator (baseset): "<< *iit);
1645  abort();
1646  }
1647  }
1648  // iterators, that are not marked as attached
1649  for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1650  if(!(*iit)->mAttached) {
1651  FD_WARN("BaseSet("<< this << "," << rMessage <<"): invalid iterator (attached): "<< *iit);
1652  abort();
1653  }
1654  }
1655  // iterators, that are invalid stl iterators
1656  for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1657  typename std::set<T,Cmp>::const_iterator vit;
1658  for(vit=pSet->begin(); vit!= pSet->end(); ++vit) {
1659  if(vit==(**iit).StlIterator()) break;
1660  }
1661  if(vit!=(**iit).StlIterator()) { // end-iterator is fine, too
1662  FD_WARN("BaseSet("<< this << "," << rMessage <<"): invalid iterator (stl) "<< *iit);
1663  (**iit).StlIterator(pSet->end()); // fix invalid iterator to refer to end()
1664  abort(); // strict version: abort
1665  }
1666  }
1667  // must have some base
1668  if(pHostSet==NULL) {
1669  FD_WARN("BaseSet(" << this << "," << rMessage << "): no host found");
1670  abort();
1671  }
1672  // hosts mut be consistent
1673  if(pHostSet->pHostSet != pHostSet) {
1674  FD_WARN("BaseSet(" << this << "," << rMessage << "): inconsistent host");
1675  abort();
1676  }
1677  // refers to other base and own data
1678  if((mpSet!=NULL) && (pHostSet != this)) {
1679  FD_WARN("BaseSet(" << this << "," << rMessage << "): double data");
1680  abort();
1681  }
1682  // refers to other base and has references
1683  if(pHostSet!=this && mpClients!=NULL) {
1684  FD_WARN("BaseSet(" << this << "," << rMessage << "): cannot be client and have clients oneself");
1685  abort();
1686  }
1687  // refers to invalid base
1688  if(pHostSet->mpClients==NULL) {
1689  FD_WARN("BaseSet(" << this << "," << rMessage << "): refers to invalid host (a)");
1690  abort();
1691  }
1692  // refers to invalid base
1693  if(pHostSet!=this && pHostSet->mpClients->empty()) {
1694  FD_WARN("BaseSet(" << this << "," << rMessage << "): refers to invalid host (b)");
1695  abort();
1696  }
1697  // is base but has no own data
1698  if((pHostSet == this) && (mpSet==NULL) && (pSet!=&msEmptySet)) {
1699  FD_WARN("BaseSet(" << this << "," << rMessage << "): no data");
1700  abort();
1701  }
1702  // is base, but has no client list
1703  if((pHostSet==this) && (pSet!=&msEmptySet) && (mpClients==NULL)) {
1704  FD_WARN("BaseSet(" << this << "," << rMessage << "): host with no client list");
1705  abort();
1706  }
1707  // is base but own data pointer mismatch
1708  if((pHostSet == this) && (pSet != mpSet) && (pSet!=&msEmptySet)) {
1709  FD_WARN("BaseSet(" << this << "," << rMessage << "): data pointer mismatch A");
1710  abort();
1711  }
1712  // refers to base with data pointer mismatch
1713  if(pSet != pHostSet->pSet) {
1714  FD_WARN("BaseSet(" << this << "," << rMessage << "): data pointer mismatch B");
1715  abort();
1716  }
1717  // test all clients from hosts list
1718  bool hf=false;
1719  for(rit=pHostSet->mpClients->begin(); rit!=pHostSet->mpClients->end(); ++rit) {
1720  if((*rit)== this) hf=true;
1721  if((*rit)->pHostSet== pHostSet) continue;
1722  FD_WARN("BaseSet(" << this << "," << rMessage << "): invalid client " << (*rit));
1723  abort();
1724  }
1725  if(!hf && (pHostSet!=this)) {
1726  FD_WARN("BaseSet(" << this << "," << rMessage << "): client not registered with host");
1727  abort();
1728  }
1729  // refers to invalid base
1730  if(pHostSet!=this && *mClientRecord!=this) {
1731  FD_WARN("BaseSet(" << this << "," << rMessage << "): refers to invalid host (c)");
1732  abort();
1733  }
1734  // error in detached flag
1735  if(mDetached && mpClients==NULL) {
1736  FD_WARN("BaseSet(" << this << "," << rMessage << "): invalid detached flag A");
1737  abort();
1738  }
1739  // error in detached flag
1740  if(mDetached && !mpClients->empty()) {
1741  FD_WARN("BaseSet(" << this << "," << rMessage << "): invalid detached flag B");
1742  abort();
1743  }
1744  // error in detached flag
1745  if(mDetached && (pSet==&msEmptySet)) {
1746  FD_WARN("BaseSet(" << this << "," << rMessage << "): detached empty set");
1747  abort();
1748  }
1749  // error in lock flag
1750  if(mLocked && (mpClients==NULL)) {
1751  FD_WARN("BaseSet(" << this << "," << rMessage << "): locked reference (a)");
1752  abort();
1753  }
1754  // invalid emptyset
1755  if(!msEmptySet.empty()) {
1756  FD_WARN("BaseSet(" << this << "," << rMessage << "): invalid empty set");
1757  abort();
1758  }
1759  // invalid emptyset
1760  if(!msEmptyAttributes.empty()) {
1761  FD_WARN("BaseSet(" << this << "," << rMessage << "): invalid empty attributes");
1762  abort();
1763  }
1764 #ifdef FAUDES_DEBUG_CONTAINER
1765  std::cerr << "TBaseSet(" << this << ")::DValid(): passed" << std::endl;
1766 #endif
1767 }
1768 
1769 
1770 
1771 // Name
1772 TEMP const std::string& THIS::Name(void) const {
1773  return mMyName;
1774 }
1775 
1776 // Name
1777 TEMP void THIS::Name(const std::string& rName) {
1778  mMyName = rName;
1779 }
1780 
1781 
1782 // TypeDefinitionp()
1783 // Note: fake const construct
1784 TEMP const TypeDefinition* THIS::TypeDefinitionp(void) const {
1785  if(!pTypeDefinition) {
1786  // provide fake const
1787  THIS* fake_const = const_cast< THIS* >(this);
1788  fake_const->pTypeDefinition=TypeRegistry::G()->Definitionp(*this);
1789  }
1790  return pTypeDefinition;
1791 }
1792 
1793 // ElementTag
1794 TEMP const std::string& THIS::XElementTag(void) const {
1795  if(mXElementTag.empty()) {
1796  // provide fake const
1797  THIS* fake_const = const_cast< THIS* >(this);
1798  fake_const->mXElementTag=mXElementTagDef;
1799  const TypeDefinition* fdp=TypeDefinitionp();
1800  if(fdp) if(!fdp->XElementTag().empty()) fake_const->mXElementTag=fdp->XElementTag();
1801  }
1802  return mXElementTag;
1803 }
1804 
1805 // ElementTag
1806 TEMP void THIS::XElementTag(const std::string& rTag) {
1807  mXElementTag=rTag;
1808 }
1809 
1810 
1811 // Faudes Type
1812 TEMP const std::string& THIS::TypeName(void) const {
1813  if(mFaudesTypeName.empty()) {
1814  // provide fake const
1815  THIS* fake_const = const_cast< THIS* >(this);
1816  const TypeDefinition* fdp=TypeDefinitionp();
1817  if(fdp) fake_const->mFaudesTypeName=fdp->Name();
1818  }
1819  return mFaudesTypeName;
1820 }
1821 
1822 // ElementTag
1823 TEMP void THIS::TypeName(const std::string& rType) {
1824  mFaudesTypeName=rType;
1825 }
1826 
1827 
1828 // Str
1829 TEMP std::string THIS::Str(const T& rElem) const {
1830  (void) rElem;
1831  std::string res="";
1832  return res;
1833 }
1834 
1835 // Size()
1836 TEMP Idx THIS::Size(void) const {
1837  return (Idx) pSet->size();
1838 }
1839 
1840 // Empty()
1841 TEMP bool THIS::Empty(void) const {
1842  return pSet->empty();
1843 }
1844 
1845 
1846 // DoWrite(tw,rLabel,cpntext)
1847 TEMP void THIS::DoWrite(TokenWriter& rTw,const std::string& rLabel, const Type* pContext) const {
1848  (void) pContext;
1849  std::string label=rLabel;
1850  if(label=="") label=Name();
1851  if(label=="") label="BaseSet";
1852  FD_DC("TBaseSet(" << this << ")::DoWrite(..): section " << label << " #" << Size());
1853  rTw.WriteBegin(label);
1854  rTw.WriteEnd(label);
1855 }
1856 
1857 
1858 // DoDWrite(tw, label, context)
1859 TEMP void THIS::DoDWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
1860  (void) pContext;
1861  (void) rLabel;
1862  BASE::DoSWrite(rTw);
1863  size_t shares=0;
1864  if(pHostSet->mpClients) shares=pHostSet->mpClients->size();
1865  rTw.WriteComment("");
1866  rTw.WriteComment(" Size/Attributes: " + ToStringInteger(this->Size())
1867  + "/" + ToStringInteger((Idx) pHostSet->pAttributes->size()));
1868  rTw.WriteComment(" Shares/Iterators: " + ToStringInteger((Idx) shares)
1869  + "/" + ToStringInteger((Idx) mIterators.size()));
1870  rTw.WriteComment("");
1871 #ifdef FAUDES_DEBUG_CODE
1872  DValid();
1873 #endif
1874 }
1875 
1876 // DoSWrite()
1877 TEMP void THIS::DoSWrite(TokenWriter& rTw) const {
1878  BASE::DoSWrite(rTw);
1879  size_t shares=0;
1880  if(pHostSet->mpClients) shares=pHostSet->mpClients->size();
1881  rTw.WriteComment(" Size: " + ToStringInteger(this->Size()));
1882  rTw.WriteComment(" Shared Data: #" + ToStringInteger((Idx) shares) + " clients");
1883  if(pAttributes->size()!=0)
1884  rTw.WriteComment(" Attributes: " +ToStringInteger((Idx) pAttributes->size()));
1885  if(pAttributes->size()!=0) {
1886  AttributeVoid* attr = pAttributes->begin()->second;
1887  rTw.WriteComment(" Attribute Type: " +FaudesTypeName(*attr));
1888  }
1889 }
1890 
1891 // DoRead(rTr, rLabel, pContext)
1892 TEMP void THIS::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
1893  (void) pContext;
1894  std::string label=rLabel;
1895  if(label=="") label=Name();
1896  if(label=="") label="BaseSet";
1897  Name(label);
1898  rTr.ReadBegin(label);
1899  rTr.ReadEnd(label);
1900 }
1901 
1902 // ThisIterator (tmoor 201308: this is by default an attached iterator)
1903 TEMP typename THIS::Iterator THIS::ThisIterator(const typename std::set<T,Cmp>::const_iterator& sit) const {
1904  return Iterator(this,sit,true);
1905 }
1906 
1907 // Begin() const
1908 TEMP inline typename THIS::Iterator THIS::Begin(void) const {
1909  return ThisIterator(pSet->begin());
1910 }
1911 
1912 // End() const
1913 TEMP inline typename THIS::Iterator THIS::End(void) const {
1914  return ThisIterator(pSet->end());
1915 }
1916 
1917 
1918 //Clear
1919 TEMP void THIS::Clear(void) {
1920  FD_DC("TBaseSet(" << this << ")::Clear()");
1921 #ifdef FAUDES_DEBUG_CODE
1922  DValid("PreClear");
1923 #endif
1924  // special case: empty anyway
1925  if(pSet==&msEmptySet) return;
1926 
1927  FD_DC("TBaseSet(" << this << ")::Clear(): doit");
1928  FD_DC("TBaseSet(" << this << ")::Clear(): type " << typeid(*this).name());
1929  // special case: locked requires a copy (not efficient!)
1930  if(mLocked) Detach(SetOnly);
1931  // make someone else handle the data
1932  RelinkClients();
1933  pHostSet->DetachClient(this);
1934  // make myself host
1935  pHostSet=this;
1936  if(!mpClients) mpClients= new std::list< TBaseSet<T,Cmp>* >;
1937  mpClients->clear();
1938  // if we hold data, clear it
1939  if(mpSet) {
1940  delete mpSet;
1941  mpSet=NULL;
1942  }
1943  // if we hold data, clear it
1944  if(mpAttributes) {
1945  for(aiterator ait=mpAttributes->begin(); ait!=mpAttributes->end(); ++ait) {
1946  FD_DC("TBaseSet(" << this << ")::Clear(): del attr " << ait->second);
1947  delete ait->second;
1948  }
1949  delete mpAttributes;
1950  mpAttributes=NULL;
1951  }
1952  // set to empty set
1953  pSet=&msEmptySet;
1954  pAttributes=&msEmptyAttributes;
1955  // fix iterators (invalidate)
1956  typename std::set< Iterator* >::iterator iit;
1957  for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1958  (**iit).Invalidate();
1959  }
1960  mIterators.clear();
1961  mDetached=false;
1962  mLocked=false;
1963 #ifdef FAUDES_DEBUG_CODE
1964  DValid("PostClear");
1965 #endif
1966  FD_DC("TBaseSet(" << this << ")::Clear(): done");
1967 }
1968 
1969 
1970 //Valid(elem)
1971 TEMP inline bool THIS::Valid(const T& rElem) const {
1972  (void) rElem;
1973  return true;
1974 }
1975 
1976 //Insert(elem)
1977 TEMP bool THIS::Insert(const T& rElem) {
1978 #ifdef FAUDES_CHECKED
1979  if(!Valid(rElem)) {
1980  std::stringstream errstr;
1981  errstr << "refuse to insert invalid element" << std::endl;
1982  throw Exception("BaseSet::Insert", errstr.str(), 61);
1983  }
1984 #endif
1985  if(!mDetached) Detach();
1986  return pSet->insert(rElem).second;
1987 }
1988 
1989 //Inject(elem)
1990 TEMP typename THIS::Iterator THIS::Inject(const Iterator& pos, const T& rElem) {
1991  if(!mDetached) Detach();
1992  iterator dst= pos.StlIterator();
1993  return ThisIterator(pSet->insert(dst,rElem));
1994 }
1995 
1996 
1997 //Inject(elem)
1998 TEMP void THIS::Inject(const T& rElem) {
1999  if(!mDetached) Detach();
2000  pSet->insert(pSet->end(),rElem);
2001 }
2002 
2003 // InsertSet(set)
2004 TEMP void THIS::InsertSet(const TBaseSet& rOtherSet) {
2005  FD_DC("TBaseSet(" << this << ")::InsertSet(" << &rOtherSet << ")");
2006  if(!mDetached) Detach();
2007  /*
2008  rm: cannot use stl since result overlaps with arguments
2009 
2010  std::insert_iterator< std::set<T,Cmp> > insit(*pSet, rpSet->begin());
2011  std::set_union(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end(), insit);
2012  */
2013  iterator it1 = pSet->begin();
2014  iterator it2 = rOtherSet.pSet->begin();
2015  while ((it1 != pSet->end()) && (it2 != rOtherSet.pSet->end())) {
2016  if (*it1 < *it2) {
2017  ++it1;
2018  }
2019  else if (*it1 == *it2) {
2020  ++it1;
2021  ++it2;
2022  }
2023  else { // (*it1 > *it2)
2024  pSet->insert(*it2);
2025  ++it2;
2026  }
2027  }
2028  while (it2 != rOtherSet.pSet->end()) {
2029  pSet->insert(*it2);
2030  ++it2;
2031  }
2032 }
2033 
2034 
2035 //Erase(rElem)
2036 TEMP bool THIS::Erase(const T& rElem) {
2037  if(!mDetached) Detach();
2038  return (pSet->erase(rElem)!=0);
2039 }
2040 
2041 
2042 //Erase(pos)
2043 TEMP typename THIS::Iterator THIS::Erase(const Iterator& pos) {
2044 #ifdef FAUDES_CHECKED
2045  if (pos == End()) {
2046  std::stringstream errstr;
2047  errstr << "iterator out of range " << std::endl;
2048  throw Exception("BaseSet::Erase", errstr.str(), 62);
2049  }
2050 #endif
2051  Detach();
2052  iterator del= pos.StlIterator();
2053  pSet->erase(del++);
2054  return ThisIterator(del);
2055 }
2056 
2057 
2058 //EraseSet(set)
2059 TEMP void THIS::EraseSet(const TBaseSet& rOtherSet) {
2060  FD_DC("TBaseSet(" << this << ")::EraseSet(" << &rOtherSet << ")");
2061  if(!mDetached) Detach();
2062  // TODO: test and optimize
2063  iterator it = pSet->begin();
2064  iterator oit = rOtherSet.pSet->begin();
2065  while ((it != pSet->end()) && (oit != rOtherSet.pSet->end())) {
2066  if (*it < *oit) {
2067  it=pSet->lower_bound(*oit); // alt: ++it;
2068  }
2069  else if (*it == *oit) {
2070  ++oit;
2071  pSet->erase(it++);
2072  }
2073  else { // (*it > *oit)
2074  oit=rOtherSet.pSet->lower_bound(*it); // ++it2;
2075  }
2076  }
2077 }
2078 
2079 
2080 //RestrictSet(set)
2081 TEMP void THIS::RestrictSet(const TBaseSet& rOtherSet) {
2082  FD_DC("TBaseSet(" << this << ")::RestrictSet(" << &rOtherSet << ")");
2083  if(!mDetached) Detach();
2084  // TODO: test and optimize
2085  iterator it = pSet->begin();
2086  iterator oit = rOtherSet.pSet->begin();
2087  while ((it != pSet->end()) && (oit != rOtherSet.pSet->end())) {
2088  if (*it < *oit) {
2089  pSet->erase(it++);
2090  }
2091  else if (*it == *oit) {
2092  ++it;
2093  ++oit;
2094  }
2095  else { // (*it > *oit)
2096  oit=rOtherSet.pSet->lower_bound(*it);
2097  }
2098  }
2099  while(it != pSet->end()) {
2100  pSet->erase(it++);
2101  }
2102 }
2103 
2104 
2105 //Disjoint(set)
2106 TEMP bool THIS::Disjoint(const TBaseSet& rOtherSet) const {
2107  FD_DC("TBaseSet(" << this << ")::Disjoint(" << &rOtherSet << ")");
2108  // trivial cases
2109  if(pSet->empty()) return true;
2110  if(rOtherSet.pSet->empty()) return true;
2111  if(*pSet->rbegin()<*rOtherSet.pSet->begin()) return true;
2112  if(*rOtherSet.pSet->rbegin()<*pSet->begin()) return true;
2113  if(rOtherSet.pSet==pSet) return false;
2114  // iterate
2115  iterator it = pSet->begin();
2116  iterator oit = rOtherSet.pSet->begin();
2117  while ((it != pSet->end()) && (oit != rOtherSet.pSet->end())) {
2118  if (*it < *oit) { it++; continue;}
2119  if (*it == *oit) { return false; }
2120  // if (*it > *oit)
2121  oit++;
2122  }
2123  return true;
2124 }
2125 
2126 //Find(elem)
2127 TEMP typename THIS::Iterator THIS::Find(const T& rElem) const {
2128  return ThisIterator(pSet->find(rElem));
2129 }
2130 
2131 //Exists(elem)
2132 TEMP bool THIS::Exists(const T& rElem) const {
2133  return pSet->find(rElem) != pSet->end();
2134 }
2135 
2136 
2137 // operator+
2138 TEMP THIS THIS::operator+ (const TBaseSet& rOtherSet) const {
2139  TBaseSet res(*this);
2140  res.InsertSet(rOtherSet);
2141  return res;
2142 }
2143 
2144 // operator-
2145 TEMP THIS THIS::operator- (const TBaseSet& rOtherSet) const {
2146  TBaseSet res(*this);
2147  res.EraseSet(rOtherSet);
2148  return res;
2149 }
2150 
2151 
2152 // operator*
2153 TEMP THIS THIS::operator* (const TBaseSet& rOtherSet) const {
2154  TBaseSet res(*this);
2155  res.RestrictSet(rOtherSet);
2156  return res;
2157 }
2158 
2159 
2160 // operator==
2161 TEMP bool THIS::DoEqual(const TBaseSet& rOtherSet) const {
2162  FD_DC("TBaseSet::DoEqual()");
2163  // true if we share anyway
2164  if(pSet == rOtherSet.pSet) return true;
2165  // compare sets
2166  return ( *pSet == *rOtherSet.pSet );
2167 }
2168 
2169 // operator<=
2170 TEMP bool THIS::operator<= (const TBaseSet& rOtherSet) const {
2171  FD_DC("BaseSet::op<=()");
2172  return ( std::includes(rOtherSet.pSet->begin(), rOtherSet.pSet->end(), pSet->begin(), pSet->end()) ) ;
2173 }
2174 
2175 // operator>=
2176 TEMP bool THIS::operator>= (const TBaseSet& rOtherSet) const {
2177  FD_DC("BaseSet::op>=()");
2178  return ( std::includes(pSet->begin(), pSet->end(), rOtherSet.pSet->begin(), rOtherSet.pSet->end()) );
2179 }
2180 
2181 // operator<
2182 TEMP bool THIS::operator< (const TBaseSet& rOtherSet) const {
2183  return *pSet < *rOtherSet.pSet;
2184 }
2185 
2186 
2187 // attribute typeinfo
2188 TEMP const AttributeVoid* THIS::AttributeType(void) const {
2189  static AttributeVoid attr;
2190  return & attr;
2191 }
2192 
2193 // test attribute type
2194 TEMP bool THIS::AttributeTest(const Type& rAttr) const {
2195  return AttributeType()->Cast(&rAttr)!=NULL;
2196 }
2197 
2198 // number of attributes
2199 TEMP Idx THIS::AttributesSize(void) const {
2200  return (Idx) pAttributes->size();
2201 }
2202 
2203 // clear attributes
2204 TEMP void THIS::ClearAttributes(void) {
2205  // bail out if there are no attributes anyway
2206  if(this->pAttributes->size()==0) return;
2207  // detach (this will copy the set if required and return with empty attributes)
2208  this->Detach(SetOnly);
2209 }
2210 
2211 
2212 // Implement attributes: equality
2213 TEMP bool THIS::EqualAttributes(const TBaseSet<T,Cmp>& rOtherSet) const {
2214  FD_DC("TBaseSet::EqualAttributes(TBaseSet)");
2215  // false, if type does not match
2216  FD_DC("TBaseSet::EqualAttributes(TBaseSet): 1");
2217  if(typeid(*rOtherSet.AttributeType())!=typeid(*this->AttributeType()))
2218  return false;
2219  // true, if we share attribute data
2220  FD_DC("TBaseSet::EqualAttributes(TBaseSet): 2");
2221  if(pAttributes==rOtherSet.pAttributes)
2222  return true;
2223  // true if there are no attributes
2224  FD_DC("TBaseSet::EqualAttributes(TBaseSet): 3");
2225  if(rOtherSet.AttributesSize()==0)
2226  if(this->AttributesSize()==0)
2227  return true;
2228  // figure shared elements and test for equal attributes
2229  aiterator ait1 = pAttributes->begin();
2230  aiterator ait2 = rOtherSet.pAttributes->begin();
2231  while ((ait1 != pAttributes->end()) && (ait2 != rOtherSet.pAttributes->end())) {
2232  if (ait1->first < ait2->first) {
2233  ++ait1;
2234  }
2235  else if (ait1->first == ait2->first) {
2236  FD_DC("TBaseSet::EqualAttributes(TBaseSet): cmp " << ait1->second->ToString()
2237  << " vs " << ait2->second->ToString());
2238  if( ! ait1->second->Equal(*ait2->second)) return false;
2239  ++ait1;
2240  ++ait2;
2241  }
2242  else { // (*it1 > *it2)
2243  ++ait2;
2244  }
2245  }
2246  // passed
2247  FD_DC("TBaseSet::EqualAttributes(TBaseSet): pass");
2248  return true;
2249 }
2250 
2251 
2252 
2253 // public wrapper
2254 TEMP THIS& THIS::AssignWithoutAttributes(const TBaseSet<T,Cmp>& rSourceSet) {
2255  // call virtual (fake copy, will only copy attributes on type match)
2256  this->DoAssign(rSourceSet);
2257  // detach, effectively clears attributes
2258  this->Detach(SetOnly);
2259  return *this;
2260 }
2261 
2262 // set attribute wrapper
2263 TEMP void THIS::Attributes(const TBaseSet<T,Cmp>& rOtherSet) {
2264  FD_DC("TBaseSet::Attributes("<<this<<")");
2265  // type mismatch
2266  if(!this->AttributeTest(*rOtherSet.AttributeType())) {
2267  std::stringstream errstr;
2268  errstr << "cannot cast attribute " << std::endl;
2269  throw Exception("TBaseSet::Attributes(otherset)", errstr.str(), 63);
2270  }
2271  // can not hold attributes anyway
2272  if(typeid(*this->AttributeType())== typeid(const AttributeVoid)) return;
2273  // do assign
2274  this->Detach(AttrIncl);
2275  iterator it1 = pSet->begin();
2276  iterator it2 = rOtherSet.pSet->begin();
2277  while ((it1 != pSet->end()) && (it2 != rOtherSet.pSet->end())) {
2278  if (*it1 < *it2) {
2279  ++it1;
2280  }
2281  else if (*it1 == *it2) {
2282  DoAttribute(*it1,&rOtherSet.Attribute(*it2));
2283  ++it1;
2284  ++it2;
2285  }
2286  else { // (*it1 > *it2)
2287  ++it2;
2288  }
2289  }
2290  FD_DC("TBaseSet::Attributes(): copy ok");
2291 }
2292 
2293 
2294 
2295 // attribute access
2296 TEMP AttributeVoid* THIS::Attributep(const T& rElem) {
2297  (void) rElem;
2298  std::stringstream errstr;
2299  errstr << "cannot get attribute for TBaseSet \"" << mMyName << "\" type " << typeid(*this).name();
2300  throw Exception("TBaseSet::Attributep(rElem)", errstr.str(), 63);
2301  // dummy: will through exception before
2302  static AttributeVoid attr;
2303  return &attr;
2304 }
2305 
2306 // attribute access
2307 TEMP const AttributeVoid& THIS::Attribute(const T& rElem) const {
2308  (void) rElem;
2309  static AttributeVoid attr;
2310  return attr;
2311 }
2312 
2313 // attribute access
2314 TEMP void THIS::Attribute(const T& rElem, const Type& rAttr) {
2315  (void) rElem;
2316  /* its pointless to test existence of the element since we wont set any attribute anyway */
2317 #ifdef FAUDES_CHECKED
2318  if (!Exists(rElem)) {
2319  std::stringstream errstr;
2320  errstr << "element not member of set" << std::endl;
2321  throw Exception("TBaseSet::Attribute(elem,attr)", errstr.str(), 60);
2322  }
2323 #endif
2324  if(!AttributeTest(rAttr)) {
2325  std::stringstream errstr;
2326  errstr << "cannot cast attribute " << std::endl;
2327  throw Exception("TBaseSet::Attribute(elem,attr)", errstr.str(), 63);
2328  }
2329  // passes test for all childs of AttributeVoid
2330 }
2331 
2332 
2333 // clr attributes wrapper
2334 TEMP void THIS::ClrAttribute(const T& rElem) {
2335  this->Detach();
2336  DoAttribute(rElem,(const AttributeVoid*) NULL);
2337 }
2338 
2339 
2340 // implement attributes: get pointer, NULL for implicit default
2341 TEMP const AttributeVoid* THIS::DoAttribute(const T& rElem) const {
2342  const_aiterator ait;
2343  ait=this->pAttributes->find(rElem);
2344  if(ait==this->pAttributes->end()) return NULL;
2345  return ait->second;
2346 }
2347 
2348 // implement attributes: get pointer (assume detached)
2349 TEMP AttributeVoid* THIS::DoAttributeExplicit(const T& rElem) {
2350  FD_DC("TBaseSet::DoAttributeExplicit(elem)");
2351 #ifdef FAUDES_DEBUG_CODE
2352  if(this->pAttributes!=this->mpAttributes) {
2353  FD_ERR("TBaseSet::DoAttributeExplicit(elem): attributes not detached");
2354  abort();
2355  }
2356 #endif
2357  aiterator ait;
2358  ait=this->pAttributes->find(rElem);
2359  if(ait!=this->pAttributes->end())
2360  return ait->second;
2361  // instantiate explicit default
2362  AttributeVoid* attr = this->AttributeType()->Copy();
2363  FD_DC("TBaseSet::DoAttributeExplicit(Elem): inserting explicit default " << attr << " type " << typeid(*attr).name());
2364  (*this->pAttributes)[rElem]=attr;
2365  return attr;
2366 }
2367 
2368 // implement attributes: set (assume detached)
2369 TEMP void THIS::DoAttribute(const T& rElem, const Type* pAttr) {
2370  FD_DC("TBaseSet::DoAttribute([v] " << this->Str(rElem) << ", ...)");
2371 #ifdef FAUDES_DEBUG_CODE
2372  if(this->pAttributes!=this->mpAttributes) {
2373  FD_ERR("TBaseSet::DoAttribute([v] set): attributes not detached");
2374  abort();
2375  }
2376 #endif
2377  // type check new attribute
2378  const AttributeVoid* newattr=dynamic_cast<const AttributeVoid*>(pAttr);
2379  if(!this->AttributeType()->Cast(pAttr)) newattr=NULL;
2380  // find element in map
2381  aiterator ait;
2382  AttributeVoid* oldattr=NULL;
2383  ait=this->pAttributes->find(rElem);
2384  if(ait!=this->pAttributes->end() )
2385  oldattr=ait->second;
2386  // set to default, case 1
2387  if(newattr==NULL) {
2388  FD_DC("TBaseSet::DoAttribute([v] " << this->Str(rElem) << ", ...): default 1");
2389  if(oldattr==NULL) return;
2390  delete oldattr;
2391  this->pAttributes->erase(ait);
2392  return;
2393  }
2394  // set to default, case 2
2395  if(newattr->IsDefault()) {
2396  FD_DC("TBaseSet::DoAttribute([v] " << this->Str(rElem) << ", ...): default 2");
2397  if(oldattr==NULL) return;
2398  delete oldattr;
2399  this->pAttributes->erase(ait);
2400  return;
2401  }
2402  FD_DC("TBaseSet::DoAttribute([v] " << this->Str(rElem) << ", ...): " << newattr->ToString());
2403  // prepare attribute and set
2404  if(oldattr==NULL) {
2405  AttributeVoid* attr = this->AttributeType()->New();
2406  attr->Assign(*newattr);
2407  (*this->pAttributes)[rElem]=attr;
2408  return;
2409  }
2410  // plain set
2411  FD_DC("TBaseSet::DoAttribute([v] " << this->Str(rElem) << ", ...): " << newattr->ToString());
2412  oldattr->Assign(*newattr);
2413 }
2414 
2415 
2416 /* undefine local shortcuts */
2417 #undef THIS
2418 #undef TEMP
2419 #undef BASE
2420 
2421 /** @} doxygen group */
2422 
2423 } // namespace faudes
2424 
2425 #endif
#define FD_DC(message)
#define FD_WARN(message)
#define FD_ERR(message)
#define FAUDES_OBJCOUNT_DEC(type)
#define FAUDES_OBJCOUNT_INC(type)
#define FAUDES_TAPI
Definition: cfl_platform.h:83
Class TokenReader.
Class TokenWriter.
#define FAUDES_TYPE_TIMPLEMENTATION_CAST(ftype, ctype, cbase, ctemp)
Definition: cfl_types.h:927
#define FAUDES_TYPE_TIMPLEMENTATION_EQUAL(ftype, ctype, cbase, ctemp)
Definition: cfl_types.h:938
#define FAUDES_TYPE_TDECLARATION(ftype, ctype, cbase)
Definition: cfl_types.h:883
#define FAUDES_TYPE_TIMPLEMENTATION_ASSIGN(ftype, ctype, cbase, ctemp)
Definition: cfl_types.h:930
#define FAUDES_TYPE_TIMPLEMENTATION_COPY(ftype, ctype, cbase, ctemp)
Definition: cfl_types.h:924
#define FAUDES_TYPE_TIMPLEMENTATION_NEW(ftype, ctype, cbase, ctemp)
Definition: cfl_types.h:921
virtual bool IsDefault(void) const
const std::string & Name(void) const
Definition: cfl_types.cpp:397
void DValid(void) const
Definition: cfl_baseset.h:495
Iterator(const TBaseSet< T, Cmp > *pBaseSet, const typename std::set< T, Cmp >::const_iterator &sit, bool att=false)
Definition: cfl_baseset.h:406
void StlIterator(const typename std::set< T, Cmp >::const_iterator &sit)
Definition: cfl_baseset.h:473
Iterator(const Iterator &fit)
Definition: cfl_baseset.h:421
const TBaseSet< T, Cmp > * pBaseSet
Definition: cfl_baseset.h:595
const std::set< T, Cmp >::const_iterator & StlIterator(void) const
Definition: cfl_baseset.h:478
std::string DStr(void) const
Definition: cfl_baseset.h:438
std::list< TBaseSet< T, Cmp > * > * mpClients
Definition: cfl_baseset.h:957
std::string mXElementTag
Definition: cfl_baseset.h:1009
std::map< T, AttributeVoid * > * mpAttributes
Definition: cfl_baseset.h:939
std::list< TBaseSet< T, Cmp > * >::iterator mClientRecord
Definition: cfl_baseset.h:954
std::string mMyName
Definition: cfl_baseset.h:916
std::string mXElementTagDef
Definition: cfl_baseset.h:1014
std::set< Iterator * > mIterators
Definition: cfl_baseset.h:975
std::set< T, Cmp >::iterator iterator
Definition: cfl_baseset.h:925
std::set< T, Cmp > * mpSet
Definition: cfl_baseset.h:922
std::string mFaudesTypeName
Definition: cfl_baseset.h:1006
const TypeDefinition * pTypeDefinition
Definition: cfl_baseset.h:1003
virtual void AttributeTry(const T &rElem, const Type &rAttr)
Definition: cfl_baseset.h:787
std::map< T, AttributeVoid * > * pAttributes
Definition: cfl_baseset.h:936
std::map< T, AttributeVoid * >::const_iterator const_aiterator
Definition: cfl_baseset.h:945
std::set< T, Cmp >::const_iterator const_iterator
Definition: cfl_baseset.h:928
std::map< T, AttributeVoid * >::iterator aiterator
Definition: cfl_baseset.h:942
std::set< T, Cmp > * pSet
Definition: cfl_baseset.h:919
TBaseSet< T, Cmp > * pHostSet
Definition: cfl_baseset.h:951
void ReadEnd(const std::string &rLabel)
void ReadBegin(const std::string &rLabel)
void WriteComment(const std::string &rComment)
void WriteEnd(const std::string &rLabel)
void WriteBegin(const std::string &rLabel)
const std::string & XElementTag(void) const
Definition: cfl_types.cpp:848
static TypeRegistry * G()
const TypeDefinition * Definitionp(const std::string &rTypeName) const
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
Definition: cfl_types.cpp:262
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Definition: cfl_types.cpp:170
virtual Type & Assign(const Type &rSrc)
Definition: cfl_types.cpp:77
virtual Type * New(void) const
Definition: cfl_types.cpp:54
virtual Type * Copy(void) const
Definition: cfl_types.cpp:60
virtual bool Insert(const T &rElem)
Definition: cfl_baseset.h:1977
bool DoEqual(const TBaseSet &rOtherSet) const
Definition: cfl_baseset.h:2161
virtual const AttributeVoid * AttributeType(void) const
Definition: cfl_baseset.h:2188
virtual const std::string & XElementTag(void) const
Definition: cfl_baseset.h:1794
void DoAttribute(const T &rElem, const Type *pAttr)
Definition: cfl_baseset.h:2369
#define TEMP
Definition: cfl_baseset.h:1166
void Lock(void) const
Definition: cfl_baseset.h:1479
virtual TBaseSet & AssignWithoutAttributes(const TBaseSet &rSourceSet)
Definition: cfl_baseset.h:2254
void DoAssign(const TBaseSet &rSourceSet)
Definition: cfl_baseset.h:1278
void Detach(DetachMode flag=AttrIncl) const
Definition: cfl_baseset.h:1348
bool SetInclusion(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB)
Definition: cfl_baseset.h:1142
virtual void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
Definition: cfl_baseset.h:1847
void AttachClient(TBaseSet *pRef) const
Definition: cfl_baseset.h:1559
bool SetEquality(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB)
Definition: cfl_baseset.h:1126
virtual void TypeName(const std::string &rType)
Definition: cfl_baseset.h:1823
bool Empty(void) const
Definition: cfl_baseset.h:1841
void DetachClient(TBaseSet *pRef) const
Definition: cfl_baseset.h:1567
void SetDifference(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Definition: cfl_baseset.h:1092
bool Exists(const T &rElem) const
Definition: cfl_baseset.h:2132
virtual void Attributes(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:2263
virtual void Attribute(const T &rElem, const Type &rAttr)
Definition: cfl_baseset.h:2314
virtual bool Disjoint(const TBaseSet &rOtherSet) const
Definition: cfl_baseset.h:2106
void Name(const std::string &rName)
Definition: cfl_baseset.h:1777
virtual void Clear(void)
Definition: cfl_baseset.h:1919
const AttributeVoid * DoAttribute(const T &rElem) const
Definition: cfl_baseset.h:2341
void DetachIterator(Iterator *pFit) const
Definition: cfl_baseset.h:1616
TBaseSet< T, Cmp >::Iterator ThisIterator(const typename std::set< T, Cmp >::const_iterator &sit) const
Definition: cfl_baseset.h:1903
Iterator Find(const T &rElem) const
Definition: cfl_baseset.h:2127
virtual bool Valid(const T &rElem) const
Definition: cfl_baseset.h:1971
virtual Iterator Inject(const Iterator &pos, const T &rElem)
Definition: cfl_baseset.h:1990
virtual void DoDWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
Definition: cfl_baseset.h:1859
virtual void XElementTag(const std::string &rTag)
Definition: cfl_baseset.h:1806
Idx AttributesSize(void) const
Definition: cfl_baseset.h:2199
static std::set< T, Cmp > msEmptySet
Definition: cfl_baseset.h:992
virtual bool AttributeTest(const Type &rAttr) const
Definition: cfl_baseset.h:2194
TBaseSet(const std::string &rFilename, const std::string &rLabel="BaseSet")
Definition: cfl_baseset.h:1209
virtual const TypeDefinition * TypeDefinitionp(void) const
Definition: cfl_baseset.h:1784
Iterator End(void) const
Definition: cfl_baseset.h:1913
virtual ~TBaseSet(void)
Definition: cfl_baseset.h:1254
virtual void RestrictSet(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:2081
virtual void InsertSet(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:2004
virtual AttributeVoid * Attributep(const T &rElem)
Definition: cfl_baseset.h:2296
bool EqualAttributes(const TBaseSet &rOtherSet) const
Definition: cfl_baseset.h:2213
Iterator Begin(void) const
Definition: cfl_baseset.h:1908
virtual const std::string & TypeName(void) const
Definition: cfl_baseset.h:1812
virtual const AttributeVoid & Attribute(const T &rElem) const
Definition: cfl_baseset.h:2307
void RelinkClients(void)
Definition: cfl_baseset.h:1510
void DValid(const std::string &rMessage="") const
Definition: cfl_baseset.h:1623
AttributeVoid * DoAttributeExplicit(const T &rElem)
Definition: cfl_baseset.h:2349
virtual bool Erase(const T &rElem)
Definition: cfl_baseset.h:2036
const std::string & Name(void) const
Definition: cfl_baseset.h:1772
#define THIS
Definition: cfl_baseset.h:1165
void SetUnion(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Definition: cfl_baseset.h:1033
void SetIntersection(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Definition: cfl_baseset.h:1063
virtual void EraseSet(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:2059
TBaseSet(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:1231
Idx Size(void) const
Definition: cfl_baseset.h:1836
virtual void Inject(const T &rElem)
Definition: cfl_baseset.h:1998
void ClearAttributes(void)
Definition: cfl_baseset.h:2204
virtual std::string Str(const T &rElem) const
Definition: cfl_baseset.h:1829
virtual Iterator Erase(const Iterator &pos)
Definition: cfl_baseset.h:2043
void AttachIterator(Iterator *pFit) const
Definition: cfl_baseset.h:1609
virtual void ClrAttribute(const T &rElem)
Definition: cfl_baseset.h:2334
static std::map< T, AttributeVoid * > msEmptyAttributes
Definition: cfl_baseset.h:995
virtual void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
Definition: cfl_baseset.h:1892
virtual void DoSWrite(TokenWriter &rTw) const
Definition: cfl_baseset.h:1877
const std::string & FaudesTypeName(const Type &rObject)
uint32_t Idx
std::string ToStringInteger(Int number)
Definition: cfl_utils.cpp:43
std::string CollapsString(const std::string &rString, unsigned int len)
Definition: cfl_utils.cpp:91

libFAUDES 2.33c --- 2025.05.15 --- c++ api documentaion by doxygen