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