Skip to content

Instantly share code, notes, and snippets.

@owlsperspective
Created August 12, 2013 10:35
Show Gist options
  • Save owlsperspective/6209791 to your computer and use it in GitHub Desktop.
Save owlsperspective/6209791 to your computer and use it in GitHub Desktop.
列挙型と列挙子名(文字列)または整数の相互変換(ジェネリックス版)
unit Unit2;
interface
uses
TypInfo, SysUtils, SysConst;
type
TEnumHelper = record
class function TryGetEnumName<T: record>(Value: T; out S: String): Boolean; static;
class function GetEnumName<T: record>(Value: T): String; static;
class function TryGetEnumValue<T: record>(const Name: String; out Enum: T): Boolean; overload; static;
class function GetEnumValue<T: record>(const Name: String): T; overload; static;
class function TryGetEnumValue<T: record>(Value: Integer; out Enum: T): Boolean; overload; static;
class function GetEnumValue<T: record>(Value: Integer): T; overload; static;
end;
implementation
class function TEnumHelper.TryGetEnumName<T>(Value: T; out S: String): Boolean;
var
P: PTypeInfo;
IValue: Integer;
begin
Result := False;
S := '';
P := TypeInfo(T);
if (P = nil) or (P^.Kind <> tkEnumeration) then
begin
Exit;
end;
IValue := 0;
Move(Value,IValue,SizeOf(T));
S := TypInfo.GetEnumName(P,IValue);
Result := True;
end;
class function TEnumHelper.GetEnumName<T>(Value: T): String;
var
P: PTypeInfo;
IValue: Integer;
begin
P := TypeInfo(T);
if (P = nil) or (P^.Kind <> tkEnumeration) then
begin
raise EInvalidOpException.CreateRes(@SVarNotImplemented);
end;
IValue := 0;
Move(Value,IValue,SizeOf(T));
Result := TypInfo.GetEnumName(P,IValue);
end;
class function TEnumHelper.TryGetEnumValue<T>(const Name: String; out Enum: T): Boolean;
var
P: PTypeInfo;
IValue: Integer;
begin
Result := False;
Enum := Default(T);
P := TypeInfo(T);
if (P = nil) or (P^.Kind <> tkEnumeration) then
begin
Exit;
end;
IValue := TypInfo.GetEnumValue(P,Name);
with GetTypeData(P)^ do
begin
if (IValue < MinValue) or (IValue > MaxValue) then
begin
Exit;
end;
end;
Move(IValue,Enum,SizeOf(T));
Result := True;
end;
class function TEnumHelper.GetEnumValue<T>(const Name: String): T;
var
P: PTypeInfo;
IValue: Integer;
begin
Result := Default(T);
P := TypeInfo(T);
if (P = nil) or (P^.Kind <> tkEnumeration) then
begin
raise EInvalidOpException.CreateRes(@SVarNotImplemented);
end;
IValue := TypInfo.GetEnumValue(P,Name);
with GetTypeData(P)^ do
begin
if (IValue < MinValue) or (IValue > MaxValue) then
begin
raise ERangeError.CreateRes(@SRangeError);
end;
end;
Move(IValue,Result,SizeOf(T));
end;
class function TEnumHelper.TryGetEnumValue<T>(Value: Integer; out Enum: T): Boolean;
var
P: PTypeInfo;
begin
Result := False;
Enum := Default(T);
P := TypeInfo(T);
if (P = nil) or (P^.Kind <> tkEnumeration) then
begin
Exit;
end;
with GetTypeData(P)^ do
begin
if (Value < MinValue) or (Value > MaxValue) then
begin
Exit;
end;
end;
Move(Value,Enum,SizeOf(T));
Result := True;
end;
class function TEnumHelper.GetEnumValue<T>(Value: Integer): T;
var
P: PTypeInfo;
begin
Result := Default(T);
P := TypeInfo(T);
if (P = nil) or (P^.Kind <> tkEnumeration) then
begin
raise EInvalidOpException.CreateRes(@SVarNotImplemented);
end;
with GetTypeData(P)^ do
begin
if (Value < MinValue) or (Value > MaxValue) then
begin
raise ERangeError.CreateRes(@SRangeError);
end;
end;
Move(Value,Result,SizeOf(T));
end;
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment