libFAUDES
Sections
Index
|
cfl_indexset.hGo to the documentation of this file.00001 /** @file cfl_indexset.h @brief Classes IndexSet, TaIndexSet */ 00002 00003 00004 /* FAU Discrete Event Systems Library (libfaudes) 00005 00006 Copyright (C) 2006 Bernd Opitz 00007 Copyright (C) 2007 Thomas Moor 00008 Exclusive copyright is granted to Klaus Schmidt 00009 00010 This library is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU Lesser General Public 00012 License as published by the Free Software Foundation; either 00013 version 2.1 of the License, or (at your option) any later version. 00014 00015 This library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public 00021 License along with this library; if not, write to the Free Software 00022 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00023 00024 00025 00026 #ifndef FAUDES_INDEXSET_H 00027 #define FAUDES_INDEXSET_H 00028 00029 #include "cfl_definitions.h" 00030 #include "cfl_exception.h" 00031 #include "cfl_abaseset.h" 00032 #include "cfl_symboltable.h" 00033 #include "cfl_registry.h" 00034 #include <algorithm> 00035 00036 00037 namespace faudes { 00038 00039 00040 00041 /** @addtogroup ContainerClasses */ 00042 /** @{*/ 00043 00044 // Forward declaration for the attributed version of indexset 00045 template<class Attr> class TaIndexSet; 00046 00047 /** 00048 * Set of indices. This class is built on top of the faudes version 00049 * TBaseSet of STL sets. It provides the essentials of the STL interface 00050 * and inherits the standard token IO interface from Type, so you may 00051 * use Read and Write for file/string/console IO. 00052 * 00053 * IndexSet is used as common base for TaIndexSet (indices with attributes), 00054 * NameSet (indices with symbolic names) and TaNameSet (indices with 00055 * attributes and symbolic names). 00056 * 00057 * The index of value 0 is reserved to indicate the invalid index. If the macro FAUDES_CHECKED 00058 * is defined, the attempt to insert an index 0 triggers an exception (id 61). Invalid 00059 * iterators throw an exception (id 62) when used as an argument to a IndexSet function. 00060 * 00061 * Technically, file IO is done by TaIndexSet functions. This requires a copy and for 00062 * that reason may be reimplemented in a future versions. 00063 * The format is demonstrated by the following example 00064 * of a set with name "MySet" consisting of indices 17, 25, 26, 27, 28, 40: 00065 * \code 00066 * <Myset> 00067 * 17 00068 * <Consecutive> 25 4 </Consecutive> 00069 * 40 00070 * </MySet> 00071 * \endcode 00072 * Theere is a minimum number of consecutive indices for the use of the consecutive 00073 * section defined in definitions.h. 00074 * 00075 */ 00076 00077 class IndexSet : public virtual TBaseSet<Idx> { 00078 00079 FAUDES_TYPE_DECLARATION(IndexSet,IndexSet,TBaseSet<Idx>) 00080 00081 public: 00082 00083 /** 00084 * We implement "protected privacy for template classes" by friendship. 00085 * This is used for the pragmatic implemention conversion constructors. 00086 */ 00087 template<class Attr> friend class TaIndexSet; 00088 00089 00090 /** 00091 * Constructor. 00092 */ 00093 IndexSet(void); 00094 00095 /** 00096 * Copy-constructor. 00097 */ 00098 IndexSet(const IndexSet& rOtherSet); 00099 00100 /** 00101 * Copy-constructor. 00102 */ 00103 IndexSet(const TBaseSet<Idx>& rOtherSet); 00104 00105 /** 00106 * Construct from file. Uses the Read(TokenReader&, const std::string&) function to read. 00107 * a IndexSet from section rLabel in file rFilename. 00108 * 00109 * @param rFilename 00110 * Name of file to read 00111 * @param rLabel 00112 * Section to read 00113 * 00114 * @exception Exception 00115 * - IO Errors (id 1) 00116 * - Token mismatch (id 50, 51, 52) 00117 */ 00118 IndexSet(const std::string& rFilename, const std::string& rLabel = ""); 00119 00120 /** 00121 * Virtual destructor 00122 */ 00123 virtual ~IndexSet(void) {}; 00124 00125 /** 00126 * Get maximum index used in this set (0 for emptyset) 00127 * 00128 * @return 00129 * max indices 00130 */ 00131 Idx MaxIndex(void) const; 00132 00133 /** 00134 * Test whether index is not 0 00135 * @param rIndex 00136 * Index to test 00137 * @return 00138 * True if idx!=0 00139 */ 00140 bool Valid(const Idx& rIndex) const; 00141 00142 /** 00143 * Iterators on indexset. 00144 */ 00145 typedef TBaseSet<Idx>::Iterator Iterator; 00146 00147 /** 00148 * Insert new index to set 00149 * 00150 * @return 00151 * New index 00152 */ 00153 Idx Insert(void); 00154 00155 /** 00156 * Insert specified index 00157 * 00158 * @param rIndex 00159 * Index to insert 00160 * @return 00161 * True if index was new to set 00162 */ 00163 bool Insert(const Idx& rIndex); 00164 00165 /** 00166 * Compute an Idx type signature for a Set. The value is computed by 00167 * summing up the product of every index with an integer starting at 00168 * 1 (for the first index) and ending at Size() (for the last index). 00169 * 00170 * @return 00171 * Idx type set signature 00172 */ 00173 Idx Signature(void) const; 00174 00175 /** 00176 * Return pretty printable index. 00177 * 00178 * @param rIndex 00179 * Index to print 00180 * 00181 * @return 00182 * String 00183 */ 00184 std::string Str(const Idx& rIndex) const {return ToStringInteger(rIndex); }; 00185 00186 protected: 00187 00188 /** 00189 * Assign my members. This method maintains attributes 00190 * provided that the type can be appropriately casted. 00191 * 00192 * @param rSource 00193 * Source to copy from 00194 * @return 00195 * Ref to this set 00196 */ 00197 virtual void DoAssign(const IndexSet& rSource); 00198 00199 /** 00200 * Write to TokenWriter, see Type::Write for public wrappers. 00201 * Appends the IndexSet to 00202 * TokenWriter. This will write a section with label as specified that holds 00203 * integer tokens to represent the IndexSet. For non-default attribute values, 00204 * the respective index is followed by the attribute value. The latter may 00205 * consist of sections (or tokens different from integer or string) to allow 00206 * for transparent reading; see AttributeVoid and AttributeFlags. Example for 00207 * a set with name "MySet" consisting of indices 17, 25, 40, where index 25 has a 00208 * nontrivial attribute attached: 00209 * \code 00210 * <Myset> 00211 * 17 00212 * 25 <AValue> "Some Value" </AValue> 00213 * 40 00214 * </MySet> 00215 * \endcode 00216 * 00217 * @param tw 00218 * Reference to TokenWriter 00219 * @param rLabel 00220 * Label of section to write, defaults to name of set or "IndexSet" 00221 * @param pContext 00222 * Write context to provide contextual information 00223 * 00224 * @exception Exception 00225 * - IO errors (id 2) 00226 */ 00227 virtual void DoWrite(TokenWriter& tw, const std::string& rLabel="", const Type* pContext=0) const; 00228 00229 /** 00230 * Read from TokenReader, see Type::Read for public wrappers. 00231 * This method invokes TokenReader::ReadBegin() to seek the specified 00232 * section, reads subsequent integer tokens as indexes, and calls matching TokenReader::ReadEnd(). 00233 * If no section is specified, the section is assumed to start at the current position 00234 * of the token stream. If the current position is no begin token, 00235 * the section "IndexSet" is read. 00236 * When used by a derived class with attributes, attributes are read, too. 00237 * 00238 * @param rTr 00239 * Reference to tokenreader 00240 * @param rLabel 00241 * Section to read, defaults to current begin label or else "IndexSet" 00242 * @param pContext 00243 * Read context to provide contextual information 00244 * 00245 * @exception Exception 00246 * - IO errors (id 1) 00247 * - token mismatch (id 50, 51, 52) 00248 */ 00249 virtual void DoRead(TokenReader& rTr, const std::string& rLabel="", const Type* pContext=0); 00250 00251 }; 00252 00253 /* convenience typedef for stateset */ 00254 typedef IndexSet StateSet; 00255 00256 00257 00258 /** 00259 * Set of indices with attributes. A TaIndexSet<Attr> is a template derived from IndexSet, 00260 * such that each set element has an Attribute of class Attr. 00261 * The template parameter Attr must provide basic functions for file IO and must define a default 00262 * value, see AttributeVoid and AttributeFlags for an examples. 00263 * Attributes are maintained by an STL map to associate indices 00264 * with attributes different from the default value. Thus, attributes with default value 00265 * do not take up any memeory. 00266 * 00267 * @param mAttributeMap 00268 * STL map of type std::map<Idx,Attr> to hold attributes 00269 * 00270 * The copy constructor copies attributes; the methods InsertSet(), EraseSet() and 00271 * RestrictSet() maintain attributes; all other set operations derived from IndexSet 00272 * either return a IndexSet (no attributes) or set all attributes to the dafault value. 00273 * To set or get an attribute of an index that does not exist in the set is considered 00274 * as an error and triggers an exception (id 60) when the macro FAUDES_CHECKED is defined. 00275 * 00276 * The format for token IO is demonstrated by the following example 00277 * of a set with name "MySet" consisting of indices 17, 25, 40, where index 25 has a 00278 * nontrivial attribute attached: 00279 * \code 00280 * <Myset> 00281 * 17 00282 * 25 <AValue> "Some Value" </AValue> 00283 * 40 00284 * </MySet> 00285 * \endcode 00286 * Note that attributes may be either subsections or tokens of type different from integer and string. 00287 * This is to allow reading a token stream to a class with incompatible (or no) attributes. 00288 */ 00289 00290 00291 00292 template<class Attr> 00293 class TaIndexSet : public IndexSet, public TaBaseSet<Idx,Attr> { 00294 00295 FAUDES_TYPE_TDECLARATION(Void,TaIndexSet,IndexSet) 00296 00297 public: 00298 00299 /** 00300 * We implement "protected privacy for template classes" by friendship. 00301 * This is used for the pragmatic implemention conversion constructors. 00302 */ 00303 friend class IndexSet; 00304 00305 00306 /** 00307 * Constructor. 00308 */ 00309 TaIndexSet(void); 00310 00311 /** 00312 * Copy-constructor (from TaIndexSet, incl attributes) 00313 */ 00314 TaIndexSet(const TaIndexSet& rOtherSet); 00315 00316 /** 00317 * Copy-constructor (from IndexSet, sets attributes to default) 00318 */ 00319 TaIndexSet(const IndexSet& rOtherSet); 00320 00321 /** 00322 * Construct from file. 00323 * This constructor uses the Read(TokenReader&, const std::string&) function to read. 00324 * 00325 * @param rFilename 00326 * Name of file 00327 * @param rLabel 00328 * Section for the set in file 00329 * 00330 * @exception Exception 00331 * - IO errors (id 1) 00332 * - token mismatch (id 50, 51, 52) 00333 */ 00334 TaIndexSet(const std::string& rFilename, const std::string& rLabel = ""); 00335 00336 /** 00337 * Virtual destructor 00338 */ 00339 virtual ~TaIndexSet(void) {}; 00340 00341 /** Relaxed assignment method. Maintain provided they can be casted.. 00342 * 00343 * @param rSrc 00344 * Source from which to assign 00345 * @return 00346 * Ref to this set 00347 */ 00348 virtual TaIndexSet& Assign(const IndexSet& rSrc); 00349 00350 /** Relaxed assignment operator. Maintain attributes provided they can be casted. 00351 * 00352 * @param rSrc 00353 * Source from which to assign 00354 * @return 00355 * Ref to this set 00356 */ 00357 virtual TaIndexSet& operator=(const IndexSet& rSrc); 00358 00359 /** 00360 * Set attributes. Provided that rOtherSet has attributes that can be 00361 * casted to the appropriate type, attributes are copied per element from rOtherSet. 00362 * Elements of this set which are not in rOtherSet maintain their attribute. 00363 * 00364 * @param rOtherSet 00365 * Other IndexSet 00366 * @exception Exception 00367 * - Element does not exist (63) 00368 * - Cannot cast attribute type (63) 00369 */ 00370 virtual void Attributes(const IndexSet& rOtherSet); 00371 00372 /** 00373 * Set attributes. Attributes are copied per element from rOtherSet. 00374 * Elements of this set which are not in rOtherSet maintain their attribute. 00375 * 00376 * @param rOtherSet 00377 * Other IndexSet 00378 */ 00379 virtual void Attributes(const TaIndexSet& rOtherSet); 00380 00381 /** 00382 * Iterators on indexset. 00383 */ 00384 typedef IndexSet::Iterator Iterator; 00385 00386 /** 00387 * Erase Element (incl its attribute) 00388 * 00389 * @param rIndex 00390 * Index to specify element 00391 * @return 00392 * True if element used to exist 00393 */ 00394 bool Erase(const Idx& rIndex); 00395 00396 00397 /** 00398 * Erase element by iterator (incl attribute) 00399 * 00400 * @param pos 00401 * Iterator to specify element 00402 * @return 00403 * Iterator to next element or End() 00404 */ 00405 Iterator Erase(const Iterator& pos); 00406 00407 00408 /** 00409 * Erase elements given by other set. This function 00410 * ignores the attributes of the other set and maintains the attributes 00411 * of the remaining elements in this set. 00412 * 00413 * @param rOtherSet 00414 * Elements to erase 00415 */ 00416 void EraseSet(const IndexSet& rOtherSet); 00417 00418 /** 00419 * Restrict to specified subset. Erases any elements no in 00420 * the specified set. This function 00421 * ignores the attributes of the other set and maintains the attributes 00422 * of the remaining elements in this set. 00423 * 00424 * @param rOtherSet 00425 * Elements to erase 00426 */ 00427 void RestrictSet(const IndexSet& rOtherSet); 00428 00429 00430 /** 00431 * Insert new index to set using default attribute. 00432 * 00433 * @return 00434 * New index 00435 */ 00436 Idx Insert(void); 00437 00438 /** 00439 * Insert new index with attribute. 00440 * If the index allready exists, the 00441 * attribute is overwritten by rAttr. 00442 * 00443 * @param rAttr 00444 * Specify attribute of new element 00445 * @return 00446 * new index 00447 */ 00448 Idx Insert(const Attr& rAttr); 00449 00450 /** 00451 * Insert element. If the element exists, the attribute is maintained. 00452 * If the element does not exist, it is inserted with default attribute. 00453 * 00454 * @param rIndex 00455 * Index to specify element 00456 * @return 00457 * True if element was new to set 00458 */ 00459 bool Insert(const Idx& rIndex); 00460 00461 /** 00462 * Insert element with attribute. 00463 * 00464 * @param rIndex 00465 * Index to specify element 00466 * @param attr 00467 * Specify attribute of (new) element 00468 * @return 00469 * True if element was new to set 00470 */ 00471 bool Insert(const Idx& rIndex, const Attr& attr); 00472 00473 /** 00474 * Inserts elements of rOtherSet. 00475 * Attributes of this set are maintained, newly inserted elements have default attribute. 00476 * 00477 * 00478 * @param rOtherSet 00479 * Other IndexSet 00480 */ 00481 virtual void InsertSet(const IndexSet& rOtherSet); 00482 00483 /** 00484 * Inserts elements of rOtherSet. 00485 * Attributes of this set are maintained, new elements are inserted with attribute. 00486 * 00487 * @param rOtherSet 00488 * Other IndexSet 00489 */ 00490 virtual void InsertSet(const TaIndexSet& rOtherSet); 00491 00492 /** 00493 * Clear all set. 00494 */ 00495 virtual void Clear(void); 00496 00497 00498 00499 protected: 00500 00501 /** 00502 * Assign my members. This method maintains attributes. 00503 * 00504 * @param rSource 00505 * Source to copy from 00506 * @return 00507 * Ref to this set 00508 */ 00509 virtual void DoAssign(const TaIndexSet& rSource); 00510 00511 00512 }; 00513 00514 /** Convenience Macro */ 00515 //template<class Attr> typedef TaStateSet<class Attr> TaIndexSet<class Attr> 00516 #define TaStateSet TaIndexSet 00517 00518 00519 /** @} doxygen group */ 00520 00521 00522 /* 00523 ************************************************************************************* 00524 ************************************************************************************* 00525 Implementation 00526 ************************************************************************************* 00527 ************************************************************************************* 00528 */ 00529 00530 00531 // std faudes type 00532 FAUDES_TYPE_TIMPLEMENTATION(Void,TaIndexSet<Attr>,IndexSet,template<class Attr>) 00533 00534 00535 // TaIndexSet() 00536 template<class Attr> 00537 TaIndexSet<Attr>::TaIndexSet(void) : 00538 TBaseSet<Idx>(), 00539 IndexSet(), 00540 TaBaseSet<Idx,Attr>() 00541 { 00542 FD_DC("TaIndexSet(" << this << ")::TaIndexSet()"); 00543 } 00544 00545 // TaIndexSet(rOtherSet) 00546 template<class Attr> 00547 TaIndexSet<Attr>::TaIndexSet(const TaIndexSet& rOtherSet) : 00548 TBaseSet<Idx>(), 00549 IndexSet(), 00550 TaBaseSet<Idx,Attr>() 00551 { 00552 FD_DC("TaIndexSet(" << this << ")::TaIndexSet(rOtherSet " << &rOtherSet << ")"); 00553 // copy my members 00554 DoAssign(rOtherSet); 00555 } 00556 00557 // TaIndexSet(rOtherSet) 00558 template<class Attr> 00559 TaIndexSet<Attr>::TaIndexSet(const IndexSet& rOtherSet) : 00560 TBaseSet<Idx>(), 00561 IndexSet(), 00562 TaBaseSet<Idx,Attr>() 00563 { 00564 FD_DC("TaIndexSet(" << this << ")::TaIndexSet(rOtherSet " << &rOtherSet << ")"); 00565 // copy my members 00566 Assign(rOtherSet); 00567 } 00568 00569 00570 // File constructor 00571 template<class Attr> 00572 TaIndexSet<Attr>::TaIndexSet(const std::string& rFilename, const std::string& rLabel) : 00573 TBaseSet<Idx>(), 00574 IndexSet(), 00575 TaBaseSet<Idx,Attr>() 00576 { 00577 FD_DC("TaIndexSet(" << this << ")::TaIndexSet(" << rFilename << ")"); 00578 Read(rFilename, rLabel); 00579 } 00580 00581 00582 // DoAssign (attributes known and match) 00583 template<class Attr> 00584 void TaIndexSet<Attr>::DoAssign(const TaIndexSet<Attr>& rSourceSet) { 00585 FD_DC("TaIndexSet(" << this << ")::DoAssign( [a] " << &rSourceSet<<")"); 00586 // call base incl attributes 00587 TaBaseSet<Idx,Attr>::DoAssign(rSourceSet); 00588 } 00589 00590 // Relaxed Assign() 00591 template<class Attr> 00592 TaIndexSet<Attr>& TaIndexSet<Attr>::Assign(const IndexSet& rSourceSet) { 00593 FD_DC("TaIndexSet(" << this << ")::Assign([v] " << &rSourceSet<<")"); 00594 FD_DC("TaIndexSet(" << this << ")::Assign(): src type " << typeid(rSourceSet).name()); 00595 FD_DC("TaIndexSet(" << this << ")::Assign(): dst type " << typeid(*this).name()); 00596 // call attribute smart base 00597 TaBaseSet<Idx,Attr>::Assign(rSourceSet); 00598 // done 00599 return *this; 00600 } 00601 00602 // Relaxed Assignment Operator(rSet) 00603 template<class Attr> 00604 TaIndexSet<Attr>& TaIndexSet<Attr>::operator=(const IndexSet& rSourceSet) { 00605 return Assign(rSourceSet); 00606 } 00607 00608 00609 // Attributes(set) 00610 template<class Attr> 00611 void TaIndexSet<Attr>::Attributes(const TaIndexSet& rOtherSet) { 00612 FD_DC("TaIndexSet(" << this << ")::Attributes(set) with type " << typeid(rOtherSet.Attribute()).name()); 00613 TaBaseSet<Idx,Attr>::Attributes(rOtherSet); 00614 } 00615 00616 // Attributes(set) 00617 template<class Attr> 00618 void TaIndexSet<Attr>::Attributes(const IndexSet& rOtherSet) { 00619 FD_DC("TaIndexSet(" << this << ")::Attributes(set) with type " << typeid(rOtherSet.Attribute()).name()); 00620 TaBaseSet<Idx,Attr>::Attributes(rOtherSet); 00621 } 00622 00623 00624 //Clear 00625 template<class Attr> 00626 void TaIndexSet<Attr>::Clear(void) { 00627 FD_DC("TaIndexSet(" << this << ")::Clear()"); 00628 TaBaseSet<Idx,Attr>::Clear(); 00629 } 00630 00631 // Insert() 00632 template<class Attr> 00633 Idx TaIndexSet<Attr>::Insert(void) { 00634 FD_DC("TaIndexSet(" << this << ")::Insert()"); 00635 Idx index=MaxIndex()+1; 00636 TaBaseSet<Idx,Attr>::Insert(index); 00637 return index; 00638 } 00639 00640 //Insert(idx) 00641 template<class Attr> 00642 bool TaIndexSet<Attr>::Insert(const Idx& rIndex) { 00643 FD_DC("TaIndexSet(" << this << ")::Insert("<< rIndex <<")"); 00644 bool ret=IndexSet::Insert(rIndex); // automatic: keep attribute if exists 00645 return ret; 00646 } 00647 00648 // Insert(attr) 00649 template<class Attr> 00650 Idx TaIndexSet<Attr>::Insert(const Attr& attr) { 00651 FD_DC("TaIndexSet(" << this << ")::Insert(" << attr.ToString() << ")"); 00652 Idx index = Insert(); 00653 if(!attr.IsDefault()) { 00654 TaBaseSet<Idx,Attr>::Attribute(index,attr); 00655 } 00656 return index; 00657 } 00658 00659 //Insert(idx,attr) 00660 template<class Attr> 00661 bool TaIndexSet<Attr>::Insert(const Idx& rIndex, const Attr& attr) { 00662 FD_DC("TaIndexSet(" << this << ")::Insert("<< rIndex <<",attr)"); 00663 return TaBaseSet<Idx,Attr>::Insert(rIndex,attr); 00664 } 00665 00666 00667 // InsertSet(set) 00668 template<class Attr> 00669 void TaIndexSet<Attr>::InsertSet(const TaIndexSet& rOtherSet) { 00670 FD_DC("TaIndexSet(" << this << ")::InsertSet( T " << &rOtherSet << ")"); 00671 TaBaseSet<Idx,Attr>::InsertSet(rOtherSet); 00672 } 00673 00674 // InsertSet(set) 00675 template<class Attr> 00676 void TaIndexSet<Attr>::InsertSet(const IndexSet& rOtherSet) { 00677 FD_DC("TaIndexSet(" << this << ")::InsertSet(" << &rOtherSet << ")"); 00678 IndexSet::InsertSet(rOtherSet); 00679 } 00680 00681 //Erase(idx) 00682 template<class Attr> 00683 bool TaIndexSet<Attr>::Erase(const Idx& rIndex) { 00684 return TaBaseSet<Idx,Attr>::Erase(rIndex); 00685 } 00686 00687 //Erase(pos) 00688 template<class Attr> 00689 typename TaIndexSet<Attr>::Iterator TaIndexSet<Attr>::Erase(const Iterator& pos) { 00690 return TaBaseSet<Idx,Attr>::Erase(pos); 00691 } 00692 00693 00694 //EraseSet(set) 00695 template<class Attr> 00696 void TaIndexSet<Attr>::EraseSet(const IndexSet& rOtherSet) { 00697 FD_DC("TaIndexSet(" << this << ")::EraseSet(" << rOtherSet.ToString() << ")"); 00698 TaBaseSet<Idx,Attr>::EraseSet(rOtherSet); 00699 } 00700 00701 //RestrictSet(set) 00702 template<class Attr> 00703 void TaIndexSet<Attr>::RestrictSet(const IndexSet& rOtherSet) { 00704 FD_DC("TaIndexSet(" << this << ")::RestrictSet(" << rOtherSet.ToString() << ")"); 00705 TaBaseSet<Idx,Attr>::RestrictSet(rOtherSet); 00706 } 00707 00708 00709 00710 00711 } // namespace faudes 00712 00713 #endif |
libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen