Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old January 25th, 2006, 02:35 PM
Fred Zwarts
Guest
 
Posts: n/a
Default Loop over enum values

What is the recommended way to loop over all enum values of a certain enum type?

Consider the following definition:

typdef enum {A=2, B, C=5, D} E;

then

for (E x = A; x <= D; ++x) { ... }

does not work because

1) Some compilers complain that the ++ operator is not defined for enum types.
2) Other compilers complain that the test x<=D is always true.
3) Other compiler compile, but at run time illegal values are assigned to x.

I can, of course, define a ++ operator for E, but the code would probably consist
of a switch ... case construction, which is error prone, because modification of
the definition of E does not automatically adjust the cases within the ++ operator.
The problem that x<=D is always true could be solved by using a conditional break
at the end of the loop.
if (x==D) break;
Has someone found a simpler solution?

Fred.Zwarts.
  #2  
Old January 25th, 2006, 02:55 PM
mlimber
Guest
 
Posts: n/a
Default Re: Loop over enum values

Fred Zwarts wrote:[color=blue]
> What is the recommended way to loop over all enum values of a certain enum type?
>
> Consider the following definition:
>
> typdef enum {A=2, B, C=5, D} E;
>
> then
>
> for (E x = A; x <= D; ++x) { ... }
>
> does not work because
>
> 1) Some compilers complain that the ++ operator is not defined for enum types.
> 2) Other compilers complain that the test x<=D is always true.
> 3) Other compiler compile, but at run time illegal values are assigned to x.
>
> I can, of course, define a ++ operator for E, but the code would probably consist
> of a switch ... case construction, which is error prone, because modification of
> the definition of E does not automatically adjust the cases within the ++ operator.
> The problem that x<=D is always true could be solved by using a conditional break
> at the end of the loop.
> if (x==D) break;
> Has someone found a simpler solution?
>
> Fred.Zwarts.[/color]

I generally define an enum with min and max values and then run for
loops using those:

enum E { MIN, A=MIN, B, C, D, MAX=D };
for( E e=MIN; e <= MAX; e = E( e+1 ) ) {...}

That way, if the enum changes by adding or subtracting values, my for
loops don't change because I have already updated MIN and MAX, which
practice is admittedly somewhat fragile but it is less so than not
using MIN and MAX, IMHO.

Cheers! --M

  #3  
Old January 25th, 2006, 03:05 PM
Victor Bazarov
Guest
 
Posts: n/a
Default Re: Loop over enum values

Fred Zwarts wrote:[color=blue]
> What is the recommended way to loop over all enum values of a certain enum type?[/color]

You can overload ++ for the enum, but you will have to manually ensure
that the next value is the one from the declared/defined enumerators.
[color=blue]
> Consider the following definition:
>
> typdef enum {A=2, B, C=5, D} E;
>
> then
>
> for (E x = A; x <= D; ++x) { ... }
>
> does not work because
>
> 1) Some compilers complain that the ++ operator is not defined for enum types.[/color]

And that's true.
[color=blue]
> 2) Other compilers complain that the test x<=D is always true.[/color]

That's not necessarily true.
[color=blue]
> 3) Other compiler compile, but at run time illegal values are assigned to x.[/color]

No such thing as "illegal" as long as the value is within the range
represented by the enum base type.
[color=blue]
> I can, of course, define a ++ operator for E, but the code would probably consist
> of a switch ... case construction, which is error prone, because modification of
> the definition of E does not automatically adjust the cases within the ++ operator.[/color]

That's what you'll have to do if you want to iterate "over" those values.
Enumerations are not there to be iterated over. They represent "typed
constants". If you want to iterate, use an array or a standard container.
[color=blue]
> The problem that x<=D is always true could be solved by using a conditional break
> at the end of the loop.
> if (x==D) break;
> Has someone found a simpler solution?[/color]

No such thing.

V
  #4  
Old January 25th, 2006, 03:05 PM
Gavin Deane
Guest
 
Posts: n/a
Default Re: Loop over enum values


