Hauptseite | Klassenhierarchie | Auflistung der Klassen | Auflistung der Dateien | Klassen-Elemente | Datei-Elemente | Zusätzliche Informationen

U_LISTS.H

gehe zur Dokumentation dieser Datei
00001 //############################################################################# 00002 // // 00003 // U_LISTS.H // 00004 // Subsystem: Utilities - verkettete Listen // 00005 // Benutung durch andere Subsysteme erforderlich: JA // 00006 // Implementation: U_LISTS.CPP // 00007 //---------------------------------------------------------------------------// 00008 // Autoren: Thomas Kullmann, Günther Reinecker // 00009 // Stand: 02.04.2004 // 00010 // // 00011 //############################################################################# 00012 00013 #ifndef __U_LISTS_H 00014 #define __U_LISTS_H 00015 00016 #include "utils\u_values.h" // für _CURVECLASS, _FREEOBJ, Trace 00017 00018 //############################################################################## 00019 // TLnkContainer 00020 //############################################################################## 00021 00022 // Kontainer zum Verketten von void* -Elementen als doppelt verkettete Liste 00023 // Zugriff nur durch dieses Subsystem 00024 class TLnkContainer { 00025 friend class TLnkList; 00026 friend class TIndList; 00027 00028 private: 00029 TLnkContainer(void *const aData, TLnkList &aList); 00030 00031 // ==> stimmen <aList> und <m_List> überein ? 00032 bool IsElementOf(const TLnkList *const aList) const; 00033 00034 // ATTRIBUT(E) 00035 private: 00036 void *const m_Data; 00037 00038 TLnkList &m_List; 00039 00040 TLnkContainer *m_Prev; 00041 TLnkContainer *m_Next; 00042 }; 00043 00044 //############################################################################## 00045 // TLnkList 00046 //############################################################################## 00047 00048 // doppelt verkettete Liste 00049 // Zugriff nur über Container und dieses Subsystem 00050 class _CURVECLASS TLnkList { 00051 private: 00052 TLnkList(const TLnkList& aList) : m_FailIfNull(aList.m_FailIfNull), m_FailIfExists(aList.m_FailIfExists), m_AutoDelete(aList.m_AutoDelete), m_First(0), m_Last(0) {}; // kein Copy-Konstruktor 00053 TLnkList &operator= (const TLnkList&) { return *this; }; // kein Zuweisungsoperator 00054 00055 public: 00056 TLnkList(bool aFailIfNull= true, bool aFailIfExists= true, bool aAutoDelete= false); 00057 virtual ~TLnkList(); 00058 00059 // gibt das Element aus dem Container zurück 00060 // (1) wenn <m_AutoDelete>==true darf das Element nicht selbst mit delete freigegeben werden! 00061 // ==> das im Container verpackte Element 00062 void *GetAt(TLnkContainer &aContainer) const; 00063 00064 // fügt <aData> am Anfang der Liste ein 00065 // (1) wenn <m_FailIfExists>==true und <aData> bereits in der Liste, dann wird <aData> nicht eingefügt 00066 // (2) wenn <m_FailIfNull>==true und <aData>==0 ist, wird <aData> nicht eingefügt 00067 // ==> wurde <aData> eingefügt 00068 // bei (1) und (2) ist der Rückgabewert false 00069 bool Insert(void *const aData); 00070 00071 // fügt <aData> am Ende der Liste ein 00072 // (1) wenn <m_FailIfExists>==true und <aData> bereits in der Liste, dann wird <aData> nicht eingefügt 00073 // (2) wenn <m_FailIfNull>==true und <aData>==0 ist, wird <aData> nicht eingefügt 00074 // ==> wurde <aData> eingefügt 00075 // bei (1) und (2) ist der Rückgabewert false 00076 bool Append(void *const aData); 00077 00078 // fügt <aData> VOR <aContainer> ein 00079 // (0) wenn <aContainer>==0 wird am Anfang der Liste eingefügt - siehe Insert 00080 // (1) wenn <m_FailIfExists>==true und <aData> bereits in der Liste, dann wird <aData> nicht eingefügt 00081 // (2) wenn <m_FailIfNull>==true und <aData>==0 ist, wird <aData> nicht eingefügt 00082 // ==> wurde <aData> eingefügt 00083 // bei (1) und (2) ist der Rückgabewert false 00084 bool InsBefore(TLnkContainer *aContainer, void *const aData); 00085 00086 // fügt <aData> NACH <aContainer> ein 00087 // (0) wenn <aContainer>==0 wird am Ende der Liste eingefügt - siehe Append 00088 // (1) wenn <m_FailIfExists>==true und <aData> bereits in der Liste, dann wird <aData> nicht eingefügt 00089 // (2) wenn <m_FailIfNull>==true und <aData>==0 ist, wird <aData> nicht eingefügt 00090 // ==> wurde <aData> eingefügt 00091 // bei (1) und (2) ist der Rückgabewert false 00092 bool AddAfter(TLnkContainer *aContainer, void *const aData); 00093 00094 // entfernt <aContainer> 00095 // (1) wenn <m_AutoDelete>==true und das in <aContainer> liegende Non-Null-Element einzigartig in der Liste ist, wird das Element entfernt und mit delete freigegeben 00096 // ==> das entfernte Element 00097 // bei (1) ist der Rückgabewert 0 00098 void *Remove(TLnkContainer &aContainer); 00099 00100 // entfernt alle Element aus der Liste 00101 // bei <m_AutoDelete>==true werden die Non-Null-Elemente mit delete freigegeben 00102 virtual void Clear(); 00103 00104 // entfernt <aContainer> und Folgeelemente 00105 // bei <m_AutoDelete>==true werden einzigartige Non-Null-Elemente mit delete freigegeben 00106 void CutList(TLnkContainer &aContainer); 00107 00108 private: 00109 // sucht nach dem nächsten Container, der <aData> beinhaltet - die Suche beginnt bei <aStart> 00110 // ist <aStart>==0, beginnt die Suche am Anfang 00111 // ==> der gefundene Container; ggf. 0 00112 TLnkContainer *Find(void *aData, TLnkContainer *aStart=0); 00113 00114 // ATTRIBUT(E) 00115 protected: 00116 const bool m_FailIfNull; // Null-Elemente dürfen nicht eingefügt werden 00117 const bool m_FailIfExists; // Elemente dürfen nicht mehrfach eingefügt werden 00118 const bool m_AutoDelete; // Non-Null-Elemente mit delete freigeben, wenn letztes Vorkommen mit Remove bzw. Clear entfernt wird 00119 00120 TLnkContainer *m_First; 00121 TLnkContainer *m_Last; 00122 }; 00123 00124 //############################################################################## 00125 // TIndList 00126 //############################################################################## 00127 00128 typedef unsigned long TIndex; 00129 00130 // Liste von void* -Elementen; Zugriff per Index, d.h. [0...GetCount()-1] 00131 // ***In der DEBUG-Version wird zusätzlich eine TraceErr-Fehlermeldung ausgegeben! 00132 class _CURVECLASS TIndList : protected TLnkList { 00133 public: 00134 TIndList(bool aFailIfNull= true, bool aFailIfExists= true, bool aAutoDelete= false); 00135 00136 // (0) Bei einem zu großen Index wird das letzte Element zurückgegeben.*** 00137 // (E) Ist die Liste leer, wird 0 zurückgegeben.*** 00138 // <aValid> wird true gesetzt, wenn <aIndex> gültig ist und die Liste nicht leer ist; sonst false. 00139 // ==> das Element an Position <aIndex> 00140 void *GetAt(TIndex aIndex, bool &aValid) const; 00141 00142 // WIEVOR, jedoch ohne aValid - d.h. ein zu großer Index oder eine leere Liste sind für den Aufrufer nicht nachvollziehbar 00143 void *GetAt(TIndex aIndex) const; 00144 void *operator[] (TIndex aIndex) const; 00145 00146 // fügt <aData> am Anfang bzw. am Ende der Liste ein 00147 bool Insert(void *const aData); 00148 bool Append(void *const aData); 00149 00150 // fügt <aData> VOR dem Element an Position <aIndex> ein 00151 // (E) Bei einem zu großen Index oder einer leeren Liste wird am Ende eingefügt.*** 00152 // (1) und (2) und Rückgabewert gelten von TLnkList::InsBefore 00153 bool InsBefore(TIndex aIndex, void *const aData); 00154 00155 // fügt <aData> NACH dem Element an Position <aIndex> ein 00156 // (E) Bei einem zu großen Index oder einer leeren Liste wird am Ende eingefügt.*** 00157 // (1) und (2) und Rückgabewert gelten von TLnkList::AddAfter 00158 bool AddAfter(TIndex aIndex, void *const aData); 00159 00160 // entfernt das Element an Position <aIndex> 00161 // (0) Bei einem zu großen Index wird das letzte Element entfernt.*** 00162 // (E) Ist die Liste leer, wird nur 0 zurückgegeben.*** 00163 // (1) und Rückgabewert gelten von TLnkList::Remove 00164 void *Remove(TIndex aIndex); 00165 00166 // sucht das Element <aData> 00167 // (0) Ist <aData> nicht in der Liste, wird 0 zurückgegeben.*** 00168 // (E) Ist die Liste leer, wird nur 0 zurückgegeben.*** 00169 // (1) und Rückgabewert gelten von TLnkList::Remove 00170 void *RemoveData(void *aData); 00171 00172 // entfernt das Element an Position <aIndex> und alle Folgeelemente 00173 // (E) Bei einem zu großen Index oder einer leeren Liste wird keine Aktion ausgeführt.*** 00174 void CutList(TIndex aSize); 00175 00176 // wie TLnkList::Clear 00177 virtual void Clear(); 00178 00179 // ==> Anzahl der Elemente 00180 TIndex GetCount() const; 00181 00182 private: 00183 // ==> der Container an Position <aIndex> 00184 // (0) Bei einem zu großen Index wird in der RELEASE-Version das letzte Element zurückgegeben.*** 00185 // (E) Ist die Liste leer, wird 0 zurückgegeben.*** 00186 TLnkContainer *Find(TIndex aIndex) const; 00187 00188 // ATTRIBUT(E) 00189 protected: 00190 TIndex m_Count; 00191 }; 00192 00193 //############################################################################## 00194 // TIntList 00195 //############################################################################## 00196 00197 // Liste von int -Elementen; Zugriff per Index, d.h. [0...GetCount()-1] 00198 // ***In der DEBUG-Version wird zusätzlich eine TraceErr-Fehlermeldung ausgegeben! 00199 class _CURVECLASS TIntList : protected TIndList { 00200 public: 00201 // erzeugt eine Liste mit <aSize> leeren Elementen, deren Wert <aDefaultValue> entspricht 00202 TIntList(const TIndex &aSize= 0, const int &aDefaultValue= 0); 00203 00204 TIntList(const TIntList &aList); // Copy-Konstruktor, die eine neue Liste mit den gleichen Elementen erzeugt 00205 TIntList &operator= (const TIntList &aList); // Zuweisungsoperator, der eine neue Liste mit den gleichen Elementen erzeugt 00206 00207 // (E) Bei einem zu großen Index oder wenn die Liste leer ist, wird <m_DefaultValue> zurückgegeben.*** 00208 // <aValid> wird true gesetzt, wenn <aIndex> gültig ist und die Liste nicht leer ist; sonst false. 00209 // ==> das Element an Position <aIndex> 00210 int GetAt(const TIndex &aIndex, bool &aValid) const; 00211 00212 // WIEVOR, jedoch ohne aValid - d.h. es ein zu großer Index oder eine leere Liste sind für den Aufrufer nicht nachvollziehbar, es wird nur <m_DefaultValue> zurückgegeben 00213 int GetAt(const TIndex &aIndex) const; 00214 00215 // Lesezugriff: 00216 // wie GetAt(...) 00217 // Schreibzugriff: 00218 // (E) Bei einem zu großen Index oder wenn die Liste leer ist, wird kein Wert gesetzt.*** 00219 // Dazu wird eine Kopie von <m_DefaultValue> zurückgegeben. Diese kann geändert werden, hat aber keine Wirkung auf andere Elemente der Liste oder <m_DefaultValue> selbst. 00220 int &operator[] (const TIndex &aIndex); 00221 00222 // setzt <aValue> als Element an Position <aIndex> 00223 // (E) Bei einem zu großen Index oder wenn die Liste leer ist, wird kein Wert gesetzt.*** 00224 // ==> wurde der Wert gesetzt 00225 bool SetAt(const TIndex &aIndex, const int &aValue); 00226 00227 // fügt <aValue> am Anfang bzw. am Ende der Liste ein 00228 bool Insert(const int &aValue); 00229 bool Append(const int &aValue); 00230 00231 // fügt <aValue> VOR bzw. NACH dem Element an Position <aIndex> ein 00232 bool InsBefore(const TIndex &aIndex, const int &aValue); 00233 bool AddAfter(const TIndex &aIndex, const int &aValue); 00234 00235 // ändert die Größe der Liste auf <aSize>, indem entweder <aDefaultValue> am Ende eingefügt werden ODER die letzten Elemente entfernt werden 00236 void SetCount(const TIndex &aSize, const int &aDefaultValue); 00237 00238 // wie SetCount(aSize, m_DefaultValue) 00239 void SetCount(const TIndex &aSize); 00240 00241 // Element entfernen; Größe ermitteln 00242 TIndList::Remove; 00243 TIndList::Clear; 00244 TIndList::GetCount; 00245 00246 private: 00247 int m_DefaultValue; 00248 }; 00249 00250 //############################################################################## 00251 // TFloatList 00252 //############################################################################## 00253 00254 // Liste von float -Elementen; Zugriff per Index, d.h. [0...GetCount()-1] 00255 // Beschreibung siehe TIntList 00256 class _CURVECLASS TFloatList : protected TIndList { 00257 public: 00258 TFloatList(const TIndex &aSize= 0, const float &aDefaultValue= 0.0); 00259 TFloatList(const TFloatList &aList); 00260 TFloatList &operator= (const TFloatList &aList); 00261 00262 float GetAt(const TIndex &aIndex, bool &aValid) const; 00263 float GetAt(const TIndex &aIndex) const; 00264 float &operator[] (const TIndex &aIndex); 00265 bool SetAt(const TIndex &aIndex, const float &aValue); 00266 00267 bool Insert(const float &aValue); 00268 bool Append(const float &aValue); 00269 00270 bool InsBefore(const TIndex &aIndex, const float &aValue); 00271 bool AddAfter(const TIndex &aIndex, const float &aValue); 00272 00273 void SetCount(const TIndex &aSize, const float &aDefaultValue); 00274 void SetCount(const TIndex &aSize); 00275 00276 // Element entfernen; Größe ermitteln 00277 TIndList::Remove; 00278 TIndList::Clear; 00279 TIndList::GetCount; 00280 00281 private: 00282 float m_DefaultValue; 00283 }; 00284 00285 //############################################################################## 00286 // TPoint 00287 //############################################################################## 00288 00290 class _CURVECLASS TPoint { 00291 public: 00292 TPoint(); 00293 TPoint(const TPoint &aPoint); 00294 TPoint &operator= (const TPoint &aPoint); 00295 00296 // Direktzugriff auf Pt 00297 float GetAt(const TIndex &aIndex, bool &aValid) const; 00298 float GetAt(const TIndex &aIndex) const; 00299 float &operator[] (const TIndex &aIndex); 00300 bool SetAt(const TIndex &aIndex, const float &aValue); 00301 00302 TFloatList Pt; 00303 BOOL Valid; 00304 }; 00305 00306 //############################################################################## 00307 // TPointList 00308 //############################################################################## 00309 00310 // Liste von TPoint -Elementen; Zugriff per Index, d.h. [0...GetCount()-1] 00311 // Beschreibung siehe TIntList 00312 class _CURVECLASS TPointList : protected TIndList { 00313 public: 00314 TPointList(const TIndex &aSize= 0, TPoint *aDefaultValue= 0); 00315 TPointList(const TPointList &aList); 00316 TPointList &operator= (const TPointList &aList); 00317 00318 TPoint &GetAt(const TIndex &aIndex, bool &aValid) const; 00319 TPoint &GetAt(const TIndex &aIndex) const; 00320 TPoint &operator[] (const TIndex &aIndex) const; 00321 00322 bool Insert(const TPoint &aValue); 00323 bool Append(const TPoint &aValue); 00324 00325 bool InsBefore(const TIndex &aIndex, const TPoint &aValue); 00326 bool AddAfter(const TIndex &aIndex, const TPoint &aValue); 00327 00328 void SetCount(const TIndex &aSize, const TPoint &aDefaultValue); 00329 void SetCount(const TIndex &aSize); 00330 00331 // Element entfernen; Größe ermitteln 00332 TIndList::Remove; 00333 TIndList::Clear; 00334 TIndList::GetCount; 00335 00336 private: 00337 TPoint m_DefaultValue; 00338 }; 00339 00340 /* Anwendungsbeispiel1: 00341 TPointList plist(0); // Liste soll erstmal Länge 0 haben (keine Punkte enthalten) 00342 // Punkt dynamisch erzeugen und initailisieren 00343 TPoint *pkt1= new TPoint(); 00344 pkt1->Pt.SetAt(0, 2); 00345 pkt1->Pt.SetAt(1, 4); 00346 pkt1->Pt.SetAt(2, 6); 00347 pkt1->Valid= TRUE; 00348 // Punkt ans Listenende (weil vorher leer, nun das einigste Element) 00349 plist.Append(*pkt1); 00350 delete pkt1; // können wir nun freigeben, beim Einfügen von Punkten werden diese KOPIERT! 00351 // Punkt auf Stack erzeugen, wird am Ende des Blockes automatisch vom Programm freigegeben 00352 TPoint pkt2; 00353 pkt2.Pt.SetAt(0, 1); 00354 pkt2.Pt.SetAt(1, 2); 00355 pkt2.Pt.SetAt(2, 3); 00356 pkt2.Valid= FALSE; 00357 plist.Append(pkt2); // pkt2 wird von Append kopiert, können wir also weiterverwenden 00358 // und deshalb verwenden wir pkt2 noch einmal 00359 pkt2.Pt.SetAt(0, 4); 00360 pkt2.Pt.SetAt(1, 5); 00361 pkt2.Pt.SetAt(2, 6); 00362 pkt2.Valid= TRUE; 00363 plist.Append(pkt2); 00364 // jetzt ändern wir nochmal, direkt in der Liste 00365 plist[0].Pt.SetAt(1, 7); // wir entscheiden uns um und setzen Koordinate #1 von pkt1 statt auf 4 (siehe oben) jetzt auf 7 00366 plist[1].Pt.SetAt(2, 99); // und hier wird Koordinate #2 von pkt2 geändert, von 3 auf 99 00367 // Mal sehen was angekommen ist: Koordinate #0 sollte immernoch 2 sein 00368 // #1 haben wir ja auch 7 geändert 00369 TraceMsg( plist[0].Pt[0] ); 00370 TraceMsg( plist[0].Pt[1] ); 00371 // Koordinate #0 ist 1 00372 // #2 geändert auf 99 00373 TraceMsg( plist[1].Pt[0] ); 00374 TraceMsg( plist[1].Pt[2] ); 00375 // Koordinate #1 ist 5 00376 // #2 ist 6 00377 TraceMsg( plist[2].Pt[1] ); 00378 TraceMsg( plist[2].Pt[2] ); 00379 // alle dynamisch erzeugten Punkte, die in plist eingefügt werden, werden automatisch im Destruktor zerstört 00380 */ 00381 00382 /* Anwendungsbeispiel2: 00383 TPointList plist(10); // Liste soll erstmal Länge 10 haben (Punkte #0..#9) 00384 for (int j= 0; j<10; j++) { 00385 plist[j].Pt.SetAt(0, 3*j); 00386 plist[j].Pt.SetAt(1, 3*j + 1); 00387 plist[j].Pt.SetAt(2, 3*j + 2); 00388 plist[j].Valid= j % 2; // ständjger Wechsel von Valid zwischen 0 und 1 00389 } 00390 // Mal sehen was angekommen ist: Berechnungen stammen aus der for-Schleife - hinten stehen die prognostizierten Ausgaben 00391 j= 0; 00392 TraceMsg( plist[j].Pt[0] ); // 3*j = 3*0 = 0 00393 TraceMsg( plist[j].Pt[1] ); // 3*j + 1= 3*0 + 1= 1 00394 TraceMsg( plist[j].Valid ); // j % 2 = 0 % 2 = 0 00395 j= 3; 00396 TraceMsg( plist[j].Pt[0] ); // 3*j = 3*3 = 9 00397 TraceMsg( plist[j].Pt[2] ); // 3*j + 2= 3*3 + 2= 11 00398 TraceMsg( plist[j].Valid ); // j % 2 = 3 % 2 = 1 00399 j= 9; 00400 TraceMsg( plist[j].Pt[1] ); // 3*j + 1= 3*9 + 1= 28 00401 TraceMsg( plist[j].Pt[2] ); // 3*j + 2= 3*9 + 2= 29 00402 TraceMsg( plist[j].Valid ); // j % 2 = 9 % 2 = 1 00403 // alle enthaltenen Punkte, werden automatisch im Destruktor zerstört 00404 */ 00405 00406 #endif // __U_LISTS_H

Erzeugt am Sat Nov 13 12:48:11 2004 für XCTL32 von doxygen 1.3.7