www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Iterating through enumeration

reply Alexandr Druzhinin <drug2004 bk.ru> writes:
Hello all.
I have some enum foo { first=1, second=2, fourth=4, sixth=6} and I'd 
like to go through this enumeration like it:
foreach(m; foo.min..foo.max) {
	bar(m);
}
But without excluding foo.max and correct handle situation when enum 
identifiers aren't consequentive.

Thanks in advance
Aug 12 2012
next sibling parent reply simendsjo <simendsjo gmail.com> writes:
On Sun, 12 Aug 2012 12:36:21 +0200, Alexandr Druzhinin <drug2004 bk.ru>  
wrote:

 Hello all.
 I have some enum foo { first=1, second=2, fourth=4, sixth=6} and I'd  
 like to go through this enumeration like it:
 foreach(m; foo.min..foo.max) {
 	bar(m);
 }
 But without excluding foo.max and correct handle situation when enum  
 identifiers aren't consequentive.

 Thanks in advance
Looking for this? http://dlang.org/phobos/std_traits.html#EnumMembers
Aug 12 2012
parent Alexandr Druzhinin <drug2004 bk.ru> writes:
12.08.2012 17:43, simendsjo пишет:
 On Sun, 12 Aug 2012 12:36:21 +0200, Alexandr Druzhinin <drug2004 bk.ru>
 wrote:

 Hello all.
 I have some enum foo { first=1, second=2, fourth=4, sixth=6} and I'd
 like to go through this enumeration like it:
 foreach(m; foo.min..foo.max) {
     bar(m);
 }
 But without excluding foo.max and correct handle situation when enum
 identifiers aren't consequentive.

 Thanks in advance
Looking for this? http://dlang.org/phobos/std_traits.html#EnumMembers
Yes, this is what I need, thanks!
Aug 12 2012
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, August 12, 2012 17:36:21 Alexandr Druzhinin wrote:
 Hello all.
 I have some enum foo { first=1, second=2, fourth=4, sixth=6} and I'd
 like to go through this enumeration like it:
 foreach(m; foo.min..foo.max) {
 	bar(m);
 }
 But without excluding foo.max and correct handle situation when enum
 identifiers aren't consequentive.
foreach(m; std.traits.EnumMembers!foo) bar(m); Though be aware that since EnumMembers results in a TypeTuple, the foreach is actually done at compile time, meaning that you'd actually be getting bar(foo.first); bar(foo.second); bar(foo.fourth); bar(foo.sixth); Normally, that doesn't matter, but if you try and do fancier stuff, the fact that the foreach is executed at compile time could affect what you're doing, and if want your function to be small (e.g. inlining), then that would cause problems. - Jonathan M Davis
Aug 12 2012
next sibling parent Alexandr Druzhinin <drug2004 bk.ru> writes:
12.08.2012 17:45, Jonathan M Davis пишет:
 On Sunday, August 12, 2012 17:36:21 Alexandr Druzhinin wrote:
 Hello all.
 I have some enum foo { first=1, second=2, fourth=4, sixth=6} and I'd
 like to go through this enumeration like it:
 foreach(m; foo.min..foo.max) {
 	bar(m);
 }
 But without excluding foo.max and correct handle situation when enum
 identifiers aren't consequentive.
foreach(m; std.traits.EnumMembers!foo) bar(m); Though be aware that since EnumMembers results in a TypeTuple, the foreach is actually done at compile time, meaning that you'd actually be getting bar(foo.first); bar(foo.second); bar(foo.fourth); bar(foo.sixth); Normally, that doesn't matter, but if you try and do fancier stuff, the fact that the foreach is executed at compile time could affect what you're doing, and if want your function to be small (e.g. inlining), then that would cause problems. - Jonathan M Davis
didn't know about this module, definitly I'll take a look at it, thanks!
Aug 12 2012
prev sibling parent reply "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Sunday, 12 August 2012 at 10:45:37 UTC, Jonathan M Davis wrote:
 Though be aware that since EnumMembers results in a TypeTuple, 
 the foreach is actually done at compile time, meaning that 
 you'd actually be getting

 bar(foo.first);
 bar(foo.second);
 bar(foo.fourth);
 bar(foo.sixth);

 Normally, that doesn't matter, but if you try and do fancier 
 stuff, the fact that the foreach is executed at compile time 
 could affect what you're doing, and if want your function to be 
 small (e.g. inlining), then that would cause problems.
