Jump to page: 1 2
Thread overview
foreach over enums?
Sep 21, 2010
%u
Sep 21, 2010
Simen kjaeraas
Sep 21, 2010
%u
Sep 22, 2010
Simen kjaeraas
Sep 23, 2010
%u
Sep 23, 2010
Simen kjaeraas
Sep 23, 2010
%u
Sep 23, 2010
%u
Sep 23, 2010
Simen kjaeraas
Sep 23, 2010
%u
Sep 23, 2010
Simen kjaeraas
Sep 24, 2010
%u
Sep 24, 2010
Simen kjaeraas
Oct 05, 2010
Tomek Sowiński
September 21, 2010
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
%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
== 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
%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
== 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
%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
== 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
== 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
%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
== 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?
« First   ‹ Prev
1 2