VLL
VLL

Reputation: 10155

Check at compile time that multiple enums have unique values

I want to list error codes using multiple enums, so that I can define those enums in different files. How do I check at compile time that all values in these enums are unique?

I am currently defining enums like this:

constexpr int ERROR_CODE_MAX = 1000000;

#define ERRORS1_LIST(f) \
    f(IRRADIANCE_MUST_BE_BETWEEN, 103, L"message1") \
    f(MODULE_MUST_BE_SELECTED, 104, L"message2")

#define GENERATE_ENUM(key, value, name) key = value,
#define GENERATE_LIST(key, value, name) { key, name },

enum Errors1 {
    ERRORS1_LIST(GENERATE_ENUM)
    UndefinedError1 = ERROR_CODE_MAX - 1
};

// Error code 103 is defined twice; should trigger compile error
#define ERRORS2_LIST(f) \
    f(OPERATOR_MUST_BE_SELECTED, 105, L"message3")  \
    f(IRRADIANCE_MUST_BE_BETWEEN2, 103, L"message4")

enum Errors2 {
    ERRORS2_LIST(GENERATE_ENUM)
    UndefinedError2 = ERROR_CODE_MAX - 2
};

// List of all error messages
// I want to check error code uniqueness in the same place where I define this
static const std::map<int, std::wstring> ErrorMessageList = {
    ERRORS1_LIST(GENERATE_LIST)
    ERRORS2_LIST(GENERATE_LIST)
    {UndefinedError1, L"Undefined"}
};

Upvotes: 2

Views: 419

Answers (2)

Ahmed Bahtity
Ahmed Bahtity

Reputation: 571

You cannot do it. The compiler will not restrict the values you could assign to enums. however You could let the compiler check for the duplicate values of enum(s) using switch as following

    enum ERROR_LIST1
{
    ERROR1 = 1,
    IRRADIANCE_MUST_BE_BETWEEN = 103,
};


enum ERROR_LIST2
{
    ERROR3 = 2,
    IRRADIANCE_MUST_BE_BETWEEN2 = 103,
};


void TestDublicateEnumValue() 
{
    int x = 0;
    switch (x)
    {
    case ERROR1 :
    case IRRADIANCE_MUST_BE_BETWEEN:
    case ERROR3 :
    case IRRADIANCE_MUST_BE_BETWEEN2://this will generate compiler error
        break;
    }   
}

Upvotes: 1

VLL
VLL

Reputation: 10155

One way to do this is to create variables using each error code in the variable name:

#define GENERATE_COUNTER(key, value, name) constexpr int IsErrorcodeUnique ## value = 1;

namespace {

ERRORS1_LIST(GENERATE_COUNTER)
ERRORS2_LIST(GENERATE_COUNTER)

} // namespace

Upvotes: 1

Related Questions