What would be the best way to implement an enumeration with circular values, and appropriate functions to transition from a value to another?
For example:
enum class Direction {
NORTH, EAST, SOUTH, WEST
};
constexpr Direction left(Direction d) {
return (Direction)((std::underlying_type<Directions>::type(d) - 1) % 4);
}
However, I feel that this is error prone and generally unreadable. Is there a more proper way to deal with this type of enumerations?
You could always do:
enum class Direction {
NORTH, EAST, SOUTH, WEST, NUMBER_OF_DIRECTIONS
};
constexpr Direction left(Direction d) {
using ut = std::underlying_type<Direction>::type;
return (Direction)((ut(d) + ut(Direction::NUMBER_OF_DIRECTIONS)-1)
% ut(Direction::NUMBER_OF_DIRECTIONS));
}
Usage example / small test:
#include <iostream>
std::ostream& operator<<(std::ostream& os, Direction d)
{
switch(d)
{
case Direction::NORTH: return os << "NORTH";
case Direction::EAST : return os << "EAST";
case Direction::SOUTH: return os << "SOUTH";
case Direction::WEST : return os << "WEST";
default : return os << "invalid";
}
}
int main()
{
Direction d = Direction::NORTH;
for(int i = 0; i < 2*(int)Direction::NUMBER_OF_DIRECTIONS; ++i)
{
std::cout << d << "\n";
d = left(d);
}
}
Output:
NORTH WEST SOUTH EAST NORTH WEST SOUTH EAST
Live example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With