Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementation of circular enum values

Tags:

c++

enums

c++11

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?

like image 303
Svalorzen Avatar asked Apr 20 '13 20:04

Svalorzen


1 Answers

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

like image 163
3 revs, 2 users 67% Avatar answered Sep 22 '22 11:09

3 revs, 2 users 67%