program EnumToRecordImplicitBroken;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
type
TMyEnum = (entry_1, entry_2, entry_3, entry_4, entry_5, entry_6, entry_7, entry_8, entry_9, entry_10, entry_11, entry_12,
entry_13, entry_14, entry_15, entry_16, entry_17, entry_18, entry_19, entry_20, entry_21, entry_22, entry_23, entry_24,
entry_25, entry_26, entry_27, entry_28, entry_29, entry_30, entry_31, entry_32, entry_33, entry_34, entry_35, entry_36,
entry_37, entry_38, entry_39, entry_40, entry_41, entry_42, entry_43, entry_44, entry_45, entry_46, entry_47, entry_48,
entry_49, entry_50, entry_51, entry_52, entry_53, entry_54, entry_55, entry_56, entry_57, entry_58, entry_59, entry_60,
entry_61, entry_62, entry_63, entry_64, entry_65, entry_66, entry_67, entry_68, entry_69, entry_70, entry_71, entry_72,
entry_73, entry_74, entry_75, entry_76, entry_77, entry_78, entry_79, entry_80, entry_81, entry_82, entry_83, entry_84,
entry_85, entry_86, entry_87, entry_88, entry_89, entry_90, entry_91, entry_92, entry_93, entry_94, entry_95, entry_96,
entry_97, entry_98, entry_99, entry_100, entry_101, entry_102, entry_103, entry_104, entry_105, entry_106, entry_107,
entry_108, entry_109, entry_110, entry_111, entry_112, entry_113, entry_114, entry_115, entry_116, entry_117, entry_118,
entry_119, entry_120, entry_121, entry_122, entry_123, entry_124, entry_125, entry_126, entry_127, entry_128, entry_129,
entry_130, entry_131, entry_132, entry_133, entry_134, entry_135, entry_136, entry_137, entry_138, entry_139, entry_140,
entry_141, entry_142, entry_143, entry_144, entry_145, entry_146, entry_147, entry_148, entry_149, entry_150, entry_151,
entry_152, entry_153, entry_154, entry_155, entry_156, entry_157, entry_158, entry_159, entry_160, entry_161, entry_162,
entry_163, entry_164, entry_165, entry_166, entry_167, entry_168, entry_169, entry_170, entry_171, entry_172, entry_173,
entry_174, entry_175, entry_176, entry_177, entry_178, entry_179, entry_180, entry_181, entry_182, entry_183, entry_184,
entry_185, entry_186, entry_187, entry_188, entry_189, entry_190, entry_191, entry_192, entry_193, entry_194, entry_195,
entry_196, entry_197, entry_198, entry_199, entry_200);
TMyEnumWrapper =
record
FMyEnumSet:
array [0 .. (Ord(High(TMyEnum))
div 32) + 1]
of Cardinal;
function ToString:
string;
procedure IndexOf(
const a: TMyEnum;
out Index: Integer;
out Mask: Cardinal);
inline;
procedure SetItem(
const a: TMyEnum);
inline;
procedure Create();
overload;
procedure Create(
const a: TMyEnum);
overload;
procedure Create(
const a:
array of TMyEnum);
overload;
class operator Implicit(
const a:
array of TMyEnum): TMyEnumWrapper;
overload;
class operator Implicit(
const a: TMyEnum): TMyEnumWrapper;
overload;
class operator In (
const a: TMyEnum;
const b: TMyEnumWrapper): Boolean;
end;
class operator TMyEnumWrapper.Implicit(
const a:
array of TMyEnum): TMyEnumWrapper;
begin
// in Delphi 12 ist das im Local Variables Window ein "Inaccessible value" -> da fängt der Fehler schon an
// in Delphi 11.3 steht im Local Variables Window ein "()" -> richtig und schön
Result.Create(a);
end;
procedure TMyEnumWrapper.Create;
begin
FillChar(Self, sizeof(TMyEnumWrapper), 0);
end;
procedure TMyEnumWrapper.Create(
const a:
array of TMyEnum);
var
i: Integer;
begin
Create();
for i := Low(a)
to High(a)
do
begin
SetItem(a[i]);
end;
end;
procedure TMyEnumWrapper.Create(
const a: TMyEnum);
begin
Create();
SetItem(a);
end;
class operator TMyEnumWrapper.Implicit(
const a: TMyEnum): TMyEnumWrapper;
begin
Result.Create();
end;
class operator TMyEnumWrapper.
In(
const a: TMyEnum;
const b: TMyEnumWrapper): Boolean;
var
i: Integer;
m: Cardinal;
begin
b.IndexOf(a, i, m);
Result := (b.FMyEnumSet[i]
and (m)) <> 0;
end;
procedure TMyEnumWrapper.IndexOf(
const a: TMyEnum;
out Index: Integer;
out Mask: Cardinal);
var
i: Integer;
begin
i := Ord(a);
Index := (i
div 32);
Mask := $01
shl (i - (
Index * 32));
// Maske (Bit)
end;
procedure TMyEnumWrapper.SetItem(
const a: TMyEnum);
var
i: Integer;
m: Cardinal;
begin
IndexOf(a, i, m);
FMyEnumSet[i] := (FMyEnumSet[i]
or m);
end;
function TMyEnumWrapper.ToString:
string;
var
i: Integer;
begin
Result := '
';
for i := 0
to Length(self.FMyEnumSet) - 1
do
begin
if (Result <> '
')
then
Result := Result + '
, ';
Result := Result + Ord(FMyEnumSet[i]).ToString;
end;
end;
procedure Main;
var
MyEnumWrapperVar: TMyEnumWrapper;
begin
MyEnumWrapperVar := [];
Writeln(MyEnumWrapperVar.ToString);
end;
begin
try
Main;
except
on E:
Exception do
Writeln(E.ClassName, '
: ', E.
Message);
end;
readln;
end.