473,471 Members | 1,868 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

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.
Jan 25 '06 #1
9 53540
Fred Zwarts wrote:
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.


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

Jan 25 '06 #2
Fred Zwarts wrote:
What is the recommended way to loop over all enum values of a certain enum type?
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.
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.
And that's true.
2) Other compilers complain that the test x<=D is always true.
That's not necessarily true.
3) Other compiler compile, but at run time illegal values are assigned to x.
No such thing as "illegal" as long as the value is within the range
represented by the enum base type.
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.
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.
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?


No such thing.

V
Jan 25 '06 #3

mlimber wrote:
Fred Zwarts wrote:
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.


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.


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

Jan 25 '06 #4

mlimber wrote:
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.


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.

Jan 25 '06 #5
mlimber wrote:
Fred Zwarts wrote:
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;
[..]


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.


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
Jan 25 '06 #6

Victor Bazarov wrote:
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.


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.

Jan 25 '06 #7
Victor Bazarov wrote:
mlimber wrote:
Fred Zwarts wrote:
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;
[..]


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.


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


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

Jan 25 '06 #8
Fred Zwarts wrote:
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.
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.

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?


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
Jan 25 '06 #9
In article <dr**********@info.service.rug.nl>,
"Fred Zwarts" <F.******@KVI.nl> wrote:
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;
.....if (x==D) break;
Has someone found a simpler solution?

Fred.Zwarts.


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
Jan 26 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
by: Glenn Venzke | last post by:
I'm writing a class with a method that will accept 1 of 3 items listed in an enum. Is it possible to pass the item name without the enum name in your calling statement? EXAMPLE: public enum...
0
by: Vaclav Haisman | last post by:
Motivation: I have been working on some project recently that uses lots of enums with disjunctive intervals of values because it is rather convenient way to define series of constants with...
3
by: Richard | last post by:
Okay gang, This should be simple but apparently it's not... I want to use the System.DayOfWeek enum to create and access an array of objects with one object for each day of the week. I'd like...
13
by: Adam Blair | last post by:
Is it possible to bind a switch statement to an Enum such that a compile-time error is raised if not all values within the Enum are handled in the switch statement? I realise you can use default:...
18
by: Visual Systems AB \(Martin Arvidsson\) | last post by:
Hi! I have created an enum list like this: enum myEnum : int { This = 2, That, NewVal = 10, LastItm
3
by: giant food | last post by:
This seems like a long shot, but I wondered if there's a way to loop over the values in an Enum. For example, say I have an Enum as follows: Public Enum statusValues Ready Running Finished...
34
by: Steven Nagy | last post by:
So I was needing some extra power from my enums and implemented the typesafe enum pattern. And it got me to thinking... why should I EVER use standard enums? There's now a nice little code...
6
by: bsma1 | last post by:
I building a web service that has an enum I want the consuming application to be able to use. I have the enum declared in the web service as: public enum myEnum { ONE = 1, TWO = 2, };
1
by: jerry | last post by:
i have written a simple phonebook program,i'll show you some of the codes,the program's head file is member.h . i suppose the head file works well.so i don't post it. here's the clips of main...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.