Ja, ordinal geht es prima, aber am schönsten mit strings. Die
unit TypeInfo hat zwei funktionen die das konvertieren von set-properties beherrschen. Leider ist das auf auf properties spezialisiert. Ich hatte das mal entspezialisiert, sodass es mit normalen typeInfos geht:
Delphi-Quellcode:
uses typInfo, RTLConsts;
...
function SetToStr(SetTypeInfo:PTypeInfo;value:integer;Brackets:boolean=true):string;
var
S: TIntSet;
TypeInfo: PTypeInfo;
compTypeDate: PTypeData;
I: Integer;
begin
Result := '';
Integer(S) := Value;
TypeInfo := GetTypeData(SetTypeInfo)^.CompType^;
compTypeDate := GetTypeData(TypeInfo);
for I := compTypeDate.MinValue to compTypeDate.MaxValue do
if I in s then
begin
if Result <> '' then
Result := Result + ',';
Result := Result + GetEnumName(TypeInfo, I);
end;
if Brackets then Result := '[' + Result + ']';
end;
function StrToSet(SetTypeInfo:PTypeInfo; const Value: string): Integer;
var
P: PChar;
EnumName: string;
EnumValue: Longint;
EnumInfo: PTypeInfo;
// grab the next enum name
function NextWord(var P: PChar): string;
var
i: Integer;
begin
i := 0;
// scan til whitespace
while not (P[i] in [',', ' ', #0,']']) do
Inc(i);
SetString(Result, P, i);
// skip whitespace
while P[i] in [',', ' ',']'] do
Inc(i);
Inc(P, i);
end;
begin
Result := 0;
if Value = '' then Exit;
P := PChar(Value);
// skip leading bracket and whitespace
while P^ in ['[',' '] do
Inc(P);
EnumInfo := GetTypeData(SetTypeInfo)^.CompType^;
EnumName := NextWord(P);
while EnumName <> '' do
begin
EnumValue := GetEnumValue(EnumInfo, EnumName);
if EnumValue < 0 then
raise EPropertyConvertError.CreateResFmt(@SInvalidPropertyElement, [EnumName]);
Include(TIntegerSet(Result), EnumValue);
EnumName := NextWord(P);
end;
end;
Damit kann man super leicht konverieren:
Delphi-Quellcode:
type
T8BitSet = set of (bit_0, bit_1, bit_2, bit_3, bit_4, bit_5, bit_6, bit_7);
...
var
Bits:T8BitSet;
s:string;
begin
Bits := [bit_2, bit_4, bit_7];
...
s := setToStr(typeInfo(T8BitSet), PInteger(@Bits)^, true);
..
PInteger(@Bits)^ := strToSet(typeInfo(T8BitSet), s);
end;
Entsprechend leicht dürfte das speichern in eine datei sein -> stringStream oder so.
Und wenn es hier nicht gebraucht wird, dann sicher später von jemand anderem!
//edit:
PS:@Kedariodakon: Du hast quasi gerade entdeckt, dass jeder eintrag in einem set einem bit entspricht...was auch logisch und effizient ist.
//edit2: blöde pointer
mâxîmôv.
{KDT}