sergiol
sergiol

Reputation: 4335

What is the best way for non sequencial integer c++ enums

Following the C++ enum pattern I already described here, I was trying to do a similar thing but this time the sequence of values I want to use is not comprehended of continuous integer numbers.

The code is obviously wrong:

class Rotations
{
    enum PossibleIndexes
    {
        ZERO,
        PLUS180,
        PLUS90,
        MINUS90
    };


    enum PossibleValues
    {
        ZERO= 0,
        PLUS180= 180,
        PLUS90= 90,
        MINUS90= -90
    };

    static int Count() { return MINUS90 + 1; }

    static PossibleValues Default(){ return ZERO; }
};

as there will be conflicts between elements inherent of the two enums.

So my question is: What is the best approach to implement a fixed number of hardcoded Rotations{0, 180, 90, -90} which has also a Default and a Count functionality?

Upvotes: 3

Views: 395

Answers (3)

sergiol
sergiol

Reputation: 4335

Due to the limitations of Visual C++ 2010 Compilation Toolkit (not fully C++11 compliant), I had to surrender myself to inferior approaches.

The post at https://stackoverflow.com/a/15961043/383779 also suggested me an interesting approach for getting the values.

class Rotations
{
public:
    typedef enum
    {
        ZERO= 0,
        PLUS180= 180,
        PLUS90 = 90,
        MINUS90 = -90
    }PossibleValues;

    static const PossibleValues PossibleValuesCollection(int index) {
        static const PossibleValues values[] = { ZERO, PLUS180, PLUS90, MINUS90 };

        return values[index];
    }

    static int Count() { return 4; }
    static PossibleValues Default(){ return ZERO; }
};

Upvotes: 0

antron
antron

Reputation: 3847

Disclaimer: I am mentioning an open-source library that I recently published.

You may want to look at Better Enums. It will save you from having to repeat anything.

#include <enum.h>
ENUM(Rotations, int, ZERO = 0, PLUS180 = 180, PLUS90 = 90, MINUS90 = -90)

You could then access the number of constants as

Rotations::_size

There is currently no built-in way of declaring a default value. However, the default constructor is currently private, so you would be forced to provide a value when creating a Rotations value. There is a syntactically "nice" way to do this shown here – look at how invalid is defined using a template. It might be complete overkill for your needs. If you try this library and have any feedback concerning default values, please let me know.

I should note that the count and default value are generated at compile time.

Upvotes: 1

KABoissonneault
KABoissonneault

Reputation: 2369

You can always keep a static std::initializer_list containing all possible values

namespace PossibleValues
{
    enum Type
    {
        ZERO= 0,
        PLUS180= 180,
        PLUS90= 90,
        MINUS90= -90
    };

    constexpr auto Values = {ZERO, PLUS180, PLUS90, MINUS90};
    size_t Count() { return Values.size(); }
    Type Default() { return *begin(Values); }
}

This approach will have the added bonus of being able to iterate of the values of the enum in a for-loop

Note: I wish the compiler could generate all that code though, at least for enum class

Upvotes: 4

Related Questions