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

libFAUDES 2.32b --- 2024.03.01 --- c++ api documentaion by doxygen