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

libFAUDES 2.34e --- 2026.03.16 --- c++ api documentaion by doxygen