delphi typeinfo установка и сравнение tkset
Мне нужна функция универсального сравнение set of T и функция универсальной установки set of T
function TMy.Compare<T>(var Instance, Value: T): boolean;
var
P: PTypeInfo;
begin
Result := False;
P := PTypeInfo(TypeInfo(T));
case P.Kind of
tkSet: begin
Result := PSetof(@Instance)^ = PSetof(@Value)^;
// setter Instance := Value;
end
else
raise Exception.Create('Error Message');
end;
end;
в каком варианте реализации всегда вернет false причем я понимаю что
PSetof(@Instance)^ это не совсем верно и после будут ошибки где то в коде.
как сделать верно?
Установить можно просто Instance := Value;
А вот как сравнить не совсем понятно
Уже рещил проблему. Она была в том что компилятор не знает размер Instance и Value
строка Result := PSetof(@Instance)^ = PSetof(@Value)^;
копирует всё начиная от @Instance до конца проги или sizeof(PSetof^) = 255
а нужно только 1 байт.
что бы решить это достаточно сделать правильное преобразование set of T к set of byte
class function AmRttiConvectrer.EnumsSetToByteSet<T>(enValue: T): TSetOf;
var PTyp:PTypeInfo;
v: TValue;
begin
Result:=[];
PTyp:= TypeInfo(T);
if (PTyp = nil) or (PTyp.Kind <> tkSet) then
raise Exception.Create('Error AmRttiConvectrer.EnumsSetToByteSet<T>');
v:=TValue.From(enValue);
v.ExtractRawData(@Result);
end;
Использовал TValue т.к в v.ExtractRawData(@Result);
вызывается inlineSize := GetInlineSize(FData.FTypeInfo);
который и вернет то кол-во байт которое нужно скопировать
Теперь готовый вариант выглядит так
type
TSetof = set of Byte;
PSetof = ^TSetof;
function TMy.Compare<T>(var Instance, Value: T): boolean;
var
P: PTypeInfo;
var V1,V2:TSetof;
begin
Result := False;
P := PTypeInfo(TypeInfo(T));
case P.Kind of
tkSet: begin
V1:= AmRttiConvectrer.EnumsSetToByteSet(Value);
V2:= AmRttiConvectrer.EnumsSetToByteSet(Instance);
Result:= V1 = V2;
end
else
raise Exception.Create('Error Message');
end;
end;