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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With