Fun Code of the Day #1

unit uEnumConverter;

interface

type
  TEnum = record
  public
    class function AsString<T>(aEnum: T): string; static;
    class function AsInteger<T>(aEnum: T): Integer; static;
  end;

implementation

uses
      TypInfo
    ;

{ TEnum }

class function TEnum.AsString<T>(aEnum: T): string;
begin
  Result := GetEnumName(TypeInfo(T), AsInteger(aEnum));
end;

class function TEnum.AsInteger<T>(aEnum: T): Integer;
begin
  case Sizeof(T) of
    1: Result := pByte(@aEnum)^;
    2: Result := pWord(@aEnum)^;
    4: Result := pCardinal(@aEnum)^;
  end;
end;

end.

 

8 Replies to “Fun Code of the Day #1”

    • If you directly want to convert an enum to Integer I would not use that function,right.

      But as the AsInteger is used inside the AsString it is necessary unless you want to put that case into the AsString method. That is because Ord does not accept an argument of type T.

      • I was not talking about how to implement generic-based function using enumerates.

        My point was that why on earth would we have to use such a bloating TEnum.AsInteger(aEnum: T) function when you have the ord() built-in keyword available?

        Because of AsString?
        So yes, it may have been set private.
        But all this seems over-engineered to me…

        At asm level, using ord() “may” be a little more optimized, e.g. allowing the variable to stay at the CPU register level. Whereas using such a pointer redirection will force the variable to be allocated on the stack. But if it is to be called within AsString, so it is not a problem.

        From my experiment, code generation of inlined code may be pretty disappointing, even in latest versions of the Delphi compiler. Sometimes it is faster, sometimes a local function may be much faster.
        Current registration allocation is pretty limited in the Delphi compiler.

  1. It’d be even more fun with some commentary on why you believe it’s fun and examples of the code in use. Are these meant to be “record helpers” to add to an enum? It took me a bit to realize they don’t stand on their own.

    • Nope, but writing s := TEnum.AsString(someEnumVar) is the easiest and imo most readable way to turn an enum into a string these days.

  2. The AsString function will raise an access violation with TTestEmum = (test1=1,test5=5,test10=10);

Comments are closed.