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

libFAUDES 2.34g --- 2026.04.09 --- c++ api documentaion by doxygen