Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 12, 2012 Iterating through enumeration | ||||
---|---|---|---|---|
| ||||
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 |
August 12, 2012 Re: Iterating through enumeration | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alexandr Druzhinin | 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 |
August 12, 2012 Re: Iterating through enumeration | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alexandr Druzhinin | 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
|
August 12, 2012 Re: Iterating through enumeration | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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!
|
August 12, 2012 Re: Iterating through enumeration | ||||
---|---|---|---|---|
| ||||
Posted in reply to simendsjo | 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!
|
August 12, 2012 Re: Iterating through enumeration | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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
}
|
August 12, 2012 Re: Iterating through enumeration | ||||
---|---|---|---|---|
| ||||
Posted in reply to Era Scarecrow | 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!
|
August 12, 2012 Re: Iterating through enumeration | ||||
---|---|---|---|---|
| ||||
Posted in reply to Era Scarecrow | 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
|
August 12, 2012 Re: Iterating through enumeration | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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){
}
|
August 12, 2012 Re: Iterating through enumeration | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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 |
Copyright © 1999-2021 by the D Language Foundation