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

libFAUDES 2.32f --- 2024.12.22 --- c++ api documentaion by doxygen