473,786 Members | 2,380 Online
Bytes | Software Development & Data Engineering Community
+ 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 53805
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 NoParticularOrd er { 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 NoParticularOrd er { 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 NoParticularOrd er { 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**********@i nfo.service.rug .nl>,
"Fred Zwarts" <F.******@KVI.n l> 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
4851
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 EnumName FirstValue = 1 SecondValue = 2 ThirdValue = 3
0
1746
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 consecutive values. The problem is that some functions should only accept some of the ranges. To store values of more than one range/enum in variable one has to use int as storage which imho compromises type safety because any function that wants to...
3
16078
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 the array declaration to be strongly typed to the enum and I'd like to use the enum to access entries in the array. I'd like to write code something like this: #using System;
13
3073
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: to catch unhandled cases, but of course this is only at run-time. Example: public enum MyEnum { one, two, three, four }
18
11371
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
15106
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 Error End Enum
34
11205
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 snippet that I wrote today that gives me an instant implementation of the pattern. I could easily just always use such an implementation instead of a standard enum, so I wanted to know what you experts all thought. Is there a case for standard enums?
6
10060
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
6021
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 function which i think has problem // this a simple program about phonebook,it can add items,del items,find items and #include "member.h" #include <fstream> #include <vector>
0
9492
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10360
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10163
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9960
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8988
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7510
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5397
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5532
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2894
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.