Re: foreach over string enum

2011-02-20 Thread Daniel Murphy
Jesse Phillips jessekphillip...@gmail.com wrote in message 
news:ij2drt$1mq3$1...@digitalmars.com...

 Magic.

 No really, the best I can tell is that the compiler will try to run the 
 foreach loop at compile-time if there is something in the body that must 
 be evaluated at compile time.


Actually this happens because __traits(allMembers ...) returns a TypeTuple 
of string literals.
TypeTuples can contain elements of different types (and types themselves as 
elements), so in order for them to be used in foreach loops, they MUST be 
unrolled.

It's not something in the body, it's the iterable itself that forces 
unrolling.

http://www.digitalmars.com/d/2.0/tuple.html

You can do LOTS of cool stuff with this:

switch(x)
{
  foreach(i; TypeTuple!(1, 2, 6, 8, 17))
case i:
  doSomething();
}

---

class C {}
class D : C {}
class E : C {}
class F : C {}
class G : C {}

C[] list;
foreach(T; TypeTuple!(D, E, F, G))
  list ~= new T();



int id = runtimeInput();

foreach(i, T; TypeTuple!(C, D ,E, F, G, H))
  if (i == id)
return new T(); 




Re: foreach over string enum

2011-02-11 Thread spir

On 02/11/2011 05:27 AM, Jesse Phillips wrote:

spir Wrote:


But in your example the symbol a does not look like a constant, instead it the
loop variable. Do, how does it work?


Magic.

No really, the best I can tell is that the compiler will try to run the foreach 
loop at compile-time if there is something in the body that must be evaluated 
at compile time.

The type you are iterating over must be known at compile-time, and just like 
any such value it is identified by its type and not its contents. So your array 
literal could in fact be built with a variable, the fact that it is not doesn't 
matter.

I'm not sure if much thought has gone into compile-time-looping, the best way to enforce 
it is to get a function to run at compile time. I think the rule of when the body 
needs evaluated at compile-time is what's used, but this also means that when you 
try to iterate something like __traits or tupleof and don't use a compile-time construct 
in the body, you don't get an error or the loop executed.


Oh yes, I see. This explains why my example using plain constants (predefined 
values, thus known at compile-time) does not run: there is nothing /forcing/ 
the compiler (such as a ref to a type), thus the compiler does not even try. 
Even if would be less complicated, probably, than with __traits.


Denis
--
_
vita es estrany
spir.wikidot.com



foreach over string enum

2011-02-10 Thread Nrgyzer
Hey guys,

I'm trying to iterate over an enumeration which contains strings like
the this:

enum FileName : string {
file1 = file1.ext,
file2 = file2.ext
}

I already found this article: http://lists.puremagic.com/pipermail/
digitalmars-d/2007-July/021920.html but it's an enum which contains
integers instead of strings, thus I can't use min- or max-property.

Any suggestions - thanks in advance!


Re: foreach over string enum

2011-02-10 Thread Jesse Phillips
Nrgyzer Wrote:

 Hey guys,
 
 I'm trying to iterate over an enumeration which contains strings like
 the this:
 
 enum FileName : string {
 file1 = file1.ext,
 file2 = file2.ext
 }
 
 I already found this article: http://lists.puremagic.com/pipermail/
 digitalmars-d/2007-July/021920.html but it's an enum which contains
 integers instead of strings, thus I can't use min- or max-property.
 
 Any suggestions - thanks in advance!

I'll just be leaving this here, if you need more explanation ask, but maybe 
you'll understand:

import std.stdio;

enum FileName : string {
file1 = file1.ext,
file2 = file2.ext
}

void main(string args[])
{
foreach(a; __traits(allMembers, FileName))
writeln(mixin(FileName. ~ a));
}



Re: foreach over string enum

2011-02-10 Thread Nrgyzer
== Auszug aus Jesse Phillips (jessekphillip...@gmail.com)'s Artikel
 Nrgyzer Wrote:
  Hey guys,
 
  I'm trying to iterate over an enumeration which contains strings
like
  the this:
 
  enum FileName : string {
  file1 = file1.ext,
  file2 = file2.ext
  }
 
  I already found this article: http://lists.puremagic.com/
pipermail/
  digitalmars-d/2007-July/021920.html but it's an enum which
contains
  integers instead of strings, thus I can't use min- or max-
