Is there a subroutine that can convert an enum value to a strings, so that I can do something like ShowMessage(EnumToStr(enumValue))?
Mailing lists / fpc-pascal / 2010-08
How can you convert an enum value to string?
13 messages · 8 people · –
- FFrank Church 3
- GGraeme Geldenhuys 2
- Ssilvioprog 2
- SSven Barth 2
- HHoward Page-Clark 1
- JJonas Maebe 1
- +2 more
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
Op 2010-08-30 12:30, Frank Church het geskryf:
Is there a subroutine that can convert an enum value to a strings, so that I can do something like ShowMessage(EnumToStr(enumValue))?
eg:
function ObjectStateToString(AObjectState : TPerObjectState): string;
begin
result := GetEnumName(TypeInfo(TPerObjectState),
Ord(AObjectState));
end;GetEnumName is defined in 'typinfo' unit.
Regards,
- Graeme -
Graeme Geldenhuys wrote 15 lines
Another possibility is this (requires 2.4.0 or newer):
function ObjectStateToString(AObjectState : TPerObjectState): string;
begin
WriteStr(Result, AObjectState);
end;WriteStr works the same as Write, but with a String as a argument instead of a File. See here:
http://www.freepascal.org/docs-html/rtl/system/writestr.html
Regards,
Sven
Op 2010-08-30 12:30, Frank Church het geskryf: eg: function…
Graeme Geldenhuys wrote 14 lines
Is there a way to pass the enum so that the type will not matter, so that the type can be determined at runtime, so that it is not necessary to create a new function for every type?
Show quoted text 15 lines
Op 2010-08-30 13:43, Frank Church het geskryf:
Is there a way to pass the enum so that the type will not matter, so that the type can be determined at runtime, so that it is not necessary to create a new function for every type?
I don't know... you might have to create a few overloaded functions with the various enum types.
Regards,
- Graeme -
Is there a subroutine that can convert an enum value to a strings, so that I can do…
Frank Church wroteIs there a subroutine that can convert an enum value to a strings, so that I can do something like ShowMessage(EnumToStr(enumValue))?
Just use writestr ?
program testw;
type
mytype = (a,b,c);
var
d : mytype;
s : string;
begin
d:=a;
writestr(s,d);
writeln(s);
end.This works in trunk, and I think that even str() works with enumerateds in trunk.
Michael.
Michael Van Canneyt wrote 27 lines
WriteStr already worked in 2.4.0 as well.
Regards,
Sven
Sven Barth wrote 15 lines
Correct. However, str() is broken for enums in 2.4.0 and 2.4.2 on 64 bit platforms (writestr works fine).
Jonas
Is there a subroutine that can convert an enum value to a strings, so that I can do…
Frank Church wrote 5 lines
program testnums;
//{$APPTYPE CONSOLE}
uses
Classes, SysUtils;
type
stType = (stLite := -100, stDb, stBothLite, stBothDb); //settings
location Type
var
d : stType;
s : string;
i : integer;
begin
d:= stLite;
writestr(s,d);
writeln(s + ' ' + IntToStr(Integer(d)));
d:= stDb;
writestr(s,d);
writeln(s + ' ' + IntToStr(Integer(d)));
d:= stBothLite;
writestr(s,d);
writeln(s + ' ' + IntToStr(Integer(d)));
d:= stBothDB;
writestr(s,d);
writeln(s + ' ' + IntToStr(Integer(d)));
readln;
end.This is the code I created, as enums are stored as integers, or QWORDs, what is the default way of displaying the integer value of an enum.
Frank Church
======================= http://devblog.brahmancreations.com
But if you want speed in your conversion, GetEnumName is more fast than WriteStr. :3
Result:
00:00:04:336 - 00:00:01:407
Oops, sorry, <raw> tag on nabble platform cutted my code. :S
silvioprog wroteBut if you want speed in your conversion, GetEnumName is more fast than WriteStr. :3
uses
typinfo;
type
tenum = (e1, e2, e3);
procedure TForm1.Button1Click(Sender: TObject);
const
c = 10000000;
m = 'hh:nn:ss:zzzz';
var
i: integer;
en: tenum;
s, r: string;
b, e: tdatetime;
begin
en := e2;
b := now;
for i := 1 to c do
writestr(s, en);
e := now;
r := formatdatetime(m, e - b);
e := b;
b := now;
for i := 1 to c do
getenumname(typeinfo(tenum), integer(en));
e := now;
r += ' - ' + formatdatetime(m, e - b);
ShowMessage(r);
end;Result:
00:00:04:336 - 00:00:01:407
On 13/12/2014 02:50, silvioprog wrote:
...
for i := 1 to c do getenumname(typeinfo(tenum), integer(en));
...
I think for a fairer comparison with WriteStr the compared GetEnumName call should be
...
for i := 1 to c do
s := GetEnumName(TypeInfo(tenum), integer(en));
...Mind you, on my system, such an adapted GetEnumName assignment remains faster than WriteStr.
Howard
---
This email has been checked for viruses by Avast antivirus software. http://www.avast.com
I shall talk about FPC 2.6.2.
First of all - there can be enumerations with predefined values. In 2.6.2, typeinfo for such enumerations does not exist. So solutions with GetEnumName are limited and cannot be used in general case.
str(MyEnum,MyString) and writestr(MyString,MyEnum) give correct results also for enumeraations with assigned values. But there are two problems. First - definitely function is much more comfortable than procedure. Second, catastrophical - enumeration variable can contain value out of definition scope (always contains it, if enumeration does not start from 0). str in such cases generates runtime error, and program is finished. writestr generates exception, which can be caught.
So, my current solution - generic class (unfortunately, generic functions still not implemented in FP). It requires "specialize" statement for every enumeration we propose to convert.
Definitions:
type
generic Enumstr<T>=class
class function tostr(value:T):string;
end;
class function Enumstr.tostr(value: T): string;
begin
try
writestr(result,value);
except
on e:Exception do
result := '('+IntToStr(integer(value))+')';
end;
end;Usage:
type
TMyEnum = (e1=3, e2=-4, e3);
TMyEnumStr=specialize Enumstr<TMyEnum>;
var
MyEnum: TMyEnum;
MyString: string;
begin
MyEnum := e2;
MyString := TMyEnumStr.tostr(MyEnum); // 'e2'
MyEnum := TMyEnum(25);
MyString := TMyEnumStr.tostr(MyEnum); // '(25)'