Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 21, 2010 foreach over enums? | ||||
---|---|---|---|---|
| ||||
enum X { A=3, B=1, C } void main() { foreach(e;X) writefln(e.stringof," = ",e); } //X.A = 3 //X.B = 1 //X.C = 2 or //X.B = 1 //X.C = 2 //X.A = 3 |
September 21, 2010 Re: foreach over enums? | ||||
---|---|---|---|---|
| ||||
Posted in reply to %u | %u <e@ee.com> wrote: > enum X { A=3, B=1, C } > > void main() { > foreach(e;X) > writefln(e.stringof," = ",e); > } > //X.A = 3 > //X.B = 1 > //X.C = 2 > or > //X.B = 1 > //X.C = 2 > //X.A = 3 enum X { A=3, B=1, C } void main( ) { foreach( e; __traits(allMembers, X) ) { writeln( "X.", e, " = ", mixin( "X."~e ) ); } } -- Simen |
September 21, 2010 Re: foreach over enums? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | == Quote from Simen kjaeraas (simen.kjaras@gmail.com)'s article
> %u <e@ee.com> wrote:
> > enum X { A=3, B=1, C }
> >
> > void main() {
> > foreach(e;X)
> > writefln(e.stringof," = ",e);
> > }
> > //X.A = 3
> > //X.B = 1
> > //X.C = 2
> > or
> > //X.B = 1
> > //X.C = 2
> > //X.A = 3
> enum X { A=3, B=1, C }
> void main( ) {
> foreach( e; __traits(allMembers, X) ) {
> writeln( "X.", e, " = ", mixin( "X."~e ) );
> }
> }
D1 :'(
|
September 22, 2010 Re: foreach over enums? | ||||
---|---|---|---|---|
| ||||
Posted in reply to %u | %u <e@ee.com> wrote: > == Quote from Simen kjaeraas (simen.kjaras@gmail.com)'s article >> %u <e@ee.com> wrote: >> > enum X { A=3, B=1, C } >> > >> > void main() { >> > foreach(e;X) >> > writefln(e.stringof," = ",e); >> > } >> > //X.A = 3 >> > //X.B = 1 >> > //X.C = 2 >> > or >> > //X.B = 1 >> > //X.C = 2 >> > //X.A = 3 >> enum X { A=3, B=1, C } >> void main( ) { >> foreach( e; __traits(allMembers, X) ) { >> writeln( "X.", e, " = ", mixin( "X."~e ) ); >> } >> } > > D1 :'( Oh. Without being an expert on D1 matters, I believe that is impossible. I thought there was a struct called defineEnum in phobos1, but it appears I am wrong. However, it should be fairly simple to create one. Untested code, as I do not have D1 installed: struct defineEnum( T... ) { foreach ( i, e; T ) { mixin( "static defineEnum " ~ e ~ " = defineEnum( i );" ); } static int opApply( int delegate( ref bar ) dg ) { int result = 0; foreach ( e; T ) { mixin( "result = dg( " ~ e ~ " ) );" ); if ( result ) { break; } } return result; } } -- Simen |
September 23, 2010 Re: foreach over enums? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | == Quote from Simen kjaeraas (simen.kjaras@gmail.com)'s article > %u <e@ee.com> wrote: > > == Quote from Simen kjaeraas (simen.kjaras@gmail.com)'s article > >> %u <e@ee.com> wrote: > >> > enum X { A=3, B=1, C } > >> > > >> > void main() { > >> > foreach(e;X) > >> > writefln(e.stringof," = ",e); > >> > } > >> > //X.A = 3 > >> > //X.B = 1 > >> > //X.C = 2 > >> > or > >> > //X.B = 1 > >> > //X.C = 2 > >> > //X.A = 3 > >> enum X { A=3, B=1, C } > >> void main( ) { > >> foreach( e; __traits(allMembers, X) ) { > >> writeln( "X.", e, " = ", mixin( "X."~e ) ); > >> } > >> } > > > > D1 :'( > Oh. Without being an expert on D1 matters, I believe that is impossible. > I thought there was a struct called defineEnum in phobos1, but it > appears I am wrong. However, it should be fairly simple to create one. > Untested code, as I do not have D1 installed: > struct defineEnum( T... ) { > foreach ( i, e; T ) { > mixin( "static defineEnum " ~ e ~ " = defineEnum( i );" ); > } I think in D1, the foreach need to be encapsulated in a char[] function(). > static int opApply( int delegate( ref bar ) dg ) { > int result = 0; > foreach ( e; T ) { > mixin( "result = dg( " ~ e ~ " ) );" ); Why is this a mixin? > if ( result ) { > break; > } > } > return result; > } > } The code didn't compile, so I tried fixing it.. and failed as I don't really get what you want it to do (or even how to call it :) Please explain it to me. |
September 23, 2010 Re: foreach over enums? | ||||
---|---|---|---|---|
| ||||
Posted in reply to %u | %u <e@ee.com> wrote: > The code didn't compile, so I tried fixing it.. and failed as I don't really get > what you want it to do (or even how to call it :) > Please explain it to me. Sorry, it was late and I was tired. Updated code (tested, even! :p): module foo; import std.stdio; template defineStaticImpl( T, int value, string name, args... ) { mixin( "static T " ~ name ~ " = cast(T)value; " ); static if ( args.length != 0 ) { mixin defineStaticImpl!( T, value + 1, args ); } } template defineStatic( T, args... ) { mixin defineStaticImpl!( T, 0, args ); } struct defineEnum( T... ) { int value; static const int num = T.length; mixin defineStatic!( typeof( this ), T ); static int opApply( int delegate( ref defineEnum ) dg ) { int result = 0; foreach ( i, e; T ) { result = dg( defineEnum( i ) ); if ( result ) { break; } } return result; } static defineEnum opCall( int value ) { defineEnum tmp; tmp.value = value; return tmp; } string toString( ) { foreach ( i, e; T ) { if ( i == value ) { return e.dup; } } } } void main( ) { alias defineEnum!( "A", "B", "C" ) Bar; foreach ( e; Bar ) { writefln( e ); } } -- Simen |
September 23, 2010 Re: foreach over enums? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | == Quote from Simen kjaeraas (simen.kjaras@gmail.com)'s article
> %u <e@ee.com> wrote:
> > The code didn't compile, so I tried fixing it.. and failed as I don't
> > really get
> > what you want it to do (or even how to call it :)
> > Please explain it to me.
> Sorry, it was late and I was tired. Updated code (tested, even! :p):
> module foo;
> import std.stdio;
> template defineStaticImpl( T, int value, string name, args... ) {
> mixin( "static T " ~ name ~ " = cast(T)value; " );
> static if ( args.length != 0 ) {
> mixin defineStaticImpl!( T, value + 1, args );
> }
> }
> template defineStatic( T, args... ) {
> mixin defineStaticImpl!( T, 0, args );
> }
> struct defineEnum( T... ) {
> int value;
> static const int num = T.length;
> mixin defineStatic!( typeof( this ), T );
> static int opApply( int delegate( ref defineEnum ) dg ) {
> int result = 0;
> foreach ( i, e; T ) {
> result = dg( defineEnum( i ) );
> if ( result ) {
> break;
> }
> }
> return result;
> }
> static defineEnum opCall( int value ) {
> defineEnum tmp;
> tmp.value = value;
> return tmp;
> }
> string toString( ) {
> foreach ( i, e; T ) {
> if ( i == value ) {
> return e.dup;
> }
> }
> }
> }
> void main( ) {
> alias defineEnum!( "A", "B", "C" ) Bar;
> foreach ( e; Bar ) {
> writefln( e );
> }
> }
Thanks!! :)
This I can understand.
|
September 23, 2010 Re: foreach over enums? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | == Quote from Simen kjaeraas (simen.kjaras@gmail.com)'s article
> Sorry, it was late and I was tired. Updated code (tested, even! :p):
> module foo;
> import std.stdio;
> template defineStaticImpl( T, int value, string name, args... ) {
> mixin( "static T " ~ name ~ " = cast(T)value; " );
> static if ( args.length != 0 ) {
> mixin defineStaticImpl!( T, value + 1, args );
> }
> }
> template defineStatic( T, args... ) {
> mixin defineStaticImpl!( T, 0, args );
> }
> struct defineEnum( T... ) {
> int value;
> static const int num = T.length;
> mixin defineStatic!( typeof( this ), T );
> static int opApply( int delegate( ref defineEnum ) dg ) {
> int result = 0;
> foreach ( i, e; T ) {
> result = dg( defineEnum( i ) );
> if ( result ) {
> break;
> }
> }
> return result;
> }
> static defineEnum opCall( int value ) {
> defineEnum tmp;
> tmp.value = value;
> return tmp;
> }
> string toString( ) {
> foreach ( i, e; T ) {
> if ( i == value ) {
> return e.dup;
> }
> }
> }
> }
> void main( ) {
> alias defineEnum!( "A", "B", "C" ) Bar;
> foreach ( e; Bar ) {
> writefln( e );
> }
> }
Okee, that took me a while to wholly get. :)
First question, shouldn't the first foreach be replaced by a simple for loop: for(int i = 0; i<num; i++ ) {
If I understand it correctly the foreach aggregates are actually string-tuple
literals.
Then couldn't the second one be CT translated to char[][]?
That way the stringOf would be a simple array index.
And lastly, I probably need to make the whole struct a string mixin if I want it's type to be like an enum.. don't I? :'(
|
September 23, 2010 Re: foreach over enums? | ||||
---|---|---|---|---|
| ||||
Posted in reply to %u | %u <e@ee.com> wrote: > First question, shouldn't the first foreach be replaced by a simple for loop: > for(int i = 0; i<num; i++ ) { It certainly could, and that would explain the presence of 'num', but it's not necessary, and should make no difference in the generated executable. > If I understand it correctly the foreach aggregates are actually string-tuple > literals. Yes. > Then couldn't the second one be CT translated to char[][]? > That way the stringOf would be a simple array index. Indeed it could, though I will leave its implementation as an exercise for the reader :p. I also thought up a Duff's device-inspired contraption that works: string toString( ) { switch ( value ) { foreach ( i, e; T ) { case i: return T[i]; } } } This should be as fast as the char[][]. > And lastly, I probably need to make the whole struct a string mixin if I want it's > type to be like an enum.. don't I? :'( I'm not sure what you're getting at here. In what way that you don't like it is it enum-unlike? -- Simen |
September 23, 2010 Re: foreach over enums? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | == Quote from Simen kjaeraas (simen.kjaras@gmail.com)'s article > %u <e@ee.com> wrote: > > First question, shouldn't the first foreach be replaced by a simple for > > loop: > > for(int i = 0; i<num; i++ ) { > It certainly could, and that would explain the presence of 'num', but it's not necessary, and should make no difference in the generated executable. > > If I understand it correctly the foreach aggregates are actually > > string-tuple > > literals. > Yes. > > Then couldn't the second one be CT translated to char[][]? That way the stringOf would be a simple array index. > Indeed it could, though I will leave its implementation as an > exercise for the reader :p. I also thought up a Duff's > device-inspired contraption that works: > string toString( ) { > switch ( value ) { > foreach ( i, e; T ) { > case i: > return T[i]; > } > } > } > This should be as fast as the char[][]. I thought that would be more annoying to implement(string mixins etc).. didn't know it could be that nice :) > > And lastly, I probably need to make the whole struct a string mixin if I > > want it's > > type to be like an enum.. don't I? :'( > I'm not sure what you're getting at here. In what way that you don't like it is it enum-unlike? These two have distinctly different outputs ;P alias defineEnum!( "A", "B", "C" ) Bar; writefln( typeof(Bar.A).stringof ); enum Foo { A, B, C } writefln( typeof(Foo.A).stringof ); Won't the compiler even choke on the type size when feeding defineEnum a hundred elements or so? |
Copyright © 1999-2021 by the D Language Foundation