property.
 
  Any suggestions - thanks in advance!
 I'll just be leaving this here, if you need more explanation ask,
but maybe you'll understand:
 import std.stdio;
 enum FileName : string {
 file1 = file1.ext,
 file2 = file2.ext
 }
 void main(string args[])
 {
 foreach(a; __traits(allMembers, FileName))
 writeln(mixin(FileName. ~ a));
 }

I've already worked with the mixin-statement, but the __trait is new.
As I can see in the documentation, it provides some interesting
features.

Your solution works great, thanks!


Re: foreach over string enum

2011-02-10 Thread spir

On 02/10/2011 08:22 PM, Jesse Phillips wrote:

Nrgyzer Wrote:


Hey guys,

I'm trying to iterate over an enumeration which contains strings like
the this:

enum FileName : string {
file1 = file1.ext,
file2 = file2.ext
}

I already found this article: http://lists.puremagic.com/pipermail/
digitalmars-d/2007-July/021920.html but it's an enum which contains
integers instead of strings, thus I can't use min- or max-property.

Any suggestions -  thanks in advance!


I'll just be leaving this here, if you need more explanation ask, but maybe 
you'll understand:

import std.stdio;

enum FileName : string {
file1 = file1.ext,
file2 = file2.ext
}

void main(string args[])
{
 foreach(a; __traits(allMembers, FileName))
 writeln(mixin(FileName. ~ a));
}


Why the mixin? Is it (just) to have the output string computed at compile-time?

Denis
--
_
vita es estrany
spir.wikidot.com



Re: foreach over string enum

2011-02-10 Thread Jesse Phillips
spir Wrote:

 On 02/10/2011 08:22 PM, Jesse Phillips wrote:

  enum FileName : string {
  file1 = file1.ext,
  file2 = file2.ext
  }
 
  void main(string args[])
  {
   foreach(a; __traits(allMembers, FileName))
   writeln(mixin(FileName. ~ a));
  }
 
 Why the mixin? Is it (just) to have the output string computed at 
 compile-time?

The value of 'a' is the enum field name, not its value. The code will 
ultimately expand to:

void main() {
  writeln(FileName.file1));
  writeln(FileName.file2));
}

Which in turn will may have its enum contents expanded to the string value. The 
mixin is required because it is a named enum and 'a' is a string, not an alias:

  writeln(FileName.a)

doesn't work and nor does:

writeln(FileName.mixin(a));


Re: foreach over string enum

2011-02-10 Thread Ali Çehreli

I don't have answers to your other questions.

On 02/10/2011 03:25 PM, spir wrote:

 unittest {
 auto i = 1;
 auto s = i;

It works if you define s as:

enum s = i;

 writeln(mixin(i)); // compiler happy up to here -- 1
 writeln(mixin(s)); // compiler unhappy -- Error: argument to mixin
 // must be a string, not (s)

It now works.

Ali



Re: foreach over string enum

2011-02-10 Thread spir

On 02/11/2011 01:02 AM, Ali Çehreli wrote:

I don't have answers to your other questions.

On 02/10/2011 03:25 PM, spir wrote:


 unittest {
 auto i = 1;
 auto s = i;


It works if you define s as:

enum s = i;


 writeln(mixin(i)); // compiler happy up to here -- 1
 writeln(mixin(s)); // compiler unhappy -- Error: argument to mixin
 // must be a string, not (s)


It now works.

Ali


Thank you, Ali.

denis
--
_
vita es estrany
spir.wikidot.com




Re: foreach over string enum

2011-02-10 Thread Jesse Phillips
spir Wrote:

 But in your example the symbol a does not look like a constant, instead it 
 the 
 loop variable. Do, how does it work? 

Magic.

No really, the best I can tell is that the compiler will try to run the foreach 
loop at compile-time if there is something in the body that must be evaluated 
at compile time.

The type you are iterating over must be known at compile-time, and just like 
any such value it is identified by its type and not its contents. So your array 
literal could in fact be built with a variable, the fact that it is not doesn't 
matter.

I'm not sure if much thought has gone into compile-time-looping, the best way 
to enforce it is to get a function to run at compile time. I think the rule of 
when the body needs evaluated at compile-time is what's used, but this also 
means that when you try to iterate something like __traits or tupleof and don't 
use a compile-time construct in the body, you don't get an error or the loop 
executed.