unit generico;
{$mode objfpc}
{$INTERFACES CORBA}
interface
uses sysutils,eccezioni;
type generic tipoDato<Tipo>=record
cella:Tipo;
end;
type generic ElementoLista<_T> = Interface
Function GetItem(AIndex : Integer) : _T;
Procedure SetItem(AIndex : Integer; AValue : _T);
Function GetCount : Integer;
procedure addItem(AValue : _T);
procedure Clear;
function lunghezza:integer;
Property Items [AIndex : Integer] : _T Read GetItem Write SetItem;
Property Count : Integer Read GetCount;
end;
type generic Lista<Tipo>=class (TObject, specialize ElementoLista<Tipo>)
private
elementi:array of Tipo;
caricati:integer;
Function GetItem(AIndex : Integer) : Tipo;
Procedure SetItem(AIndex : Integer; AValue : Tipo);
Function GetCount : Integer;
procedure raddoppiaMemoria;
public
constructor crea();
constructor crea(dimensione:word);
constructor crea(dimensione:word; zero:Tipo);
procedure addItem(AValue : Tipo);
procedure Clear;
function lunghezza:integer;
Property Items [AIndex : Integer] : Tipo Read GetItem Write SetItem;
Property Count : Integer Read GetCount;
end;
implementation
constructor Lista.crea();
begin
setLength(elementi, 10);
caricati:=0;
end;
constructor Lista.crea(dimensione:word);
begin
if dimensione < 5 then dimensione:=5;
if dimensione > 10000 then dimensione:=10000;
setLength(elementi, dimensione);
caricati:=0;
end;
constructor Lista.crea(dimensione:word; zero:Tipo);
var i:integer;
begin
if dimensione < 5 then dimensione:=5;
if dimensione > 10000 then dimensione:=10000;
setLength(elementi, dimensione);
i:=0;
caricati:=dimensione;
while i < caricati do
begin
elementi[i]:=zero;
i:=i + 1;
end;
end;
Function Lista.GetItem(AIndex : Integer) : Tipo;
var esito:Tipo;
begin
if (AIndex < caricati) and (AIndex >= 0) then
begin
esito:=elementi[AIndex];
end
else
raise FuoriRange.crea(Format('Impossibile accedere alla cella %d', [AIndex]));
GetItem:=esito;
end;
procedure Lista.addItem(AValue : Tipo);
begin
if caricati >= length(elementi) then
raddoppiaMemoria;
elementi[caricati]:=AValue;
caricati:=caricati + 1;
end;
procedure Lista.Clear;
begin
caricati:=0;
end;
Procedure Lista.SetItem(AIndex : Integer; AValue : Tipo);
begin
if (AIndex < 0) or (AIndex >= caricati) then
begin
raise FuoriRange.crea(Format('Impossibile accedere alla cella %d', [AIndex]));
end;
elementi[AIndex]:=AValue;
end;
Function Lista.GetCount : Integer;
begin
GetCount:=caricati;
end;
function Lista.lunghezza:integer;
begin
lunghezza:=length(elementi);
end;
procedure Lista.raddoppiaMemoria;
var nuova:integer;
begin
nuova:=length(elementi) * 2;
if (nuova > 10000) or (nuova < 1) then
begin
raise FuoriRange.crea('Impossibile allocare più di 10''000 elementi.');
end;
setLength(elementi, nuova);
end;
begin
// non fa nulla
end.