digitalmars.D.learn - enum to string
- Nick Sabalausky (16/16) Mar 10 2009 Is there any way to do this (preferably in D1) with reflection? (ie, wit...
- MIURA Masahiro (10/10) Mar 10 2009 In D2:
- Nick Sabalausky (5/15) Mar 10 2009 So there's no built-in way to do this with compile-time reflection?
- Jarrett Billingsley (7/24) Mar 10 2009 In D1, that's the way you have to do it.
- Robert Fraser (2/5) Mar 12 2009 Which should be easily portable to D1.
- Daniel Keep (5/23) Mar 10 2009 The only way that I know of is to generate foo at the same time as
- Lionello Lunesu (21/40) Mar 12 2009 You got to give it to Walter: the code is pretty clean (for C++ code any...
- Lionello Lunesu (4/4) Mar 12 2009 Oops, sorry, I didn't notice this was the .learn newsgroup. I guess a
- Nick Sabalausky (6/10) Mar 12 2009 Hey, solutions are solutions :) In fact I may very well try that out. I...
- Lionello Lunesu (7/20) Mar 12 2009 I'm really glad it's so easy to hack stuff into the compiler. Although
- Nick Sabalausky (3/46) Mar 12 2009 Your attachment is zero-byte.
- Lionello Lunesu (1/3) Mar 12 2009 Oops... Try this one..
- Lionello Lunesu (2/2) Mar 12 2009 cr*p, I've pasted too little. Try this one instead..
- BCS (3/7) Mar 12 2009 you client is messing with you, paste-bin the sucker or add it to a bugz...
- Lionello Lunesu (23/23) Mar 12 2009 //src\dmd\mtype.c, line 5025 (in TypeEnum::dotExp, after the #endif):
- Brad Roberts (13/22) Mar 12 2009 Just to be sure the two don't get combined (I know you didn't say to do
- Lionello Lunesu (18/23) Mar 12 2009 You're not wrong :)
- Ary Borenszweig (5/25) Mar 13 2009 Can you foreach at compile-time? I thought you could only do that in
- Daniel Keep (26/53) Mar 13 2009 We have a sort-of static foreach. The trick is that the aggregate HAS
- bearophile (5/6) Mar 14 2009 If some of you needs a version that takes 1 or 2 or 3 arguments, for the...
Is there any way to do this (preferably in D1) with reflection? (ie, without having to manually create a conversion func/lookup for every value of every enum.) ---------------------- enum Shape { Square, Circle } char[] foo(Shape s) { // ????? } // Either one of these, I don't really care which assert(foo(Shape.Square) == "Shape.Square"); assert(foo(Shape.Square) == "Square"); ----------------------
Mar 10 2009
In D2: enum Shape: string { Square = "Square", Circle = "Circle", } void main() { assert(cast(string) Shape.Square == "Square"); }
Mar 10 2009
"MIURA Masahiro" <echochamber gmail.com> wrote in message news:gp730i$30e8$1 digitalmars.com...In D2: enum Shape: string { Square = "Square", Circle = "Circle", } void main() { assert(cast(string) Shape.Square == "Square"); }So there's no built-in way to do this with compile-time reflection? I suppose I could work around it by creating a mixin that automatically generates both the enum and an enum->string routine.
Mar 10 2009
On Tue, Mar 10, 2009 at 9:54 PM, Nick Sabalausky <a a.a> wrote:"MIURA Masahiro" <echochamber gmail.com> wrote in message news:gp730i$30e8$1 digitalmars.com...In D1, that's the way you have to do it. In D2, there is more reflection - I know you can use __traits(allMembers, Shape) to get the names? Or something like that? It's completely undocumented, of course. There's also std.typecons which has an enum generator that will create toString and I think fromString functions as well.In D2: enum Shape: string { =A0 =A0Square =3D "Square", =A0 =A0Circle =3D "Circle", } void main() { =A0 =A0assert(cast(string) Shape.Square =3D=3D "Square"); }So there's no built-in way to do this with compile-time reflection? I suppose I could work around it by creating a mixin that automatically generates both the enum and an enum->string routine.
Mar 10 2009
Jarrett Billingsley wrote:There's also std.typecons which has an enum generator that will create toString and I think fromString functions as well.Which should be easily portable to D1.
Mar 12 2009
Nick Sabalausky wrote:Is there any way to do this (preferably in D1) with reflection? (ie, without having to manually create a conversion func/lookup for every value of every enum.) ---------------------- enum Shape { Square, Circle } char[] foo(Shape s) { // ????? } // Either one of these, I don't really care which assert(foo(Shape.Square) == "Shape.Square"); assert(foo(Shape.Square) == "Square"); ----------------------The only way that I know of is to generate foo at the same time as Shape. Generally, you write a CTFE function that generates the enum and also generates the toString function. -- Daniel
Mar 10 2009
Nick Sabalausky wrote:Is there any way to do this (preferably in D1) with reflection? (ie, without having to manually create a conversion func/lookup for every value of every enum.) ---------------------- enum Shape { Square, Circle } char[] foo(Shape s) { // ????? } // Either one of these, I don't really care which assert(foo(Shape.Square) == "Shape.Square"); assert(foo(Shape.Square) == "Square"); ----------------------You got to give it to Walter: the code is pretty clean (for C++ code anyway) Add the attached code to src\dmd\mtype.c, line 5025 (in TypeEnum::dotExp, after the #endif). This now works: import std.stdio; enum ABC { A, B, C }; void main(string[] args) { foreach(a; ABC.tupleof) { writefln(a); } } prints: A B C Of course, I'm way over my head here. I've just copied the code from struct.tupleof to make enum.tupleof and creating a tuple of StringExps insteadof DotVarExps, whatever they are.... L.
Mar 12 2009
Oops, sorry, I didn't notice this was the .learn newsgroup. I guess a patch to the DMD source was not really what you expected. I just got so anxious! L.
Mar 12 2009
"Lionello Lunesu" <lio lunesu.remove.com> wrote in message news:gpc4j3$30a0$2 digitalmars.com...Oops, sorry, I didn't notice this was the .learn newsgroup. I guess a patch to the DMD source was not really what you expected. I just got so anxious! L.Hey, solutions are solutions :) In fact I may very well try that out. I'm not particularly keen on using an ugly mixin to declare all my enums just so that I can use a simple reflection feature like that (which I'd mostly just be using for debugging info anyway).
Mar 12 2009
Nick Sabalausky wrote:"Lionello Lunesu" <lio lunesu.remove.com> wrote in message news:gpc4j3$30a0$2 digitalmars.com...I'm really glad it's so easy to hack stuff into the compiler. Although I'm still strugling to get these new "string expression" to evaluate at compile time. The enum.tupleof is done at compile time, the foreach as well, but I cannot pragma(msg) the values, nor can they be mixin-ed.. Must be some constness flag somewhere? L.Oops, sorry, I didn't notice this was the .learn newsgroup. I guess a patch to the DMD source was not really what you expected. I just got so anxious! L.Hey, solutions are solutions :) In fact I may very well try that out. I'm not particularly keen on using an ugly mixin to declare all my enums just so that I can use a simple reflection feature like that (which I'd mostly just be using for debugging info anyway).
Mar 12 2009
"Lionello Lunesu" <lio lunesu.remove.com> wrote in message news:gpc4es$30a0$1 digitalmars.com...Nick Sabalausky wrote:Your attachment is zero-byte.Is there any way to do this (preferably in D1) with reflection? (ie, without having to manually create a conversion func/lookup for every value of every enum.) ---------------------- enum Shape { Square, Circle } char[] foo(Shape s) { // ????? } // Either one of these, I don't really care which assert(foo(Shape.Square) == "Shape.Square"); assert(foo(Shape.Square) == "Square"); ----------------------You got to give it to Walter: the code is pretty clean (for C++ code anyway) Add the attached code to src\dmd\mtype.c, line 5025 (in TypeEnum::dotExp, after the #endif). This now works: import std.stdio; enum ABC { A, B, C }; void main(string[] args) { foreach(a; ABC.tupleof) { writefln(a); } } prints: A B C Of course, I'm way over my head here. I've just copied the code from struct.tupleof to make enum.tupleof and creating a tuple of StringExps insteadof DotVarExps, whatever they are.... L.
Mar 12 2009
Your attachment is zero-byte.Oops... Try this one..
Mar 12 2009
cr*p, I've pasted too little. Try this one instead.. I'll use a proper diff tool next time..
Mar 12 2009
Reply to Lionello,cr*p, I've pasted too little. Try this one instead.. I'll use a proper diff tool next time..you client is messing with you, paste-bin the sucker or add it to a bugzilla item
Mar 12 2009
//src\dmd\mtype.c, line 5025 (in TypeEnum::dotExp, after the #endif): /* If e.tupleof */ if (ident == Id::tupleof) { /* Create a TupleExp out of the fields of the struct e: * (e.field0, e.field1, e.field2, ...) */ e = e->semantic(sc); // do this before turning on noaccesscheck Expressions *exps = new Expressions; exps->reserve(sym->members->dim); for (size_t i = 0; i < sym->members->dim; i++) { EnumMember *em = ((Dsymbol *)sym->members->data[i])->isEnumMember(); char* s = em->ident->toChars(); Expression *fe = new StringExp(e->loc, s, strlen(s), 'c'); exps->push(fe); } e = new TupleExp(e->loc, exps); Scope sss; e = e->semantic(&sss); return e; }
Mar 12 2009
On Thu, 12 Mar 2009, BCS wrote:Reply to Lionello,Just to be sure the two don't get combined (I know you didn't say to do both, just making sure), please don't paste-bin stuff for bug reports. Either put it directly in a comment or attach it as a patch. While paste-bin's aren't super ephemeral, there's no good reason to have thing disconnected from the bug like that. That said, I don't think this really helps the desired usecase much. It's useful, don't get me wrong, but still requires code to build up the bi-directional translations. Or am I missing something? Seems to be happening to me a lot lately, so I'm very prepared to be wrong here too. :) Later, Bradcr*p, I've pasted too little. Try this one instead.. I'll use a proper diff tool next time..you client is messing with you, paste-bin the sucker or add it to a bugzilla item
Mar 12 2009
"Brad Roberts" <braddr bellevue.puremagic.com> wrote in message news:alpine.DEB.2.00.0903121755240.4513 bellevue.puremagic.com...That said, I don't think this really helps the desired usecase much. It's useful, don't get me wrong, but still requires code to build up the bi-directional translations. Or am I missing something? Seems to be happening to me a lot lately, so I'm very prepared to be wrong here too. :)You're not wrong :) The problem is that the foreach variable is not evaluatable to a compile-time string. I don't know why, but I'll figure it out tonight. I've also managed to convert an enum to an AssocArrayLiteralExp* (with the name/string as the key and the value/int as the value) but it seems that it cannot be foreached at compile time, even if it's a literal expression. But hell, I've spent about 1 hour browsing through dmd's code, so I'm pretty sure it's possible with a little more research. I want to get either one to work at compile-time. In the case of TupleExp, one could then use a string mixin to convert the string to a value. L. * I don't have the AA patch handy (I'm at work) but it's a good exercise: start with my original tupleof patch but create an AssocArrayLiteralExp instead of the TupleExp. You'll need two Expressions arrays, one for keys and one for values. EnumMember::ident is the name, EnumMember::value is the value expression. Pretty straightforward.
Mar 12 2009
Lionello Lunesu wrote:"Brad Roberts" <braddr bellevue.puremagic.com> wrote in message news:alpine.DEB.2.00.0903121755240.4513 bellevue.puremagic.com...Can you foreach at compile-time? I thought you could only do that in CTFE (or templates?). Maybe that's why it's not working. How do you do it to pragma msg the members of a struct? I remember someone proposed "static foreach" some time ago...That said, I don't think this really helps the desired usecase much. It's useful, don't get me wrong, but still requires code to build up the bi-directional translations. Or am I missing something? Seems to be happening to me a lot lately, so I'm very prepared to be wrong here too. :)You're not wrong :) The problem is that the foreach variable is not evaluatable to a compile-time string. I don't know why, but I'll figure it out tonight. I've also managed to convert an enum to an AssocArrayLiteralExp* (with the name/string as the key and the value/int as the value) but it seems that it cannot be foreached at compile time, even if it's a literal expression. But hell, I've spent about 1 hour browsing through dmd's code, so I'm pretty sure it's possible with a little more research.
Mar 13 2009
Ary Borenszweig wrote:Lionello Lunesu wrote:We have a sort-of static foreach. The trick is that the aggregate HAS to be a tuple. When in doubt, you can always fall back on the following construct: template Tuple(T...) { alias T Tuple; } template Range(int n) { static if( n <= 0 ) alias Tuple!() Range; else alias Tuple!(Range!(n-1), n-1) Range; } void blah() { // Note that static foreach ONLY works inside a function foreach( i ; Range!(n) ) { // do stuff with i, which should be a const int } } There have been times when directly accessing some CT construct would make the compiler choke, but going via an index worked fine. -- Daniel"Brad Roberts" <braddr bellevue.puremagic.com> wrote in message news:alpine.DEB.2.00.0903121755240.4513 bellevue.puremagic.com...Can you foreach at compile-time? I thought you could only do that in CTFE (or templates?). Maybe that's why it's not working. How do you do it to pragma msg the members of a struct? I remember someone proposed "static foreach" some time ago...That said, I don't think this really helps the desired usecase much. It's useful, don't get me wrong, but still requires code to build up the bi-directional translations. Or am I missing something? Seems to be happening to me a lot lately, so I'm very prepared to be wrong here too. :)You're not wrong :) The problem is that the foreach variable is not evaluatable to a compile-time string. I don't know why, but I'll figure it out tonight. I've also managed to convert an enum to an AssocArrayLiteralExp* (with the name/string as the key and the value/int as the value) but it seems that it cannot be foreached at compile time, even if it's a literal expression. But hell, I've spent about 1 hour browsing through dmd's code, so I'm pretty sure it's possible with a little more research.
Mar 13 2009
Daniel Keep:template Range(int n)If some of you needs a version that takes 1 or 2 or 3 arguments, for the start, stop and stride, take a look at my dlibs: http://www.fantascienza.net/leonardo/so/dlibs/templates.html Bye, bearophile
Mar 14 2009