dzTemplates is a set of pseudo templates for Delphi, Kylix and other Object Pascal compilers. It has grown out of my
article about pseudo templates. It is a set of type safe containers that can be easily used to store whatever data you want it to store.
The following containers are available:
-
List templates are the most generic containers. They come in two flavours: One that stores anything that can be typecasted into a pointer or an interface and one that assumes the items are descendants of TObject and "owns" them (that is, it will free them in its destructor). There is also an interface declaration for this kind of container (dzListInterfaceTemplate).
-
dzListTemplate / dzObjectListTemplate is the most generic container it stores its items in the order they are added.
-
dzSortedListTemplate / dzSortedObjectListTemplate is based on dzListTemplate and adds a sort order to it. It introduces methods for comparing two items and searching for them with a binary search algorithm. A Duplicates property like the one in TStringList determines what to do with duplicate items.
-
dzIntegerSortedListTemplate / dzIntegerSortedObjectListTemplate is a specialized descendant of dzSortedListTemplate which assumes that its items are sorted by an integer value.
-
dzStackTemplate / dzObjectStackTemplate are both stacks (LIFO = last in first out), again one for storing anything that can be typecasted to a pointer or interface and one for storing TObject descendants.
-
dzQueueTemplate is a queue (FIFO = first in first out) for storing anything that can be typecasted to a pointer or interface. There is currently no dzObjectQueueTemplate but I will add one shortly.
-
dzHashTemplate is a hash or associative array for storing items and accessing them via an associated string.
Just download a release archive and extract it or use Subversion access to the repository to get the files.
Since all templates are include files you must add the "templates" directory to your project's search path.
If you want to use the life templates (Delphi 2005 and later) copy them to your live templates directory.
The "examples" directory contains at least one example for each container type. Basically the way to use them is like this:
unit u_MyUnit;
uses
// necessary for the templates to work:
SysUtils,
Classes,
// declares whatever you want to store in the container:
u_MyDataItem;
{$define <some template specific conditional define>}
type
// several template specific type declarations
{$include '<name of the template file goes here>'}
type
TMyContainerType = class(<name of the template class>)
// you may add additional methods
// but the basic container functionality is already there
end;
implementation
// yes that's the same include as above, you need it twice
{$include '<name of the template file goes here>'}
end.
To create a new container using the live templates, add a new unit to your project move the cursor to the interface section and press Ctrl-J. You should now get a list of dzXxxx entries. Select one to active the life template, fill in the fields and enjoy. ;-)
As said above there are plenty of examples in the "examples" directory but since you probably want to see one before downloading the sources, here is the unit declaring a stack for storing integers:
unit u_IntegerStack;
uses
SysUtils,
Classes;
{$define __STACK_TEMPLATE__}
type
_STACK_ITEM_ = integer;
_STACK_CONTAINER_TYPE = TList;
_STACK_ANCESTOR_ = TObject;
{$include 't_dzStackTemplate.tpl'}
type
TIntegerStack = class(_STACK_TEMPLATE_)
end;
implementation
{$include 't_dzStackTemplate.tpl'}
end.
And here is some source that uses it:
program IntegerStackTest;
{$apptype console}
uses
u_IntegerStack;
var
MyIntegerStack: TIntegerStack;
begin
MyIntegerStack := TIntegerStack.Create;
try
MyIntegerStack.Push(0);
MyIntegerStack.Push(1);
MyIntegerStack.Push(2);
WriteLn('Stack Depth is now: ', MyIntegerStack.Depth);
WriteLn('Poping from the stack until it is empty:');
while not MyIntegerStack.IsEmpty do
WriteLn(MyIntegerStack.Pop);
finally
MyIntegerStack.Free;
end;
end.
As you can see it is very simple to use the templates.
Of course you probably already know how to write a stack class for integers yourself or you have been using the TStack class that comes with Delphi (see the Containrs unit if you didn't know there is one).
In the first case you had to do the work again if you wanted to store lets say singles(singles are also 4 bytes so they can be typecasted to a pointer) instead of integers. This always introduces the danger of making a mistake in the rewrite. Even worse you end up with two copies of the code that basically does the same, so every time you want to fix a bug (OK you don't make mistakes so there won't be any bugs ;-) ) or want to add a feature (e.g. add a property like IsEmpty or Depth) you must do it twice.
In the second case you had to write some ugly code like this every time you accessed the stack:
var
i: integer
{ ... }
MyStack.Push(pointer(0));
{ ... }
i := integer(MyStack.Pop);
This is not only cumbersome but also makes the code much less readable, just compare it to the example above and you will see what I mean.
Then of course there are code generators. They make work a little bit easier but they basically have the same problem of code duplication I already mentioned.
Project hosted on
.
This document was generated using AFT v5.096
|