mlimber wrote:[color=blue]
> Fred Zwarts wrote:[color=green]
> > What is the recommended way to loop over all enum values of a certain enum type?
> >
> > Consider the following definition:
> >
> > typdef enum {A=2, B, C=5, D} E;
> >
> > then
> >
> > for (E x = A; x <= D; ++x) { ... }
> >
> > does not work because
> >
> > 1) Some compilers complain that the ++ operator is not defined for enum types.
> > 2) Other compilers complain that the test x<=D is always true.
> > 3) Other compiler compile, but at run time illegal values are assigned to x.
> >
> > I can, of course, define a ++ operator for E, but the code would probably consist
> > of a switch ... case construction, which is error prone, because modification of
> > the definition of E does not automatically adjust the cases within the ++ operator.
> > The problem that x<=D is always true could be solved by using a conditional break
> > at the end of the loop.
> > if (x==D) break;
> > Has someone found a simpler solution?
> >
> > Fred.Zwarts.[/color]
>
> I generally define an enum with min and max values and then run for
> loops using those:
>
> enum E { MIN, A=MIN, B, C, D, MAX=D };
> for( E e=MIN; e <= MAX; e = E( e+1 ) ) {...}
>
> That way, if the enum changes by adding or subtracting values, my for
> loops don't change because I have already updated MIN and MAX, which
> practice is admittedly somewhat fragile but it is less so than not
> using MIN and MAX, IMHO.[/color]

I don't thnik that helps the OP's "at run time illegal values are
assigned to e" problem. In the OP's code, not every integer between MIN
and MAX had a corresponding value in the enum.

Gavin Deane

  #5  
Old January 25th, 2006, 03:05 PM
roberts.noah@gmail.com
Guest
 
Posts: n/a
Default Re: Loop over enum values


mlimber wrote:
[color=blue]
> I generally define an enum with min and max values and then run for
> loops using those:
>
> enum E { MIN, A=MIN, B, C, D, MAX=D };
> for( E e=MIN; e <= MAX; e = E( e+1 ) ) {...}
>
> That way, if the enum changes by adding or subtracting values, my for
> loops don't change because I have already updated MIN and MAX, which
> practice is admittedly somewhat fragile but it is less so than not
> using MIN and MAX, IMHO.[/color]

The OP has bigger problems than that caused by assigning values to the
enums. There are ranges within the overall range that are invalid.

I do the same thing but I don't assign MAX to the last value. That way
I don't have to use <= but can just use <. I'm of the school of
thought that if you are using <= in a C or C++ loop then you should be
double checking that there is no logic error because it isn't natural
for most situations.

  #6  
Old January 25th, 2006, 03:15 PM
Victor Bazarov
Guest
 
Posts: n/a
Default Re: Loop over enum values

mlimber wrote:[color=blue]
> Fred Zwarts wrote:
>[color=green]
>>What is the recommended way to loop over all enum values of a certain enum type?
>>
>>Consider the following definition:
>>
>>typdef enum {A=2, B, C=5, D} E;
>> [..][/color]
>
> I generally define an enum with min and max values and then run for
> loops using those:
>
> enum E { MIN, A=MIN, B, C, D, MAX=D };
> for( E e=MIN; e <= MAX; e = E( e+1 ) ) {...}
>
> That way, if the enum changes by adding or subtracting values, my for
> loops don't change because I have already updated MIN and MAX, which
> practice is admittedly somewhat fragile but it is less so than not
> using MIN and MAX, IMHO.[/color]

Notice the difference between the two definitions: Yours doesn't have
gaps as the OP's. Essentially what you have here is not a set of
unrelated (in values) typed constants but a range. It is generally
allowed to have any order of values in there. Since those values have
no particular ordering runing over then with a regular ++ makes no sense.

enum NoParticularOrder { ONE = 777, TWO = 22, THREE = 3 };

Now, try getting the sequence [ ONE, TWO, THREE ] out of it. There is no
way except to provide a custom ++ operator in which there is a 'switch'
statement that implements the business logic of "moving to the next value"
"along" that enumeration.

V
  #7  
Old January 25th, 2006, 03:15 PM
roberts.noah@gmail.com
Guest
 
Posts: n/a
Default Re: Loop over enum values


Victor Bazarov wrote:
[color=blue]
> Notice the difference between the two definitions: Yours doesn't have
> gaps as the OP's. Essentially what you have here is not a set of
> unrelated (in values) typed constants but a range. It is generally
> allowed to have any order of values in there. Since those values have
> no particular ordering runing over then with a regular ++ makes no sense.
>
> enum NoParticularOrder { ONE = 777, TWO = 22, THREE = 3 };
>
> Now, try getting the sequence [ ONE, TWO, THREE ] out of it. There is no
> way except to provide a custom ++ operator in which there is a 'switch'
> statement that implements the business logic of "moving to the next value"
> "along" that enumeration.[/color]

A lookup table would probably be more manageable. The OP probably also
wants a class built just to deal with this thing; then they could make
some sort of iterator to abstract the mess of looping through the
values.

  #8  
Old January 25th, 2006, 03:25 PM
mlimber
Guest
 
Posts: n/a
Default Re: Loop over enum values

