tags:

views:

240

answers:

4

Could one write a function that returns the number of elements in an enum? For example, say I have defined:

enum E {x, y, z};

Then f(E) would return 3.

+11  A: 

Nope.

If there were, you wouldn't see so much code like this:

enum E {
  VALUE_BLAH,
  VALUE_OTHERBLAH,
  ...
  VALUE_FINALBLAH,
  VALUE_COUNT
}

Note that this code is also a hint for a (nasty) solution -- if you add a final "guard" element, and don't explicitly state the values of the enum fields, then the last "COUNT" element will have the value you're looking for -- this happens because enum count is zero-based:

enum  B {
  ONE,   // has value = 0
  TWO,   // has value = 1
  THREE, // has value = 2
  COUNT  // has value = 3 - cardinality of enum without COUNT
}
Kornel Kisielewicz
Thanks, that seems like as good a solution as I'm going to come up with.
endtime
Which of course only works for continuous enums. If you ever have a 'hole' like in an error code list, you're screwed.
Matthieu M.
I posted a simple macro that do the trick and handles the "holes" issues.
Matthieu M.
+2  A: 

No. For one thing, you can't take types as parameters (just instances of types)

Matthew Flaschen
+2  A: 

No, this is a VFAQ and the answer is NO!!

Not without kludging anyway.

Even that trick about with a final entry only works if none of the values are non-default. E.g.,

enum  B {
         ONE,   // has value = 0
         TWO,   // has value = 1
         THREE=8, // because I don't like threes
         COUNT  // has value = 9 
        }
Mawg
Thanks. Sorry for repeating a VFAQ - I did search both here and the greater web, and couldn't find any instances of this question.
endtime
No problem. I have searched for it often enough myself to know that the gurus say "cain't be dun"
Mawg
+4  A: 

There are ways, but you have to work... a bit :)

Basically you can get it with a macro.

DEFINE_NEW_ENUM(MyEnum, (Val1)(Val2)(Val3 = 6));

size_t s = count(MyEnum());

How does it work ?

#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/size.hpp>

#define DEFINE_NEW_ENUM(Type_, Values_)\
  typedef enum { BOOST_PP_SEQ_ENUM(Values_) } Type_;\
  size_t count(Type_) { return BOOST_PP_SEQ_SIZE(Values_); }

Note that length could also be a template specialization or anything. I dont know about you but I really like the expressiveness of a "Sequence" in BOOST_PP ;)

Matthieu M.
+1 because it works. Although I'm not sure I like the declaration syntax.
ScaryAardvark
Well, there are a few structures to choose from (array, list, sequence and tuple), I could have used a tuple for `DEFINE_NEW_ENUM(MyEnum, (Val1, Val2, Val3 = 6));`. It was merely a demonstration of the usefulness of macros :)
Matthieu M.