Jump to page: 1 2 3
Thread overview
Getting the string representing the enum value
Apr 02, 2006
Hasan Aljudy
Apr 02, 2006
Victor Nakoryakov
Apr 02, 2006
Jason Mills
Apr 02, 2006
Ben Gardner
Re: Getting the string representing the enum value ~ Proposal
Apr 03, 2006
kris
Apr 03, 2006
Ben Gardner
Apr 03, 2006
Hasan Aljudy
Apr 03, 2006
James Dunne
Apr 03, 2006
Sean Kelly
Apr 03, 2006
pragma
Apr 03, 2006
kris
Apr 03, 2006
pragma
Apr 04, 2006
Tom
Apr 05, 2006
kris
Apr 05, 2006
Tom
Apr 05, 2006
Justin C Calvarese
Apr 05, 2006
John C
Apr 05, 2006
kris
Apr 05, 2006
John C
Apr 05, 2006
Bruno Medeiros
Apr 05, 2006
Kyle Furlong
Apr 05, 2006
Don Clugston
Apr 05, 2006
kris
April 02, 2006
say I have an enum

    enum X
    {
     A,
     B,
     C
    }

and I have

    void someFunc( X e )
    {
     //.. some code
    }

I want to print the value of 'e' but I don't want to get a number!! I want to get a string that represents it. i.e. A or B or C


    void someFunc( X e )
    {
       toString(e);
       e.string;
       e.value;
       //or something like that ..
    }

Is there any such thing in D?

April 02, 2006
Hasan Aljudy wrote:
> say I have an enum
> 
>     enum X
>     {
>      A,
>      B,
>      C
>     }
> 
> and I have
> 
>     void someFunc( X e )
>     {
>      //.. some code
>     }
> 
> I want to print the value of 'e' but I don't want to get a number!! I want to get a string that represents it. i.e. A or B or C
> 
> 
>     void someFunc( X e )
>     {
>        toString(e);
>        e.string;
>        e.value;
>        //or something like that ..
>     }
> 
> Is there any such thing in D?
> 
Hello,

AFAIK, there is now way to do what you want directly. Simplest solution is to create helper map that would have X as a key and char[] as a value and then to define function toString(X x) the would return string representation.


-- 
Victor (aka nail) Nakoryakov
nail-mail<at>mail<dot>ru

Krasnoznamensk, Moscow, Russia
April 02, 2006
Hasan Aljudy wrote:
> say I have an enum
> 
>     enum X
>     {
>      A,
>      B,
>      C
>     }
> 
> and I have
> 
>     void someFunc( X e )
>     {
>      //.. some code
>     }
> 
> I want to print the value of 'e' but I don't want to get a number!! I want to get a string that represents it. i.e. A or B or C
> 
> Is there any such thing in D?
> 

Sadly, no. I once suggested that enums be a little smarter, more like .NET enums or, even better in my opinion, Java 5 enums. Being able to obtain a string representation from an enum value, parsing an enum value from a string, and (in Java versions) attach functionality or custom strings to enum values, is very powerful.

If I remember correctly, the idea was rejected out right. Maybe there are performance issues?

Jason
April 02, 2006
I've done that "the hard way" in C.
Here's an example in D:

/////
import std.stdio;
import std.string;

enum X {
  Apple,
  Bat,
  Car,
}

char [][] X_names = [
   X.Apple : "Apple",
   X.Bat   : "Bat",
   X.Car   : "Car",
];

char [] get_X_name(X e)
{
   if ((e >= X.min) && (cast(int)e < X_names.length) &&
       (X_names[e] !is null)) {
      return X_names[e];
   }
   return ("invalid");
}

X get_X_id(char [] name)
{
   for (int idx = 0; idx < X_names.length; idx++) {
      if ((X_names[idx] !is null) && (icmp(X_names[idx], name) == 0))
         return cast(X)idx;
   }
   return cast(X)-1;
}

void main(char [][] args)
{
   for (int i = -1; i < 4; i++)
   {
      writef("%d = '%s'\n", i, get_X_name(cast(X)i));
   }

   char [] name = "bat";
   writef("id for '%s' is %d\n", name, cast(int)get_X_id(name));
}
////

Running this produces the output:
-1 = 'invalid'
0 = 'Apple'
1 = 'Bat'
2 = 'Car'
3 = 'invalid'
id for 'bat' is 1

Ben

