Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(How) can I count the items in an enum?

This question came to my mind, when I had something like

enum Folders {FA, FB, FC}; 

and wanted to create an array of containers for each folder:

ContainerClass*m_containers[3]; .... m_containers[FA] = ...; // etc. 

(Using maps it's much more elegant to use: std::map<Folders, ContainerClass*> m_containers;)

But to come back to my original question: What if I do not want to hard-code the array size, is there a way to figure out how many items are in Folders? (Without relying on e.g. FC being the last item in the list which would allow something like ContainerClass*m_containers[FC+1] if I'm not mistaken.)

like image 454
fuenfundachtzig Avatar asked Jan 20 '10 15:01

fuenfundachtzig


People also ask

How do you find the number of elements in an enum?

Use the len() class to get the number of elements in an enum, e.g. len(Color) . The len() function returns the length (the number of items) of an object and can directly be passed an enum.

How many values can an enum have?

In theory, an ENUM column can have a maximum of 65,535 distinct values; in practice, the real maximum depends on many factors. ENUM values are represented internally as integers.

Can enums have numbers?

Numeric EnumNumeric enums are number-based enums i.e. they store string values as numbers. Enums are always assigned numeric values when they are stored. The first value always takes the numeric value of 0, while the other values in the enum are incremented by 1.


2 Answers

There's not really a good way to do this, usually you see an extra item in the enum, i.e.

enum foobar {foo, bar, baz, quz, FOOBAR_NR_ITEMS}; 

So then you can do:

int fuz[FOOBAR_NR_ITEMS]; 

Still not very nice though.

But of course you do realize that just the number of items in an enum is not safe, given e.g.

enum foobar {foo, bar = 5, baz, quz = 20}; 

the number of items would be 4, but the integer values of the enum values would be way out of the array index range. Using enum values for array indexing is not safe, you should consider other options.

edit: as requested, made the special entry stick out more.

like image 190
wich Avatar answered Sep 30 '22 01:09

wich


For C++, there are various type-safe enum techniques available, and some of those (such as the proposed-but-never-submitted Boost.Enum) include support for getting the size of a enum.

The simplest approach, which works in C as well as C++, is to adopt a convention of declaring a ...MAX value for each of your enum types:

enum Folders { FA, FB, FC, Folders_MAX = FC }; ContainerClass *m_containers[Folders_MAX + 1]; .... m_containers[FA] = ...; // etc. 

Edit: Regarding { FA, FB, FC, Folders_MAX = FC} versus {FA, FB, FC, Folders_MAX]: I prefer setting the ...MAX value to the last legal value of the enum for a few reasons:

  1. The constant's name is technically more accurate (since Folders_MAX gives the maximum possible enum value).
  2. Personally, I feel like Folders_MAX = FC stands out from other entries out a bit more (making it a bit harder to accidentally add enum values without updating the max value, a problem Martin York referenced).
  3. GCC includes helpful warnings like "enumeration value not included in switch" for code such as the following. Letting Folders_MAX == FC + 1 breaks those warnings, since you end up with a bunch of ...MAX enumeration values that should never be included in switch.
 switch (folder)  {   case FA: ...;   case FB: ...;   // Oops, forgot FC! } 
like image 45
Josh Kelley Avatar answered Sep 29 '22 23:09

Josh Kelley