Paste::View Paste

FPC Enum<>String2

Martok 2013-04-06 23:11:14
  1. program pEnumString;
  2. {$mode objfpc}{$H+}
  3.  
  4. uses
  5.   SysUtils, TypInfo;
  6.  
  7. type
  8.   generic TEnum<T> = class
  9.     class function {%H-}ToString(Value: T): String;
  10.     class function FromString(Str: String): T; overload;
  11.     class function FromString(Str: String; out Value: T): boolean; overload;
  12.   end;
  13.  
  14. class function TEnum.ToString(Value: T): String;
  15. Var
  16.   PS : PShortString;
  17.   TI : PTypeInfo;
  18.   PT : PTypeData;
  19.   num: Integer;
  20. begin
  21.   TI:= TypeInfo(T);
  22.   PT:= GetTypeData(TI);
  23.   if TI^.Kind=tkBool then begin
  24.     case Integer(Value) of
  25.       0,1:
  26.         Result:=BooleanIdents[Boolean(Value)];
  27.       else
  28.         Result:='';
  29.     end;
  30.   end else begin
  31.     num:= Integer(Value);
  32.     if (num>=PT^.MinValue) and (num<=PT^.MaxValue) then begin
  33.       PS:=@PT^.NameList;
  34.       dec(num, PT^.MinValue);
  35.       while num > 0 do begin
  36.         PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  37.         Dec(Num);
  38.       end;
  39.       Result:=PS^;
  40.     end else
  41.       Result:= '';
  42.   end;
  43. end;
  44.  
  45. class function TEnum.FromString(Str: String): T;
  46. begin
  47.   if not FromString(Str, Result) then
  48.     raise EConvertError.CreateFmt('"%s" is an invalid %s',[Str,PTypeInfo(TypeInfo(T))^.Name]);
  49. end;
  50.  
  51. class function TEnum.FromString(Str: String; out Value: T): boolean;
  52. Var
  53.   PS : PShortString;
  54.   PT : PTypeData;
  55.   Count : longint;
  56.   sName: shortstring;
  57.   TI : PTypeInfo;
  58. begin
  59.   TI:= TypeInfo(T);
  60.   PT:= GetTypeData(TI);
  61.   Result:= False;
  62.   If Length(Str)=0 then
  63.     exit;
  64.   sName := Str;
  65.  
  66.   if TI^.Kind=tkBool then begin
  67.     If CompareText(BooleanIdents[false],Str)=0 then
  68.       Value:= T(0)
  69.     else if CompareText(BooleanIdents[true],Str)=0 then
  70.       Value:= T(1);
  71.     Result:= true;
  72.   end else begin
  73.     PS:=@PT^.NameList;
  74.     Count := 0;
  75.     While (PByte(PS)^<>0) do begin
  76.       If ShortCompareText(PS^, sName) = 0 then begin
  77.         Value:= T(Count+PT^.MinValue);
  78.         exit(true);
  79.       end;
  80.       PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  81.       Inc(Count);
  82.     end;
  83.   end;
  84. end;
  85.  
  86. type
  87.   TTest = (test1,test2,test3);
  88.   TEnumTTest = specialize TEnum<TTest>;
  89.  
  90.    TRaceType = (
  91.     rtNone     = -1,
  92.     rtJanaru   = 0,
  93.     rtTambinor = 1,
  94.     rtBendalir = 2,
  95.     rtCogadh   = 3);
  96.   TEnumTRaceType = specialize TEnum<TRaceType>;
  97. var
  98.   a: TTest;
  99. begin
  100.   WriteLn(TEnumTTest.ToString(TTest(-3)));
  101.   WriteLn(TEnumTTest.ToString(Test1));
  102.   WriteLn(TEnumTTest.ToString(TTest(20)));
  103.   a:= TEnumTTest.FromString('test1');
  104.   if TEnumTTest.FromString('testNone', a) then
  105.     WriteLn('huh');
  106.   a:= TEnumTTest.FromString('');
  107. end.
View Raw