Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does to!string(enum.member) works?

Tags:

d

dmd

How does std.conv.to!string(enum.member) work? How is it possible that a function takes an enum member and returns its name? Does it use a compiler extension or something similar? It's a bit usual to me since I came from C/C++ world.

like image 717
Jack Avatar asked Jul 08 '14 01:07

Jack


1 Answers

What it does is use compile time reflection on the enum type to get a list of members (the names as strings) and their values. It constructs a switch statement out of this information for a fast lookup to get the name from a value. to!SomeEnum("a_string") uses the same principle, just in the other direction.

The compile time reflection info is accessed with __traits(allMembers, TheEnumType), which returns a list of strings that can be looped over to build the switch statement. Then __traits(getMember, TheEnumType, memberName) is used to fetch the body.

Traits can be seen more of here: http://dlang.org/traits.html#allMembers

That allMembers one works on many types, not just classes as seen in the example, but also structs, enums, and more, even modules.

The phobos source code has some examples like EnumMembers in std.traits: https://github.com/D-Programming-Language/phobos/blob/master/std/traits.d#L3360

though the phobos source is kinda hard to read, but on line 3399, at the bottom of that function, you can see it using __traits(allMembers) as its data source. std.conv.to is implemented in terms of many std.traits functions.

You can also check out the sample chapter tab to get the Reflection chapter out of my D cookbook which discusses this stuff too:

http://www.packtpub.com/discover-advantages-of-programming-in-d-cookbook/book

The final example in that chapter shows how to use several of the reflection capabilities to build a little function dispatcher based on strings. The following chapter (not available for free though) shows how to build a switch out of it for better efficiency too. It's actually pretty easy: just put the case statements inside a foreach over the compile time data and the D compiler will unroll then optimize the lookup table for you!

like image 180
Adam D. Ruppe Avatar answered Sep 27 '22 18:09

Adam D. Ruppe