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

Reply via email to