читаемость повысить упаковкой record в variant... оригинально

Посмотри всетаки fpc-stl, всё для чего обычно пишутся велосипеды типа "массив любого типа" там есть
Модератор: Модераторы
если нет то выделение общего "абстрактного" родительского класса гораздо красивее-надежнее-быстрее упаковки
про вариант вообще давно пора забыть, ИМХО нафиг ненужен
Data:pointer будет самим данным если оно туда влезет и указателем на него если нет.
А как тип узнавать будем?
program test;
{$mode objfpc}{$h+}
uses
sysutils,strings;
type
chmorec = packed record
int_val: integer;
str_val: pchar;
end;
pchmorec = ^chmorec;
ANYTYPE = (INT_T,TEXT_T,REAL_T,CHMO_T);
anydatarecty = packed record
case data_type:ANYTYPE of
INT_T: (ival: integer);
TEXT_T: (tval: pchar);
REAL_T: (rval: double);
CHMO_T: (chmoval: chmorec);
end;
anydatarecarty = array of anydatarecty;
procedure addelem(var arr: anydatarecarty; atype:ANYTYPE; adataptr: pointer);
begin
setlength(arr,length(arr)+1);
arr[high(arr)].data_type:= atype;
case integer(atype) of
integer(INT_T): arr[high(arr)].ival:= integer(adataptr^);
integer(TEXT_T): arr[high(arr)].tval:= strnew(pchar(adataptr));
integer(REAL_T): arr[high(arr)].rval:= double(adataptr^);
integer(CHMO_T): begin
with arr[high(arr)].chmoval do begin
int_val:= (chmorec(adataptr^)).int_val;
str_val:= strnew((chmorec(adataptr^)).str_val);
end;
end;
end;
end;
var
arr1: anydatarecarty;
i1: integer;
pch1: pchar;
r1: double;
chmo1: chmorec;
i: integer;
begin
i1:= 1;
addelem(arr1,INT_T,@i1);
r1:= 1.234;
addelem(arr1,REAL_T,@r1);
pch1:= 'one';
addelem(arr1,TEXT_T,pch1);
chmo1.int_val:= 100;
chmo1.str_val:= 'hundred';
addelem(arr1,CHMO_T,@chmo1);
for i:= high(arr1) downto low(arr1) do begin
case integer(arr1[i].data_type) of
integer(INT_T): writeln('int val = ', arr1[i].ival);
integer(TEXT_T): begin
writeln('text val = ', arr1[i].tval);
dispose(arr1[i].tval);
end;
integer(REAL_T): writeln('real val = ', arr1[i].rval);
integer(CHMO_T): begin
writeln('chmo rec = {', arr1[i].chmoval.int_val,',',arr1[i].chmoval.str_val, '}');
dispose(arr1[i].chmoval.str_val);
end;
end;
end;
end.
program project1;
{$mode objfpc}{$h+}
uses
sysutils,strings;
const
TEST_CNT = 300000;
type
chmorec = packed record
int_val: integer;
str_val: pchar;
end;
pchmorec = ^chmorec;
baseObj = packed object
data:pointer;
procedure WriteDataWithType;virtual;abstract;
destructor done;virtual;
end;
INTObj = packed object(baseObj)
procedure WriteDataWithType;virtual;
constructor init(adataptr: pointer);
end;
TEXTObj = packed object(baseObj)
procedure WriteDataWithType;virtual;
constructor init(adataptr: pointer);
destructor done;virtual;
end;
REALObj = packed object(baseObj)
procedure WriteDataWithType;virtual;
constructor init(adataptr: pointer);
destructor done;virtual;
end;
CHMOObj = packed object(baseObj)
procedure WriteDataWithType;virtual;
constructor init(adataptr: pointer);
destructor done;virtual;
end;
anyObjarty = array of baseObj;
ANYTYPE = (INT_T,TEXT_T,REAL_T,CHMO_T);
destructor baseObj.done;
begin
end;
procedure INTObj.WriteDataWithType;
begin
writeln('int val = ', integer(data));
end;
constructor INTObj.init(adataptr: pointer);
begin
integer(data):=pinteger(adataptr)^;
end;
procedure TEXTObj.WriteDataWithType;
begin
writeln('text val = ', pchar(data));
end;
constructor TEXTObj.init(adataptr: pointer);
begin
pchar(data):=strnew(pchar(adataptr));
end;
destructor TEXTObj.done;
begin
strdispose(pchar(data));
end;
procedure REALObj.WriteDataWithType;
begin
writeln('real val = ', pdouble(data)^);
end;
constructor REALObj.init(adataptr: pointer);
begin
new(pdouble(data));
pdouble(data)^:=pdouble(adataptr)^;
end;
destructor REALObj.done;
begin
dispose(pdouble(data));
end;
procedure CHMOObj.WriteDataWithType;
begin
writeln('chmo rec = {', inttostr(pchmorec(data)^.int_val)+',',pchmorec(data)^.str_val,'}');
end;
constructor CHMOObj.init(adataptr: pointer);
begin
new(pchmorec(data));
pchmorec(data)^.int_val:=pchmorec(adataptr)^.int_val;
pchmorec(data)^.str_val:=strnew(pchmorec(adataptr)^.str_val);
end;
destructor CHMOObj.done;
begin
strdispose(pchmorec(data)^.str_val);
dispose(pchmorec(data));
end;
procedure addelem(var arr: anyObjarty; atype:ANYTYPE; adataptr: pointer);
begin
setlength(arr,length(arr)+1);
case atype of
INT_T: INTObj(arr[high(arr)]).init(adataptr);
TEXT_T:TEXTObj(arr[high(arr)]).init(adataptr);
REAL_T:REALObj(arr[high(arr)]).init(adataptr);
CHMO_T:CHMOObj(arr[high(arr)]).init(adataptr);
end;
end;
var
arr1: anyObjarty;
i1: integer;
pch1: pchar;
r1: double;
chmo1: chmorec;
i: integer;
begin
for i:= 0 to TEST_CNT do begin
i1:= 1;
addelem(arr1,INT_T,@i1);
r1:= 1.234;
addelem(arr1,REAL_T,@r1);
pch1:= 'one';
addelem(arr1,TEXT_T,pch1);
chmo1.int_val:= 100;
chmo1.str_val:= 'hundred';
addelem(arr1,CHMO_T,@chmo1);
end;
for i:= high(arr1) downto low(arr1) do
begin
arr1[i].WriteDataWithType;
arr1[i].done;
end;
end.
for i:= high(arr1) downto low(arr1) do
arr1[i].WriteDataWithType;
program test;
{$mode objfpc}{$h+}
uses
sysutils,strings;
const
TEST_CNT = 300000;
type
chmorec = packed record
int_val: integer;
str_val: pchar;
end;
pchmorec = ^chmorec;
ANYTYPE = (INT_T,TEXT_T,REAL_T,CHMO_T);
anydatarecty = packed record
case data_type:ANYTYPE of
INT_T: (ival: integer);
TEXT_T: (tval: pchar);
REAL_T: (rval: double);
CHMO_T: (chmoval: chmorec);
end;
anydatarecarty = array of anydatarecty;
procedure addelem(var arr: anydatarecarty; atype:ANYTYPE; adataptr: pointer);
begin
setlength(arr,length(arr)+1);
arr[high(arr)].data_type:= atype;
case integer(atype) of
integer(INT_T): arr[high(arr)].ival:= integer(adataptr^);
integer(TEXT_T): arr[high(arr)].tval:= strnew(pchar(adataptr));
integer(REAL_T): arr[high(arr)].rval:= double(adataptr^);
integer(CHMO_T): begin
with arr[high(arr)].chmoval do begin
int_val:= (chmorec(adataptr^)).int_val;
str_val:= strnew((chmorec(adataptr^)).str_val);
end;
end;
end;
end;
var
arr1: anydatarecarty;
i1: integer;
pch1: pchar;
r1: double;
chmo1: chmorec;
i: integer;
begin
for i:= 0 to TEST_CNT do begin
i1:= i;
addelem(arr1,INT_T,@i1);
r1:= double(i);
addelem(arr1,REAL_T,@r1);
pch1:= pchar(inttostr(i) + ' as text');
addelem(arr1,TEXT_T,pch1);
chmo1.int_val:= i;
chmo1.str_val:= pchar(inttostr(i) +' as text in CHMOREC');
addelem(arr1,CHMO_T,@chmo1);
end;
for i:= high(arr1) downto low(arr1) do begin
case integer(arr1[i].data_type) of
integer(INT_T): writeln('int val = ', arr1[i].ival);
integer(TEXT_T): begin
writeln('text val = ', arr1[i].tval);
dispose(arr1[i].tval);
end;
integer(REAL_T): writeln('real val = ', arr1[i].rval);
integer(CHMO_T): begin
writeln('chmo rec = {', arr1[i].chmoval.int_val,',',arr1[i].chmoval.str_val, '}');
dispose(arr1[i].chmoval.str_val);
end;
end;
end;
end.
debi12345 писал(а):Хочу спросить у знатоков - бага или фича ?Суть : ENUM-тип не принимается как ключ "CASE OF" если не привести его явно к типу INTEGER - и в "шапке", и в "ветках". (см. в примере в предыдущем посте).
все нормально принимается...
Сейчас этот форум просматривают: Yandex [Bot] и гости: 3