[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