cfl_attrmap.h
Go to the documentation of this file.
1 /** @file cfl_attrmap.h @brief Class TAttrMap */
2 
3 
4 /* FAU Discrete Event Systems Library (libfaudes)
5 
6  Copyright (C) 2008, 2016 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  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
21 
22 
23 
24 #ifndef FAUDES_ATTRMAP_H
25 #define FAUDES_ATTRMAP_H
26 
27 #include "cfl_baseset.h"
28 
29 namespace faudes {
30 
31 /** @addtogroup ContainerClasses */
32 /** @{*/
33 
34 /**
35  * Attribute interface for TBaseSet.
36  *
37  * TAttrMap provides a typed interface to access the attributes associated with
38  * elements of a TBaseSet. It is meant to faciltate classes derived from TBaseSet
39  * that use non-trivial attributes. Note that the actual attribute map is hosted by
40  * TBaseSet itself.
41  *
42  * Note: technically, the TAttrMap holds a reference to the associated TBaseSet.
43  * When deriving from a child of TBaseSet, the interface is introduced
44  * by additional inheritance of TAttrMap. Effectively, this avoids the diomand-shape
45  * inheritance we used to have in pre 2.30 versions of libFAUDES and which caused various
46  * issues with the MS Visual Studio compilers regarding covaraint return values in the
47  * context of templates.
48  */
49 
50 
51 template<class T, class Attr, class Cmp=std::less<T> >
53 
54 
55 public:
56 
57  /**
58  * Constructor.
59  *
60  * Record associated set.
61  */
62  TAttrMap(TBaseSet<T,Cmp>* pBaseSetRef);
63 
64  /**
65  * Virtual destructor
66  */
67  virtual ~TAttrMap(void);
68 
69  /**
70  * Copy from a TBaseSet to the associated TBaseSet, with attributes,
71  * provided that they can be casted accordingly.
72  *
73  * @param rSourceSet
74  * Set to copy from
75  */
76  void AssignWithAttributes(const TBaseSet<T,Cmp>& rSourceSet);
77 
78  /**
79  * Attribute typeinfo.
80  *
81  * @return
82  * Pointer to some attribute of this sets attribute type.
83  */
84  const Attr* AttributeType(void) const;
85 
86 
87  /**
88  * Get attribute reference by element. Note that in order to produce a non-const
89  * reference this method will insert an explicit default attribute if necessary.
90  * If a const reference is sufficient, you should use Attribute(rElem) const instead.
91  *
92  * @param rElem
93  * Specify element
94  * @exception Exception
95  * - Element does not exist (60)
96  * @return
97  * Pointer to attribute
98  */
99  Attr* Attributep(const T& rElem);
100 
101  /**
102  * Get attribute by element. This function returns a const reference to the attribute
103  * of the specified element.
104  * @param rElem
105  * Specify element
106  * @exception Exception
107  * - Element does not exist (63)
108  * @return
109  * Reference to attribute
110  */
111  const Attr& Attribute(const T& rElem) const;
112 
113  /**
114  * Set attribute. Provided that the attribute can be casted to the
115  * appropriate type, this method sets the attribute of the sepcified element to the given value.
116  *
117  * @param rElem
118  * Specify element
119  * @param attr
120  * Attribute value.
121  * @exception Exception
122  * - Element does not exist (60)
123  * - Cannot cast attribute type (63)
124  */
125  void Attribute(const T& rElem, const Type& attr);
126 
127  /**
128  * Set attribute. This method sets the attribute of the sepcified element to the given value.
129  *
130  * @param rElem
131  * Specify element
132  * @param attr
133  * Attribute value.
134  * @exception Exception
135  * - Element does not exist (60)
136  * - Cannot cast attribute type (63)
137  */
138  void Attribute(const T& rElem, const Attr& attr);
139 
140  /**
141  * Set attribute. Provided that the attribute can be casted to the
142  * appropriate type, this method sets the attribute of the sepcified element to the given value.
143  * If the cast fails, this method does nothing.
144  *
145  * @param rElem
146  * Specify element
147  * @param attr
148  * Attribute value.
149  * @exception Exception
150  * - Element does not exist (60)
151  */
152  void AttributeTry(const T& rElem, const Type& attr);
153 
154  /**
155  * Insert element. If the element exists, the attribute is maintained.
156  * If the element does not exist, it is inserted with default attribute.
157  *
158  * @param rElem
159  * Specify element
160  * @return
161  * True if element was new to set
162  */
163  bool Insert(const T& rElem);
164 
165  /**
166  * Insert element with attribute.
167  *
168  * @param rElem
169  * Specify element
170  * @param attr
171  * Specify attribute of (new) element
172  * @return
173  * True if element was new to set
174  */
175  bool Insert(const T& rElem, const Attr& attr);
176 
177  /**
178  * Inserts elements from rOtherSet.
179  *
180  * Attributes of this set are maintained, newly inserted elements receive attributes
181  * from rOtherSet, provided that can be casted appropriately.
182  *
183  *
184  * @param rOtherSet
185  * Other BaseSet
186  */
187  void InsertSet(const TBaseSet<T,Cmp>& rOtherSet);
188 
189 
190  /**
191  * Erase Element (incl its attribute)
192  *
193  * @param rElem
194  * Specify element
195  * @return
196  * True if element used to exist
197  */
198  bool Erase(const T& rElem);
199 
200  /**
201  * Erase element by iterator (incl attribute)
202  *
203  * @param pos
204  * Iterator to specify element
205  * @return
206  * Iterator to next element or End()
207  */
208  // opt: use declare&define for cl_win issues
210 
211 
212  /**
213  * Erase elements given by other set. This function
214  * ignores the attributes of the other set and maintains the attributes
215  * of the remaining elements in this set.
216  *
217  * @param rOtherSet
218  * Elements to erase
219  */
220  void EraseSet(const TBaseSet<T,Cmp>& rOtherSet);
221 
222  /**
223  * Restrict to specified subset. Erases any elements not in
224  * the specified set. This function
225  * ignores the attributes of the other set and maintains the attributes
226  * of the remaining elements in this set.
227  *
228  * @param rOtherSet
229  * Elements to erase
230  */
231  void RestrictSet(const TBaseSet<T,Cmp>& rOtherSet);
232 
233 
234 
235 protected:
236 
237  /** use TBaseSet STL iterators */
239 
240  /** use TBaseSet STL iterators */
242 
243  /** use TBaseSet STL iterators */
245 
246  /** use TBaseSet STL iterators */
248 
249  /** reference to associated TBaseSet */
251 
252 };
253 
254 
255 
256 /** @} doxygen group */
257 
258 
259 
260 /*
261 ******************************************************************************************
262 ******************************************************************************************
263 ******************************************************************************************
264 
265 Implementation of TAttrMap
266 
267 ******************************************************************************************
268 ******************************************************************************************
269 ******************************************************************************************
270 */
271 
272 /* convenience access to relevant scopes */
273 #define THIS TAttrMap<T,Attr,Cmp>
274 #define TEMP template<class T, class Attr, class Cmp>
275 
276 // TAttrMap()
277 TEMP THIS::TAttrMap(TBaseSet<T,Cmp>* pBaseSetRef) :
278  pBaseSet(pBaseSetRef)
279 {
280  FD_DC("TAttrMap(" << this << ")::TAttrMap(): set at " << pBaseSet);
281 }
282 
283 
284 // destructor
285 TEMP THIS::~TAttrMap(void) {
286  FD_DC("TAttrMap(" << this << ")::~TAttrMap()");
287 }
288 
289 
290 
291 // assign, try attributes
292 TEMP void THIS::AssignWithAttributes(const TBaseSet<T,Cmp>& rSourceSet) {
293  FD_DC("TAttrMap(" << pBaseSet << ")::Assign(..): dst map type " << typeid(*this).name());
294  FD_DC("TAttrMap(" << pBaseSet << ")::Assign(..): src type " << typeid(rSourceSet).name());
295  // call base (fake copy, this will incl attributes on exact type match or ref to empty attributes else)
296  pBaseSet->DoAssign(rSourceSet);
297  // sense the exact match and bail out
298  if(pBaseSet->AttributesSize()==rSourceSet.AttributesSize()) return;
299  // if we have void attributes, we can not cast
300  FD_DC("TAttrMap(" << this << ")::Assign(..): dst attribute type " << typeid(*AttributeType()).name());
301  if( typeid(*AttributeType()) == typeid(const AttributeVoid) ) return;
302  // if source has void attributes, we can not cast
303  FD_DC("TAttrMap(" << this << ")::Assign(..): src attribute type " << typeid(*rSourceSet.AttributeType()).name());
304  if( typeid(*rSourceSet.AttributeType()) == typeid(const AttributeVoid) ) return;
305  // ifattributes cannot be casted, we dont need to loop either
306  FD_DC("TAttrMap(" << this << ")::Assign(..): try attribute cast");
307  if(!AttributeType()->Cast(rSourceSet.AttributeType())) return;
308  // detach, since we will write to attributes
309  pBaseSet->Detach();
310  FD_DC("TAttrMap(" << this << ")::Assign(..): mind attributes");
311  const_aiterator ait=rSourceSet.pAttributes->begin();
312  for(;ait!=rSourceSet.pAttributes->end(); ++ait) {
313  Attr* attr= new Attr;
314  attr->Assign(*ait->second);
315  (*pBaseSet->pAttributes)[ait->first]=attr;
316  }
317  // done
318  FD_DC("TAttrMap(" << pBaseSet << ")::Assign(..): done");
319 }
320 
321 
322 //Insert(elem)
323 TEMP bool THIS::Insert(const T& rElem) {
324  FD_DC("TAttrMap(" << pBaseSet << ")::Insert(elem)");
325  pBaseSet->Detach();
326  bool ret=pBaseSet->pSet->insert(rElem).second;
327  return ret;
328 }
329 
330 //Insert(idx,attr)
331 TEMP bool THIS::Insert(const T& rElem, const Attr& rAttr) {
332  FD_DC("TAttrMap(" << pBaseSet << ")::Insert(elem,attr)");
333  pBaseSet->Detach();
334  bool ret=pBaseSet->pSet->insert(rElem).second;
335  pBaseSet->DoAttribute(rElem,&rAttr);
336  return ret;
337 }
338 
339 // InsertSet(set)
340 TEMP void THIS::InsertSet(const TBaseSet<T,Cmp>& rOtherSet) {
341  bool doattr=pBaseSet->AttributeTest(*rOtherSet.AttributeType());
342  FD_DC("TAttrMap(" << pBaseSet << ")::InsertSet( [v] " << &rOtherSet << "): doattr=" << doattr);
343  pBaseSet->Detach();
344  iterator it1 = pBaseSet->pSet->begin();
345  iterator it2 = rOtherSet.pSet->begin();
346  while ((it1 != pBaseSet->pSet->end()) && (it2 != rOtherSet.pSet->end())) {
347  if (*it1 < *it2) {
348  ++it1;
349  }
350  else if (*it1 == *it2) {
351  ++it1;
352  ++it2;
353  }
354  else { // (*it1 > *it2)
355  pBaseSet->pSet->insert(*it2);
356  if(doattr) pBaseSet->DoAttribute(*it2,&rOtherSet.Attribute(*it2));
357  ++it2;
358  }
359  }
360  while(it2 != rOtherSet.pSet->end()) {
361  pBaseSet->pSet->insert(*it2);
362  if(doattr) pBaseSet->DoAttribute(*it2,&rOtherSet.Attribute(*it2));
363  ++it2;
364  }
365  FD_DC("TAttrMap(" << pBaseSet << ")::InsertSet( [v] " << &rOtherSet << "): done");
366 }
367 
368 //Erase(idx)
369 TEMP bool THIS::Erase(const T& rElem) {
370  pBaseSet->Detach();
371  pBaseSet->DoAttribute(rElem,(const AttributeVoid*) 0);
372  return (pBaseSet->pSet->erase(rElem)!=0);
373 }
374 
375 //Erase(it)
376 TEMP typename TBaseSet<T,Cmp>::Iterator THIS::Erase(const typename TBaseSet<T,Cmp>::Iterator& pos) {
377  pBaseSet->Detach();
378  iterator del= pos.StlIterator();
379  pBaseSet->DoAttribute(*pos,(const AttributeVoid*) 0);
380  pBaseSet->pSet->erase(del++);
381  return pBaseSet->ThisIterator(del);
382 }
383 
384 
385 //EraseSet(set)
386 TEMP void THIS::EraseSet(const TBaseSet<T,Cmp>& rOtherSet) {
387  FD_DC("TAttrMap(" << pBaseSet << ")::EraseSet(" << &rOtherSet << ")");
388  pBaseSet->Detach();
389  // todo: test and optimize
390  iterator it = pBaseSet->pSet->begin();
391  iterator oit = rOtherSet.pSet->begin();
392  while ((it != pBaseSet->pSet->end()) && (oit != rOtherSet.pSet->end())) {
393  if (*it < *oit) {
394  it=pBaseSet->pSet->lower_bound(*oit); // alt: ++it;
395  }
396  else if (*it == *oit) {
397  pBaseSet->DoAttribute(*it,(const AttributeVoid*) 0);
398  ++oit;
399  pBaseSet->pSet->erase(it++);
400  }
401  else { // (*it > *oit)
402  oit=rOtherSet.pSet->lower_bound(*it); // ++it2;
403  }
404  }
405 }
406 
407 
408 //RestrictSet(set)
409 TEMP void THIS::RestrictSet(const TBaseSet<T,Cmp>& rOtherSet) {
410  FD_DC("TAttrMap(" << pBaseSet << ")::RestrictSet(" << &rOtherSet << ")");
411  pBaseSet->Detach();
412  // todo: test and optimize
413  iterator it = pBaseSet->pSet->begin();
414  iterator oit = rOtherSet.pSet->begin();
415  while ((it != pBaseSet->pSet->end()) && (oit != rOtherSet.pSet->end())) {
416  if (*it < *oit) {
417  pBaseSet->DoAttribute(*it,(const AttributeVoid*) 0);
418  pBaseSet->pSet->erase(it++);
419  }
420  else if (*it == *oit) {
421  ++it;
422  ++oit;
423  }
424  else { // (*it > *oit)
425  ++oit;
426  }
427  }
428  while(it != pBaseSet->pSet->end()) {
429  pBaseSet->DoAttribute(*it,(const AttributeVoid*) 0);
430  pBaseSet->pSet->erase(it++);
431  }
432 
433 }
434 
435 
436 // attribute typeinfo
437 TEMP const Attr* THIS::AttributeType(void) const {
438  static Attr attr;
439  FD_DC("TAttrMap::AttributeType(): accessing non trivial type");
440  return &attr;
441 }
442 
443 
444 // get attribute wrapper
445 TEMP Attr* THIS::Attributep(const T& rElem) {
446 #ifdef FAUDES_CHECKED
447  if(!pBaseSet->Exists(rElem)) {
448  std::stringstream errstr;
449  errstr << "element \"" << pBaseSet->Str(rElem) << "\" not member of set " << pBaseSet->Name() << std::endl;
450  throw Exception("TAttrMap::Attributep(elem)", errstr.str(), 60);
451  }
452 #endif
453  // must detach
454  pBaseSet->Detach();
455  // find in map (incl insert explicit default)
456  Attr* attr=dynamic_cast<Attr*>(pBaseSet->DoAttributeExplicit(rElem));
457  FD_DC("TAttrMap::Attributep(): found " << attr << " type " << typeid(*attr).name() );
458  // done
459  return attr;
460 }
461 
462 // get attribute wrapper
463 TEMP const Attr& THIS::Attribute(const T& rElem) const {
464 #ifdef FAUDES_CHECKED
465  if(!pBaseSet->Exists(rElem)) {
466  std::stringstream errstr;
467  errstr << "element \"" << pBaseSet->Str(rElem) << "\" not member of set " << pBaseSet->Name() << std::endl;
468  throw Exception("TAttrMap::Attribute(elem)", errstr.str(), 60);
469  }
470 #endif
471  // find in map
472  const Attr* attr=dynamic_cast<const Attr*>(pBaseSet->DoAttribute(rElem));
473  // use default
474  if(!attr) attr=this->AttributeType();
475  // done
476  return *attr;
477 }
478 
479 // set attribute wrapper
480 TEMP void THIS::Attribute(const T& rElem, const Type& attr) {
481 #ifdef FAUDES_CHECKED
482  if (!pBaseSet->Exists(rElem)) {
483  std::stringstream errstr;
484  errstr << "element \"" << pBaseSet->Str(rElem) << "\" not member of set " << pBaseSet->Name() << std::endl;
485  throw Exception("TAttrMap::Attribute(elem,attr [t])", errstr.str(), 60);
486  }
487 #endif
488  if(!pBaseSet->AttributeTest(attr)) {
489  std::stringstream errstr;
490  errstr << "cannot cast attribute " << std::endl;
491  throw Exception("TAttrMap::Attribute(elem,attr [t])", errstr.str(), 63);
492  }
493  pBaseSet->Detach();
494  pBaseSet->DoAttribute(rElem,&attr);
495 }
496 
497 // set attribute wrapper
498 TEMP void THIS::AttributeTry(const T& rElem, const Type& attr) {
499  FD_DC("TAttrMap::Attribute(elem,attr) [t]");
500 #ifdef FAUDES_CHECKED
501  if(!pBaseSet->Exists(rElem)) {
502  std::stringstream errstr;
503  errstr << "element \"" << pBaseSet->Str(rElem) << "\" not member of set " << pBaseSet->Name() << std::endl;
504  throw Exception("TAttrMap::AttributeTry(elem,attr [t])", errstr.str(), 60);
505  }
506 #endif
507  if(!pBaseSet->AttributeTest(attr)) return;
508  pBaseSet->Detach();
509  pBaseSet->DoAttribute(rElem,&attr);
510 }
511 
512 // set attribute wrapper
513 TEMP void THIS::Attribute(const T& rElem, const Attr& attr) {
514  FD_DC("TAttrMap::Attribute(elem,attr) [a]");
515 #ifdef FAUDES_CHECKED
516  if(!pBaseSet->Exists(rElem)) {
517  pBaseSet->DWrite();
518  std::stringstream errstr;
519  errstr << "element \"" << pBaseSet->Str(rElem) << "\" not member of set " << pBaseSet->Name() << std::endl;
520  throw Exception("TAttrMap::Attribute(elem,attr [a])", errstr.str(), 60);
521  }
522 #endif
523  pBaseSet->Detach();
524  pBaseSet->DoAttribute(rElem, &attr);
525 }
526 
527 
528 /* undefine local shortcuts */
529 #undef THIS
530 #undef TEMP
531 
532 
533 } // namespace faudes
534 
535 #endif
#define TEMP
Definition: cfl_attrmap.h:274
Class TBaseSet.
#define FD_DC(message)
#define FAUDES_TAPI
Definition: cfl_platform.h:83
bool Insert(const T &rElem, const Attr &attr)
Definition: cfl_attrmap.h:331
const Attr & Attribute(const T &rElem) const
Definition: cfl_attrmap.h:463
Attr * Attributep(const T &rElem)
Definition: cfl_attrmap.h:445
void AttributeTry(const T &rElem, const Type &attr)
Definition: cfl_attrmap.h:498
bool Erase(const T &rElem)
Definition: cfl_attrmap.h:369
TBaseSet< T, Cmp >::const_aiterator const_aiterator
Definition: cfl_attrmap.h:247
void EraseSet(const TBaseSet< T, Cmp > &rOtherSet)
Definition: cfl_attrmap.h:386
TBaseSet< T, Cmp >::Iterator Erase(const typename TBaseSet< T, Cmp >::Iterator &pos)
Definition: cfl_attrmap.h:376
TBaseSet< T, Cmp >::aiterator aiterator
Definition: cfl_attrmap.h:244
void Attribute(const T &rElem, const Type &attr)
Definition: cfl_attrmap.h:480
void InsertSet(const TBaseSet< T, Cmp > &rOtherSet)
Definition: cfl_attrmap.h:340
void RestrictSet(const TBaseSet< T, Cmp > &rOtherSet)
Definition: cfl_attrmap.h:409
TAttrMap(TBaseSet< T, Cmp > *pBaseSetRef)
Definition: cfl_attrmap.h:277
virtual ~TAttrMap(void)
Definition: cfl_attrmap.h:285
TBaseSet< T, Cmp >::const_iterator const_iterator
Definition: cfl_attrmap.h:241
void AssignWithAttributes(const TBaseSet< T, Cmp > &rSourceSet)
Definition: cfl_attrmap.h:292
TBaseSet< T, Cmp > * pBaseSet
Definition: cfl_attrmap.h:250
TBaseSet< T, Cmp >::iterator iterator
Definition: cfl_attrmap.h:238
bool Insert(const T &rElem)
Definition: cfl_attrmap.h:323
const Attr * AttributeType(void) const
Definition: cfl_attrmap.h:437
void Attribute(const T &rElem, const Attr &attr)
Definition: cfl_attrmap.h:513
std::map< T, AttributeVoid * > * pAttributes
Definition: cfl_baseset.h:936
std::set< T, Cmp > * pSet
Definition: cfl_baseset.h:919
virtual const AttributeVoid * AttributeType(void) const
Definition: cfl_baseset.h:2188
void DoAttribute(const T &rElem, const Type *pAttr)
Definition: cfl_baseset.h:2369
void Detach(DetachMode flag=AttrIncl) const
Definition: cfl_baseset.h:1348
Idx AttributesSize(void) const
Definition: cfl_baseset.h:2199
virtual const AttributeVoid & Attribute(const T &rElem) const
Definition: cfl_baseset.h:2307

libFAUDES 2.33b --- 2025.05.07 --- c++ api documentaion by doxygen