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

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen