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 
437 // attribute typeinfo
438 TEMP const Attr* THIS::AttributeType(void) const {
439  static Attr attr;
440  FD_DC("TAttrMap::AttributeType(): accessing non trivial type");
441  return &attr;
442 }
443 
444 
445 // get attribute wrapper
446 TEMP Attr* THIS::Attributep(const T& rElem) {
447 #ifdef FAUDES_CHECKED
448  if(!pBaseSet->Exists(rElem)) {
449  std::stringstream errstr;
450  errstr << "element \"" << pBaseSet->Str(rElem) << "\" not member of set " << pBaseSet->Name() << std::endl;
451  throw Exception("TAttrMap::Attributep(elem)", errstr.str(), 60);
452  }
453 #endif
454  // must detach
455  pBaseSet->Detach();
456  // find in map (incl insert explicit default)
457  Attr* attr=dynamic_cast<Attr*>(pBaseSet->DoAttributeExplicit(rElem));
458  FD_DC("TAttrMap::Attributep(): found " << attr << " type " << typeid(*attr).name() );
459  // done
460  return attr;
461 }
462 
463 // get attribute wrapper
464 TEMP const Attr& THIS::Attribute(const T& rElem) const {
465 #ifdef FAUDES_CHECKED
466  if(!pBaseSet->Exists(rElem)) {
467  std::stringstream errstr;
468  errstr << "element \"" << pBaseSet->Str(rElem) << "\" not member of set " << pBaseSet->Name() << std::endl;
469  throw Exception("TAttrMap::Attribute(elem)", errstr.str(), 60);
470  }
471 #endif
472  // find in map
473  const Attr* attr=dynamic_cast<const Attr*>(pBaseSet->DoAttribute(rElem));
474  // use default
475  if(!attr) attr=this->AttributeType();
476  // done
477  return *attr;
478 }
479 
480 // set attribute wrapper
481 TEMP void THIS::Attribute(const T& rElem, const Type& attr) {
482 #ifdef FAUDES_CHECKED
483  if (!pBaseSet->Exists(rElem)) {
484  std::stringstream errstr;
485  errstr << "element \"" << pBaseSet->Str(rElem) << "\" not member of set " << pBaseSet->Name() << std::endl;
486  throw Exception("TAttrMap::Attribute(elem,attr [t])", errstr.str(), 60);
487  }
488 #endif
489  if(!pBaseSet->AttributeTest(attr)) {
490  std::stringstream errstr;
491  errstr << "cannot cast attribute " << std::endl;
492  throw Exception("TAttrMap::Attribute(elem,attr [t])", errstr.str(), 63);
493  }
494  pBaseSet->Detach();
495  pBaseSet->DoAttribute(rElem,&attr);
496 }
497 
498 // set attribute wrapper
499 TEMP void THIS::AttributeTry(const T& rElem, const Type& attr) {
500  FD_DC("TAttrMap::Attribute(elem,attr) [t]");
501 #ifdef FAUDES_CHECKED
502  if(!pBaseSet->Exists(rElem)) {
503  std::stringstream errstr;
504  errstr << "element \"" << pBaseSet->Str(rElem) << "\" not member of set " << pBaseSet->Name() << std::endl;
505  throw Exception("TAttrMap::AttributeTry(elem,attr [t])", errstr.str(), 60);
506  }
507 #endif
508  if(!pBaseSet->AttributeTest(attr)) return;
509  pBaseSet->Detach();
510  pBaseSet->DoAttribute(rElem,&attr);
511 }
512 
513 // set attribute wrapper
514 TEMP void THIS::Attribute(const T& rElem, const Attr& attr) {
515  FD_DC("TAttrMap::Attribute(elem,attr) [a]");
516 #ifdef FAUDES_CHECKED
517  if(!pBaseSet->Exists(rElem)) {
518  pBaseSet->DWrite();
519  std::stringstream errstr;
520  errstr << "element \"" << pBaseSet->Str(rElem) << "\" not member of set " << pBaseSet->Name() << std::endl;
521  throw Exception("TAttrMap::Attribute(elem,attr [a])", errstr.str(), 60);
522  }
523 #endif
524  pBaseSet->Detach();
525  pBaseSet->DoAttribute(rElem, &attr);
526 }
527 
528 
529 /* undefine local shortcuts */
530 #undef THIS
531 #undef TEMP
532 
533 
534 } // namespace faudes
535 
536 #endif
#define TEMP
Definition: cfl_attrmap.h:274
Class TBaseSet.
#define FD_DC(message)
Debug: optional report on container operations.
#define FAUDES_API
Interface export/import symbols: windows.
Definition: cfl_platform.h:81
Minimal Attribute.
Faudes exception class.
Attribute interface for TBaseSet.
Definition: cfl_attrmap.h:52
bool Insert(const T &rElem, const Attr &attr)
Insert element with attribute.
Definition: cfl_attrmap.h:331
const Attr & Attribute(const T &rElem) const
Get attribute by element.
Definition: cfl_attrmap.h:464
Attr * Attributep(const T &rElem)
Get attribute reference by element.
Definition: cfl_attrmap.h:446
void AttributeTry(const T &rElem, const Type &attr)
Set attribute.
Definition: cfl_attrmap.h:499
bool Erase(const T &rElem)
Erase Element (incl its attribute)
Definition: cfl_attrmap.h:369
TBaseSet< T, Cmp >::const_aiterator const_aiterator
use TBaseSet STL iterators
Definition: cfl_attrmap.h:247
void EraseSet(const TBaseSet< T, Cmp > &rOtherSet)
Erase elements given by other set.
Definition: cfl_attrmap.h:386
TBaseSet< T, Cmp >::Iterator Erase(const typename TBaseSet< T, Cmp >::Iterator &pos)
Erase element by iterator (incl attribute)
Definition: cfl_attrmap.h:376
TBaseSet< T, Cmp >::aiterator aiterator
use TBaseSet STL iterators
Definition: cfl_attrmap.h:244
void Attribute(const T &rElem, const Type &attr)
Set attribute.
Definition: cfl_attrmap.h:481
void InsertSet(const TBaseSet< T, Cmp > &rOtherSet)
Inserts elements from rOtherSet.
Definition: cfl_attrmap.h:340
void RestrictSet(const TBaseSet< T, Cmp > &rOtherSet)
Restrict to specified subset.
Definition: cfl_attrmap.h:409
TAttrMap(TBaseSet< T, Cmp > *pBaseSetRef)
Constructor.
Definition: cfl_attrmap.h:277
virtual ~TAttrMap(void)
Virtual destructor.
Definition: cfl_attrmap.h:285
TBaseSet< T, Cmp >::const_iterator const_iterator
use TBaseSet STL iterators
Definition: cfl_attrmap.h:241
void AssignWithAttributes(const TBaseSet< T, Cmp > &rSourceSet)
Copy from a TBaseSet to the associated TBaseSet, with attributes, provided that they can be casted ac...
Definition: cfl_attrmap.h:292
TBaseSet< T, Cmp > * pBaseSet
reference to associated TBaseSet
Definition: cfl_attrmap.h:250
TBaseSet< T, Cmp >::iterator iterator
use TBaseSet STL iterators
Definition: cfl_attrmap.h:238
bool Insert(const T &rElem)
Insert element.
Definition: cfl_attrmap.h:323
const Attr * AttributeType(void) const
Attribute typeinfo.
Definition: cfl_attrmap.h:438
void Attribute(const T &rElem, const Attr &attr)
Set attribute.
Definition: cfl_attrmap.h:514
std::map< T, AttributeVoid * > * pAttributes
Pointer to attribute map to operate on.
Definition: cfl_baseset.h:927
std::set< T, Cmp > * pSet
Pointer on STL set to operate on.
Definition: cfl_baseset.h:910
Base class of all libFAUDES objects that participate in the run-time interface.
Definition: cfl_types.h:239
virtual const AttributeVoid * AttributeType(void) const
Attribute typeinfo.
Definition: cfl_baseset.h:2171
void DoAttribute(const T &rElem, const Type *pAttr)
set attribute in map (assume elem exists in set, NULL <=> set to default)
Definition: cfl_baseset.h:2352
void Detach(DetachMode flag=AttrIncl) const
Definition: cfl_baseset.h:1331
Idx AttributesSize(void) const
Attribute access.
Definition: cfl_baseset.h:2182
virtual const AttributeVoid & Attribute(const T &rElem) const
Attribute access.
Definition: cfl_baseset.h:2290
libFAUDES resides within the namespace faudes.

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