Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Neat way how to cyclically iterate 4 enum class values in both directions in C++?

I have:

enum class orientation {
  North,
  East,
  South,
  West
};

I want to rotate its instance left (North => West) and right (West => North).
But I don't want to convert them to numbers, because it harms readability and intention and also jumping from the last number to first and back is strange.

I came up with lots of solutions, but all are kind of lame :(

like image 922
Lukas Salich Avatar asked Apr 22 '20 20:04

Lukas Salich


People also ask

Can you iterate through an enum in C?

you can iterate the elements like: for(int i=Bar; i<=Last; i++) { ... } Note that this exposes the really-just-an-int nature of a C enum. In particular, you can see that a C enum doesn't really provide type safety, as you can use an int in place of an enum value and vice versa.

What is typedef enum in C?

A typedef is a mechanism for declaring an alternative name for a type. An enumerated type is an integer type with an associated set of symbolic constants representing the valid values of that type.

Can you iterate through an enum class C ++?

Can you loop through an enum C ++? Yes. It iterates over an std::initializer_list<Item>.


1 Answers

Since they're in order:

constexpr auto rotate(orientation o, int n) -> orientation {
    // convert to int
    int dir = (int)o;
    // rotate as an int
    dir = (dir + n) % 4;
    // account for negatives
    if (dir < 0) {
        dir += 4;
    }
    // and then convert back
    return orientation{dir};
}

Which you can check:

static_assert(rotate(orientation::North, 1) == orientation::East);
static_assert(rotate(orientation::North, -1) == orientation::West);

I picked the integer to mean "number of 90 degree turns right" but you can adjust as suitable for your actual problem. Or add helper functions like:

constexpr auto rotate_left(orientation o) -> orientation {
    return rotate(o, -1);
}

constexpr auto rotate_right(orientation o) -> orientation {
    return rotate(o, 1);
}
like image 153
Barry Avatar answered Sep 21 '22 18:09

Barry