Hasan Aljudy wrote:
> say I have an enum
> 
>     enum X
>     {
>      A,
>      B,
>      C
>     }
> 
> and I have
> 
>     void someFunc( X e )
>     {
>      //.. some code
>     }
> 
> I want to print the value of 'e' but I don't want to get a number!! I want to get a string that represents it. i.e. A or B or C
> 
> 
>     void someFunc( X e )
>     {
>        toString(e);
>        e.string;
>        e.value;
>        //or something like that ..
>     }
> 
> Is there any such thing in D?
> 
April 02, 2006
You have the right idea, although I think it would be better to name the X->char[] function 'toString' and the char[]->X function 'toX' and the map with all capitals. Convention, you see, and clarity through expressions like:
# X var = X.Apple;
# char[] str = var.toString;
# X another = str.toX;

In fact, if you don't want the char[]->X conversion at all, then the map can be a static variable of 'toString(X)', to prevent namespace pollution.

One other suggestion: note the rewritten code below:

Ben Gardner wrote:
> I've done that "the hard way" in C.
> Here's an example in D:
> 
> /////
> import std.stdio;
> import std.string;
> 
> enum X {
>   Apple,
>   Bat,
>   Car,
> }
> 
> char [][] X_names = [
>    X.Apple : "Apple",
>    X.Bat   : "Bat",
>    X.Car   : "Car",
> ];
> 
> char [] get_X_name(X e)
> {
>    if ((e >= X.min) && (cast(int)e < X_names.length) &&
>        (X_names[e] !is null)) {
>       return X_names[e];
>    }
>    return ("invalid");
> }

char[] toString (X value) {
  if (auto foo = value in X_NAMES)
    return *foo;
  return "invalid";
}

> X get_X_id(char [] name)
> {
>    for (int idx = 0; idx < X_names.length; idx++) {
>       if ((X_names[idx] !is null) && (icmp(X_names[idx], name) == 0))
>          return cast(X)idx;
>    }
>    return cast(X)-1;
> }

X toX (char[] value) {
  foreach (id, name; X_NAMES) {
    if (icmp(name, value) == 0)
      return id;
  }
  return cast(X)-1;
}

-- Chris Nicholson-Sauls
April 03, 2006
Ben Gardner wrote:
> I've done that "the hard way" in C.
> Here's an example in D:
> 
> /////
> import std.stdio;
> import std.string;
> 
> enum X {
>   Apple,
>   Bat,
>   Car,
> }
> 
> char [][] X_names = [
>    X.Apple : "Apple",
>    X.Bat   : "Bat",
>    X.Car   : "Car",
> ];
> 
> char [] get_X_name(X e)
> {
>    if ((e >= X.min) && (cast(int)e < X_names.length) &&
>        (X_names[e] !is null)) {
>       return X_names[e];
>    }
>    return ("invalid");
> }
> 
> X get_X_id(char [] name)
> {
>    for (int idx = 0; idx < X_names.length; idx++) {
>       if ((X_names[idx] !is null) && (icmp(X_names[idx], name) == 0))
>          return cast(X)idx;
>    }
>    return cast(X)-1;
> }
> 
> void main(char [][] args)
> {
>    for (int i = -1; i < 4; i++)
>    {
>       writef("%d = '%s'\n", i, get_X_name(cast(X)i));
>    }
> 
>    char [] name = "bat";
>    writef("id for '%s' is %d\n", name, cast(int)get_X_id(name));
> }
> ////
> 
> Running this produces the output:
> -1 = 'invalid'
> 0 = 'Apple'
> 1 = 'Bat'
> 2 = 'Car'
> 3 = 'invalid'
> id for 'bat' is 1
> 
> Ben
> 
> Hasan Aljudy wrote:
> 
>>say I have an enum
>>
>>    enum X
>>    {
>>     A,
>>     B,
>>     C
>>    }
>>
>>and I have
>>
>>    void someFunc( X e )
>>    {
>>     //.. some code
>>    }
>>
>>I want to print the value of 'e' but I don't want to get a number!! I
>>want to get a string that represents it. i.e. A or B or C
>>
>>
>>    void someFunc( X e )
>>    {
>>       toString(e);
>>       e.string;
>>       e.value;
>>       //or something like that ..
>>    }
>>
>>Is there any such thing in D?
>>


I'll propose that a new property be added, somewhat like the .mangleof property. Instead, a .nameof property would simply return the lexical token for the named entity. Doesn't matter whether it refers to a struct, class, some attribute thereof, enum types or members, whatever ... the x.nameof should just return a char[] of the respective name.

Thoughts?
April 03, 2006
kris wrote:
> 
> I'll propose that a new property be added, somewhat like the .mangleof property. Instead, a .nameof property would simply return the lexical token for the named entity. Doesn't matter whether it refers to a struct, class, some attribute thereof, enum types or members, whatever ... the x.nameof should just return a char[] of the respective name.
> 
> Thoughts?

This would be easy implement if the enum value is known at compile time
(ie, X.Apple.nameof).

But to do this for an unknown enum value would require that a complete string table be defined for every enum.

void foo(X e)
{
   writef("the enum name is %s\n", e.nameof);
}