But that problem goes away if you turn it into a small array right? (And pass the array to the foreach to cycle over) So throwing that idea out there you get... foo[] array; foreach(m; std.traits.EnumMembers!foo) array ~= m; foreach(m; array) { //not compiler-time expansion like above }
Aug 12 2012
next sibling parent Alexandr Druzhinin <drug2004 bk.ru> writes:
12.08.2012 18:23, Era Scarecrow пишет:
 On Sunday, 12 August 2012 at 10:45:37 UTC, Jonathan M Davis wrote:
 Though be aware that since EnumMembers results in a TypeTuple, the
 foreach is actually done at compile time, meaning that you'd actually
 be getting

 bar(foo.first);
 bar(foo.second);
 bar(foo.fourth);
 bar(foo.sixth);

 Normally, that doesn't matter, but if you try and do fancier stuff,
 the fact that the foreach is executed at compile time could affect
 what you're doing, and if want your function to be small (e.g.
 inlining), then that would cause problems.
But that problem goes away if you turn it into a small array right? (And pass the array to the foreach to cycle over) So throwing that idea out there you get... foo[] array; foreach(m; std.traits.EnumMembers!foo) array ~= m; foreach(m; array) { //not compiler-time expansion like above }
It's very useful tip, thank you too!
Aug 12 2012
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Era Scarecrow:

  But that problem goes away if you turn it into a small array 
 right? (And pass the array to the foreach to cycle over) So 
 throwing that idea out there you get...

 foo[] array;

 foreach(m; std.traits.EnumMembers!foo)
     array ~= m;

 foreach(m; array) {
  //not compiler-time expansion like above
 }
Often better (but every time builds an array on the heap): foreach (m; [EnumMembers!Foo]) { // Not a static foreach } Bye, bearophile
Aug 12 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/12/2012 01:54 PM, bearophile wrote:
 Era Scarecrow:

 But that problem goes away if you turn it into a small array right?
 (And pass the array to the foreach to cycle over) So throwing that
 idea out there you get...

 foo[] array;

 foreach(m; std.traits.EnumMembers!foo)
 array ~= m;

 foreach(m; array) {
 //not compiler-time expansion like above
 }
Often better (but every time builds an array on the heap): foreach (m; [EnumMembers!Foo]) { // Not a static foreach } Bye, bearophile
This builds the array once at compile time: static immutable members = [EnumMembers!Foo]; foreach(m; members){ }
Aug 12 2012
parent "bearophile" <bearophileHUGS lycos.com> writes:
Timon Gehr:

 This builds the array once at compile time:

 static immutable members = [EnumMembers!Foo];
 foreach(m; members){

 }
Right: import std.traits; enum Foo { A, B, C, D, E, F } int main() { static immutable members = [EnumMembers!Foo]; int count = 0; foreach (m; members) count++; foreach (m; members) count++; return count; } __Dmain: push EAX xor EAX, EAX xor EDX, EDX cmp _D4temp4mainFZi7membersyAE4temp3Foo, EAX je L17 LD: inc EAX inc EDX cmp EDX, _D4temp4mainFZi7membersyAE4temp3Foo jb LD L17: xor EDX, EDX cmp _D4temp4mainFZi7membersyAE4temp3Foo, EDX je L2B L21: inc EAX inc EDX cmp EDX, _D4temp4mainFZi7membersyAE4temp3Foo jb L21 L2B: pop ECX ret Bye, bearophile
Aug 12 2012