Thema: Delphi The Generics Stack

Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#1

The Generics Stack

  Alt 1. Nov 2009, 18:34
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
Angehängte Dateien
Dateityp: pas genstack_236.pas (5,9 KB, 42x aufgerufen)
Dateityp: pas genstack_200.pas (6,6 KB, 17x aufgerufen)
$2B or not $2B
  Mit Zitat antworten Zitat