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