PDA

View Full Version : Generics in FPC



JSoftware
28-05-2007, 10:23 PM
Well I've been experimenting a bit. I've made them work to some extend but they seem very rigid(But I've had no funny errors yet)

I've made a small generic TList class including working example. Does anyone have an idea if you could extend this(or recode it) so it would work with normal records and simple types too?


program test;

{$MODE OBJFPC}

uses classes;

type
generic TGList<_T> = class(TList)
//TGList = class(TList)
protected
function Get(Index: Integer): _T;
procedure Put(Index: Integer; Item: _T);
public
function Add(Item: _T): Integer;
function Extract(Item: _T): _T;
function First: _T;
function IndexOf(Item: _T): Integer;
procedure Insert(Index: Integer; Item: _T);
function Last: _T;
function Remove(Item: _T): Integer;
property Items[Index: Integer]: _T read Get write Put; default;
end;

{ TGList }

function TGList.Add(Item: _T): Integer;
begin
result := inherited Add(Item);
end;

function TGList.Extract(Item: _T): _T;
begin
result := _T(inherited Extract(Item));
end;

function TGList.First: _T;
begin
Result := _T(inherited First);
end;

function TGList.Get(Index: Integer): _T;
begin
result := _T(Inherited Get(index));
end;

function TGList.IndexOf(Item: _T): Integer;
begin
result := Inherited IndexOf(item);
end;

procedure TGList.Insert(Index: Integer; Item: _T);
begin
Inherited Insert(index, Item);
end;

function TGList.Last: _T;
begin
Result := _T(inherited Last);
end;

procedure TGList.Put(Index: Integer; Item: _T);
begin
inherited Put(index, Item);
end;

function TGList.Remove(Item: _T): Integer;
begin
result := Inherited Remove(Item);
end;

type
TSalmon = class
name: string[5];
end;

TLakseList = specialize TGList<TSalmon>;

var x: TLakseList;

a,b: TSalmon;
i: integer;
begin
a := TSalmon.Create;
a.name := 'test1';
b := TSalmon.Create;
b.name := 'test2';

x := TLakseList.Create;

x.add(a);
x.add(b);

for I := 0 to x.count - 1 do
begin
writeln(x[i].name);
x[i].free;
end;

x.free;
end.

Srki_82
28-05-2007, 10:55 PM
TList is designed to hold pointers or anything that can be casted to pointer. Types larger than 4 bytes can't fit into array of pointer that is used in TList to hold data.

AFAIK you should code whole class from scratch and use array of _T to hold data.

JSoftware
28-05-2007, 11:36 PM
That was what I feared. Couldn't the Tlist just contain a class definition of a container class to store the data as a member? I know delphi supports "nested classes" but I can't find anything on it in Freepascal

Anyone?

alexione
29-05-2007, 07:51 AM
As Srki said, TList was designed to hold pointers, and there is no other information about the data it holds.

You should think of TList and TGList<_T> in the other direction: if you have TGList implement using array of _T, then you can simply say


type TList = TGList<Pointer>;

(if this is syntax which is supported in FPC)

Almindor
29-05-2007, 09:04 AM
Should be:


type TIntListList = specialize TGList<Integer>;

or so..

FPC generics syntax is still open to suggestion. But don't expect complete overhauls. There's a unit in fpc/trunk (sorry, cannot remember name) or perhaps also in latest beta with generic lists implementations already.

JSoftware
29-05-2007, 10:05 AM
I think the specialize keyword is quite ugly. What's actually the reason for it? Prevent mistakes?