Victor Bazarov wrote:[color=blue]
> mlimber wrote:[color=green]
> > Fred Zwarts wrote:
> >[color=darkred]
> >>What is the recommended way to loop over all enum values of a certain enum type?
> >>
> >>Consider the following definition:
> >>
> >>typdef enum {A=2, B, C=5, D} E;
> >> [..][/color]
> >
> > I generally define an enum with min and max values and then run for
> > loops using those:
> >
> > enum E { MIN, A=MIN, B, C, D, MAX=D };
> > for( E e=MIN; e <= MAX; e = E( e+1 ) ) {...}
> >
> > That way, if the enum changes by adding or subtracting values, my for
> > loops don't change because I have already updated MIN and MAX, which
> > practice is admittedly somewhat fragile but it is less so than not
> > using MIN and MAX, IMHO.[/color]
>
> Notice the difference between the two definitions: Yours doesn't have
> gaps as the OP's. Essentially what you have here is not a set of
> unrelated (in values) typed constants but a range. It is generally
> allowed to have any order of values in there. Since those values have
> no particular ordering runing over then with a regular ++ makes no sense.
>
> enum NoParticularOrder { ONE = 777, TWO = 22, THREE = 3 };
>
> Now, try getting the sequence [ ONE, TWO, THREE ] out of it. There is no
> way except to provide a custom ++ operator in which there is a 'switch'
> statement that implements the business logic of "moving to the next value"
> "along" that enumeration.
>
> V[/color]

As Victor and others point out, I missed the gap, and a switch (or a
masked version of it which don't seem to hold much advantage over a
switch) is required.

Cheers! --M

  #9  
Old January 25th, 2006, 03:25 PM
Kai-Uwe Bux
Guest
 
Posts: n/a
Default Re: Loop over enum values

Fred Zwarts wrote:
[color=blue]
> What is the recommended way to loop over all enum values of a certain enum
> type?
>
> Consider the following definition:
>
> typdef enum {A=2, B, C=5, D} E;
>
> then
>
> for (E x = A; x <= D; ++x) { ... }
>
> does not work because
>
> 1) Some compilers complain that the ++ operator is not defined for enum
> types. 2) Other compilers complain that the test x<=D is always true.
> 3) Other compiler compile, but at run time illegal values are assigned to
> x.[/color]

Your phrase "illegal values" probably refers to values not defined by any of
the enumerators. Be informed that those values are actually legal:

[Standard, clause 7.2/6]

For an enumeration where emin is the smallest enumerator and emax is the
largest, the values of the enumeratio are the values of the underlying
type in the range bmin to bmax, where bmin and bmax are, respectively, the
smallest and largest values of the smallest bit-field that can store emin
and emax.81) It is possible t define an enumeration that has values not
defined by any of its enumerators.

[color=blue]
> I can, of course, define a ++ operator for E, but the code would probably
> consist of a switch ... case construction, which is error prone, because
> modification of the definition of E does not automatically adjust the
> cases within the ++ operator. The problem that x<=D is always true could
> be solved by using a conditional break at the end of the loop.
> if (x==D) break;
> Has someone found a simpler solution?[/color]

Since the non-enumerated values actually are legal, you have to decide
whether you want to include them in the iteration or not. If you do, you
can use casting and arithmetic of the underlying integral type. If not,
your could (a) make sure that there are no gaps or (b) use the switch
statement.


Best

Kai-Uwe Bux
  #10  
Old January 26th, 2006, 04:25 PM
shaun
Guest
 
Posts: n/a
Default Re: Loop over enum values

In article <dr7vv0$s8b$1@info.service.rug.nl>,
"Fred Zwarts" <F.Zwarts@KVI.nl> wrote:
[color=blue]
>What is the recommended way to loop over all enum values of a certain enum
>type?
>
>Consider the following definition:
>
>typdef enum {A=2, B, C=5, D} E;
>[/color]
.....[color=blue]
>if (x==D) break;
>Has someone found a simpler solution?
>
>Fred.Zwarts.[/color]

I'm going to second-guess your intention and suggest an alternative:
I guess you have some 'magic numbers' which you are coding in an enum.
Why not make a const vector, and initialize from an old fashioned array:

e.g somewhere in your cpp file:

const int intTable[]={ 2, 3, 5, 6 };

template <class T>
T* endof( T * const parray){
int numElements = sizeof(parray)/sizeof(parray[0]);
return parray + numElements;
}

const vector<int> E(intTable, endof(intTable));//range constructor



The 'endof' function can deal with different types of table. The
intTable can be added to without changing the remainder of the code. The
vector, of course, can be iterated over.

Good luck

shaun
 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles