[fpc-pascal] Unrelated type helpers with the same members? Implement an interface with a type helper?

Ondrej Pokorny lazarus at kluug.net
Sun Dec 25 13:27:43 CET 2022


Am 23.12.2022 um 15:50 schrieb Andrew Haines via fpc-pascal:
> Error: Ordinal expression expected
>
> [TEnumAttr(['YES', 'NO', 'COULD_BE'])]

There is another (and cleaner) approach that uses an abstract attribute 
class. See attachment.

The advantage is that the compiler warns you with an error when you add 
a new value to the enum and you don't declare a string value for it.

Ondrej
-------------- next part --------------
program EnumAttrTest;

{$mode objfpc}{$H+}
{$modeswitch prefixedattributes}

uses
  SysUtils, TypInfo;

type
  EnumValues = class(TCustomAttribute)
  public
    function OrdToStr(const aValue: Integer): string; virtual; abstract;
    constructor Create;
  end;

  MyEnumValues = class(EnumValues)
  public
    function OrdToStr(const aValue: Integer): string; override;
  end;

  [MyEnumValues]
  TMyEnum = (meYes, meNo, meCouldBe);

{ EnumValues }

constructor EnumValues.Create;
begin
end;

{ MyEnumValues }

function MyEnumValues.OrdToStr(const aValue: Integer): string;
const
  cValues: array[TMyEnum] of string = ('YES', 'NO', 'COULD_BE');
begin
  Result := cValues[TMyEnum(aValue)];
end;

procedure WriteAllValues(const aTypInfo: PTypeInfo);
var
  xAttrs: PAttributeTable;
  xAttr: TCustomAttribute;
  I, V: Integer;
begin
  xAttrs := GetAttributeTable(aTypInfo);
  for I := 0 to xAttrs^.AttributeCount-1 do
  begin
    xAttr := GetAttribute(xAttrs, I);
    try
      if xAttr is EnumValues then
      begin
        for V := 0 to GetTypeData(aTypInfo)^.MaxValue do
          Writeln(EnumValues(xAttr).OrdToStr(V));
      end;
    finally
      xAttr.Free;
    end;
  end;
end;

begin
  WriteAllValues(PTypeInfo(TypeInfo(TMyEnum)));
  ReadLn;
end.



More information about the fpc-pascal mailing list