Hi, all.
Aaron wrote:
> During the weekend I wrote a small class (really small) to encapsulate the
> Upper, Lower and Count of a set... You would need to create a
> class for each enumeration
> as it stands and is therefore a perfect example of why I'd like
> to see templates implemented
> in pascal... If anyone wants the class and example project (4k
> zip) personal email me and
> I'll send it... It's so simple I don't know if it's worth
> cluttering the delphi FTP...
[snippage]
Hrmm.. I've written an Object Pascal template/macro processor which we use
here at Profax. I have considered offering the processor as a public domain
utility and 'donating' the executable to the Delphi community since
Templates are pretty damn handy for efficient type-safe containers and are
the one thing I actually miss from C++.
Here is a snippet of sample template code to explain the grammar:
-- cut here --
unit tDList;
{
NewLook Doubly Linked List Class Template
Copyright (c) 1997, 1998 NewLook Through Old Windows Limited -
www.newlook.co.nz
}
{
Template Params
ItemType: 'Type of Item' = Pointer;
TypePrefix: 'Type Prefix' = u;
FreeItem(Item): 'Code for FreeItem' = FreeMem(Item);
}
{.DEFINE DEBUG}
interface
uses
Classes;
type
P|TypePrefix|DListNode = ^T|TypePrefix|DListNode;
T|TypePrefix|DListNode = record
Prior: P|TypePrefix|DListNode;
Next: P|TypePrefix|DListNode;
Item: ItemType;
end;
T|TypePrefix|DList = class
private
FOwnsItems: Boolean;
FCount: Integer;
FFirst: P|TypePrefix|DListNode;
FLast: P|TypePrefix|DListNode;
function GetItem(Node: P|TypePrefix|DListNode): ItemType;
procedure SetItem(Node: P|TypePrefix|DListNode; Item: ItemType);
...
function T|TypePrefix|DList.Delete(Node: P|TypePrefix|DListNode):
P|TypePrefix|DListNode;
begin
Assert(Node <> nil);
Result := Node^.Next;
if Node^.Prior = nil then
FFirst := Node^.Next
else
Node^.Prior^.Next := Node^.Next;
if Node^.Next = nil then
FLast := Node^.Prior
else
Node^.Next^.Prior := Node^.Prior;
if FOwnsItems then
FreeItem(Node^.Item);
Dispose(Node);
Dec(FCount);
{$IFDEF DEBUG}
Invariant;
{$ENDIF}
end;
-- cut here --
Explanation:
The Template Params section is a special comment block which the processor
understands. All macros and template parameters and there default expansions
(if any) are specified here.
The '|' character is the token pasteing operator and merges the various
portions into a single token (or word) e.g. P|TypePrefix|DListNode when
TypePrefix is u would result in the token PuDListNode being specific in the
output unit file.
The Template Processor is a Delphi executable which reads a template
specification unit (.nlt) and prompts for the paramater values and an output
unit name (.pas) which it then produces. The processor is a single pass
lexer/tokenizer/macro processor engine working largely upon memory streams
so it seems pretty quick. It actually depends upon itself now since the code
now uses a uDList<string> template internally rather than TStringLists
which gave a nice order of magnitude speed improvement for inserts and
deletes which macro engines by their nature do quite a bit off.
If anyone is interested, I can email them the .EXE and the complete
uDList.nlt as a sample. If lots of people end up asking, I'll put it up on
the 'NewLook Free Stuff' page at http://www.newlook.co.nz/freestuff.htm
instead.
TTFN,
Paul.
---------------------------------------------------------------------------
New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED]
Website: http://www.delphi.org.nz