I suppose that the compiler would be smart enough to drop the string table if it is never used, so there is no harm in defining the table for all enums.

Ben
April 03, 2006
kris wrote:
> Ben Gardner wrote:
> 
>> I've done that "the hard way" in C.
>> Here's an example in D:
>>
>> /////
>> import std.stdio;
>> import std.string;
>>
>> enum X {
>>   Apple,
>>   Bat,
>>   Car,
>> }
>>
>> char [][] X_names = [
>>    X.Apple : "Apple",
>>    X.Bat   : "Bat",
>>    X.Car   : "Car",
>> ];
>>
>> char [] get_X_name(X e)
>> {
>>    if ((e >= X.min) && (cast(int)e < X_names.length) &&
>>        (X_names[e] !is null)) {
>>       return X_names[e];
>>    }
>>    return ("invalid");
>> }
>>
>> X get_X_id(char [] name)
>> {
>>    for (int idx = 0; idx < X_names.length; idx++) {
>>       if ((X_names[idx] !is null) && (icmp(X_names[idx], name) == 0))
>>          return cast(X)idx;
>>    }
>>    return cast(X)-1;
>> }
>>
>> void main(char [][] args)
>> {
>>    for (int i = -1; i < 4; i++)
>>    {
>>       writef("%d = '%s'\n", i, get_X_name(cast(X)i));
>>    }
>>
>>    char [] name = "bat";
>>    writef("id for '%s' is %d\n", name, cast(int)get_X_id(name));
>> }
>> ////
>>
>> Running this produces the output:
>> -1 = 'invalid'
>> 0 = 'Apple'
>> 1 = 'Bat'
>> 2 = 'Car'
>> 3 = 'invalid'
>> id for 'bat' is 1
>>
>> Ben
>>
>> Hasan Aljudy wrote:
>>
>>> say I have an enum
>>>
>>>    enum X
>>>    {
>>>     A,
>>>     B,
>>>     C
>>>    }
>>>
>>> and I have
>>>
>>>    void someFunc( X e )
>>>    {
>>>     //.. some code
>>>    }
>>>
>>> I want to print the value of 'e' but I don't want to get a number!! I
>>> want to get a string that represents it. i.e. A or B or C
>>>
>>>
>>>    void someFunc( X e )
>>>    {
>>>       toString(e);
>>>       e.string;
>>>       e.value;
>>>       //or something like that ..
>>>    }
>>>
>>> Is there any such thing in D?
>>>
> 
> 
> I'll propose that a new property be added, somewhat like the .mangleof property. Instead, a .nameof property would simply return the lexical token for the named entity. Doesn't matter whether it refers to a struct, class, some attribute thereof, enum types or members, whatever ... the x.nameof should just return a char[] of the respective name.
> 
> Thoughts?

What if it's an alias?  Return the alias identifier's name or the thing which it aliases?

Template parameters?  Return the name of the template parameter or the actual object passed in?

-- 
Regards,
James Dunne
April 03, 2006
Ben Gardner wrote:
> kris wrote:
> 
>>I'll propose that a new property be added, somewhat like the .mangleof
>>property. Instead, a .nameof property would simply return the lexical
>>token for the named entity. Doesn't matter whether it refers to a
>>struct, class, some attribute thereof, enum types or members, whatever
>>... the x.nameof should just return a char[] of the respective name.
>>
>>Thoughts?
> 
> 
> This would be easy implement if the enum value is known at compile time
> (ie, X.Apple.nameof).
> 
> But to do this for an unknown enum value would require that a complete
> string table be defined for every enum.
> 
> void foo(X e)
> {
>    writef("the enum name is %s\n", e.nameof);
> }
> 
> I suppose that the compiler would be smart enough to drop the string
> table if it is never used, so there is no harm in defining the table for
> all enums.
> 
> Ben

Yeah, I think it's actually very easy to implement, I don't see why dmd doesn't do it.

for every enum X, the parser can very easily identify EnumMembers and generate a table along the lines of:

    char[] [X] XMemberToStringTable;

    static this()
    {
        XMemberToStringTable[X.A] = "A";
        XMemberToStringTable[X.B] = "B";
        XMemberToStringTable[X.C] = "C";
    }

    char[] XtoString( X a )
    {
        return XMemberToStringTable[a];
    }

not hard at all.

April 03, 2006
kris wrote:
>
> I'll propose that a new property be added, somewhat like the .mangleof property. Instead, a .nameof property would simply return the lexical token for the named entity. Doesn't matter whether it refers to a struct, class, some attribute thereof, enum types or members, whatever ... the x.nameof should just return a char[] of the respective name.
> 
> Thoughts?

This would be great.


Sean
« First   ‹ Prev
1 2 3