Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing enum to next value [C++11]

What I want to do is to use enum to specify different draw modes easily. So far this is what I've got:

class Grid {
   enum drawMode { GRID, EROSION, RIVERS, HUMIDITY, ATMOSPHERE }
   drawMode activeDraw;

   void draw() {
      switch(activeDraw) {
      case GRID:
         drawGrid();
         break;
      case EROSION:
         drawErosion();
         break;
      // etc..
   }

   void keyPressed(int key) {
      switch(key) {
      case ' ':
         // Cycle activeDraw to next drawMode
      }
}

So if user hits spacebar the activeDraw will change to next value from enum. So if the current activeDraw is GRID after hitting space it will change to EROSION and if activeDraw is ATMOSPHERE it will change to GRID.
Is there a simple solution to this? Thanks.

like image 777
Maroš Beťko Avatar asked Dec 05 '16 17:12

Maroš Beťko


People also ask

Can you change the value of an enum in C?

You can change default values of enum elements during declaration (if necessary).

How do I change the value of an enum?

Enum constants are implicitly static and final and you can not change their value once created. Enum in Java provides type-safety and can be used inside switch statements like int variables.

Can you increment an enum in C?

Nothing in the C Standard prevent incrementing variables of enum types. Of course the value of bla is just incremented by 1 , it may correspond to another enumeration value or not, depending on the actual values of the enumeration values in the enum type.

How do you increment an enum?

Incrementing an enumeration requires a cast to convert the integer result of addition back to the enumeration type, as in: d = day(d + 1);


2 Answers

As noted by Maroš Beťko, to add 1 to a variable, you have to cast the value to int and back:

activeDraw = static_cast<drawMode>(static_cast<int>(activeDraw) + 1);

If the enum is defined without the C++11 enum class syntax (like in the question's text), the casting to int is not necessary:

activeDraw = static_cast<drawMode>(activeDraw + 1);

To make it cycle back to zero, use integer arithmetic, modulo operator:

activeDraw = static_cast<drawMode>((activeDraw + 1) % (ATMOSPHERE + 1));    

To eliminate one ugly +1, add another element to the enum:

enum drawMode { ..., ATMOSPHERE, NUM_DRAW_MODES };
...
activeDraw = static_cast<drawMode>((activeDraw + 1) % NUM_DRAW_MODES);

You can also stuff this code into a operator++ if you use it very often:

drawMode operator++(drawMode& mode)
{
    mode = static_cast<drawMode>((mode + 1) % NUM_DRAW_MODES);
    return mode;
}

drawMode operator++(drawMode& mode, int) // postfix operator
{
    drawMode result = mode;
    ++mode;
    return result;
}

Overloading operators for enums is rarely used, and some people consider it overkill (bad), but it will make your code shorter (and arguably cleaner).

like image 157
2 revs, 2 users 99% Avatar answered Sep 27 '22 19:09

2 revs, 2 users 99%


Since your enumerates don't have a forced value, you could "increase" them, and perform a modulo on the last item + 1 to reset to the first one when needed:

 activeDraw = drawMode((activeDraw+1) % (ATMOSPHERE+1));

BTW: also works in C language with a slight modification:

activeDraw = (activeDraw+1) % (ATMOSPHERE+1);
like image 28
Jean-François Fabre Avatar answered Sep 27 '22 21:09

Jean-François Fabre