Note that GetMem's use of PopCnt on a typecast set is implementation dependent, and works only for small sets (and here, of course, the set size cannot exceed 7).
Here's a fuller example.
program Project1;
{$Mode objfpc}{$H+}
{$ModeSwitch advancedrecords}
type
TDay = (dSun, dMon, dTue, dWed, dThu, dFri, dSat);
TDays = set of TDay;
{ TWeek }
TWeek = record
public
function AddedDay(aDay: TDay): Boolean;
function GetDayCount: Integer;
function RemovedDay(aDay:TDay): Boolean;
procedure Init;
procedure Report;
private
case Boolean of
True: (days: TDays);
False: (dwrd: DWord);
end;
{ TWeek }
procedure TWeek.Init;
begin
days := [];
end;
procedure TWeek.Report;
var
d: TDay;
s, ss: String;
begin
ss := '[';
case GetDayCount of
0: begin
ss := ss + ']';
WriteLn(ss, ' week is empty');
Exit;
end
else for d in TDay do
if (d in days) then
begin
WriteStr(s, d);
s := s + ', ';
ss := ss + s;
end;
Delete(ss, Pred(Length(ss)), 2);
ss := ss + ']';
WriteLn(ss,', day count = ',GetDayCount);
end;
end;
function TWeek.AddedDay(aDay: TDay): Boolean;
begin
case aDay in days of
True: Exit(False);
False: begin
Include(days, aDay);
Result := True;
end;
end;
end;
function TWeek.RemovedDay(aDay: TDay): Boolean;
begin
case aDay in days of
True: begin
Exclude(days, aDay);
Result := True;
end;
False: Exit(False);
end;
end;
function TWeek.GetDayCount: Integer;
begin
Exit(PopCnt(dwrd));
end;
var
d: TDay;
week: TWeek;
begin
with week do
begin
WriteLn(' initialising week record');
Init;
Report;
d := dMon;
WriteLn(' adding ',d);
AddedDay(d);
Report;
d := dThu;
WriteLn(' adding ', d);
AddedDay(d);
Report;
d := dTue;
WriteLn(' adding ', d);
AddedDay(d);
Report;
d:= dSat;
Writeln(' removing ', d);
if RemovedDay(d) then
Report
else WriteLn('day ',d,' is not in the week record, so was not removed');
d := dMon;
WriteLn(' removing ', d);
if RemovedDay(d) then
Report
else WriteLn('day ',d,' is not in the week record, so was not removed');
end;
WriteLn;
WriteLn('Press [Enter] to finish');
ReadLn;
end.