Moin ihr alle,
dieses winzige Produkt ist ein kleiner Stack (kann auch als Queue verwendet werden).
Dank der Generics kann man ihn in allen möglichen Formaten erstellen
und er ist auch noch threadsicher.
Delphi-Quellcode:
Type
TStack<Typ> = Class(TCriticalSection)
Public
Procedure Push (Const X: Typ);
Function Pop (Var X: Typ): Boolean; Overload;
Function Pop: Typ; Overload;
Function Count: Integer;
Function Empty: Boolean;
Function Unshift: Typ; Overload;
Function Unshift(Var X: Typ): Boolean; Overload;
Procedure Shift(Const X: Typ);
Procedure Lock;
Procedure Unlock;
Function isLocked: Boolean; // by another thread
Function Peek: Typ; // only if locked
Property Item[Index: Integer]: Typ; // only if locked (read only)
End;
Hab den kleinen allerdings mit einem dynamischen Array versehn, als Speicher.
Wollte erst eine verkettete Liste nehmen, aber so war einiges einfacher zu lösen.
So muß ich mich an vielen Stellen nicht selber um die Speicherverwaltung kümmern
(vorallen beim Einfügen und Entfernen von Elementen und natürlich auch beim Löschen des Stacks,
also abgesehn vom Shifting kümmert sich die Compilermagic um den Speicher)
Push > Element anhängen
Pop > letztes Element wieder rausholen
Shift > Element vorne einfügen
Unshift > erstes Element vorne rausziehen
Die Function von Pop und Unshift geben True zurück, wenn sie etwas vom Stack holen konnten und geben dieses, im Erfolgsfall, über den Var-Parameter aus.
Die entsprechenden Prozeduren erzeugen in soeinem Fall eine
Exception (ERangeError),
Count > gibt die Anzahl der enthaltenen Elemente zurück
Empty > sagt True, wenn nichts auf dem Stack liegt
Und nun noch ein paar Funktionen, wenn man mal mehrere Dinge zusammenhängend machen möchte.
Lock > sperrt den Stack
Unlock > gibt ihn wieder frei
isLocked > gibt Bescheid, ob grade er gesperrt ist (durch einen anderen Thread)
Es wird jeweils nur für andere Threads gesperrt.
Der eigene sperrende Thread kann machen, was er will.
Und die Sperrungen sind kumulativ.
Auf die letzten nun folgenden Funktionen ist nur zugreifbar, wenn der Stack/Queue gelockt ist.
Peek > oberstes Item ( Item[Count-1] ) auslesen
Item > beliebiges Item auslesen
Im Prinzip kümmert sich diese Klasse bei Allem, was kein Pointer/Objekt ist, um die komplette Speicherverwaltung.
Also bei String, Arrays, Interfaces und Records ... dort wird eine interne Kopie angelegt, bzw. die Referenzzählung erhöht, so daß die Klasse "komplett" im Besizt der Daten ist.
Delphi-Quellcode:
Type TStringStack = TGenStack<String>;
Var St: TStringStack;
S: String;
St := TStringStack.Create;
St.Push(S);
...
S := St.Pop;
St.Free;
//////////////////////////////////
Var St: TGenStack<TMyRecord>;
S: TMyRecord;
St := TGenStack<TMyRecord>.Create;
...
Im Prinzip könnte es hier gut mit dazupassen
Stack für beliebige Daten
Schlagwörter: TStack TQueue Stack Queue Deque (Double-Ended QUEue) Stapel Keller Schlange Stapelspeicher Kellerspeicher Warteschlange