1

I am trying to achieve the following but in a way that follows the c++ standard :

#include <iostream>

using namespace std;



#define MAKE_BOTH(MAKE_FUNC) \
        MAKE_FUNC(FIRST) \
        MAKE_FUNC(SECOND) \
        MAKE_FUNC(THIRD) \
        MAKE_FUNC(FOURTH)

#define MAKE_STRINGS(NAME) #NAME,

const char* genericString[] {
        MAKE_BOTH(MAKE_STRINGS)
};

#define MAKE_ENUM(NAME) NAME = (1L << __COUNTER__),

enum genericEnum {
        MAKE_BOTH(MAKE_ENUM)

};



int main()
{
    cout << FIRST << endl;
    cout << SECOND << endl;
    cout << THIRD << endl;
    cout << FOURTH << endl;
}

If you think a while about this code, this creates both, enums and array of "strings" which consists of the same names as enums. The examle code expands to :

const char* genericString[] {
    "FIRST",
    "SECOND",
    "THIRD",
    "FOURTH"
};

enum genericEnum {
    FIRST = 1L << 0; (1)
    SECOND = 1L << 1; (2)
    THIRD  = 1L << 2; (4)
    FOURTH = 1L << 3; (8)
};

Basically the enums are assigned power of 2 values, the question is - is there a relatively simple way of achieving the same thing without using COUNTER ?

The problem is similar to this one: Counting preprocessor macros but I have to increase the value of counter each time the macro is used at compile time, I could not figure out how to do it without using the non-standard COUNTER macro.

Please beware the c++ 11 is not an option, but using boost is, I tried the boost approach as well but it is not possible to call the #include directive by a macro which unables me from incrementing the boost preprocessor counter.

Community
  • 1
  • 1
Sebbie
  • 29
  • 6
  • 2
    Please just generate the code using an external program. Nobody will be able to understand this code, regardless of whether a COUNTER is possible. When somebody wants to find the value of, say, `THIRD` in their IDE, they will be greeted with `MAKE_BOTH(ENUM)`... that's not helpful. – Barry Nov 21 '14 at 12:13
  • Notice that `__COUNTER__` is a [GCC](http://gcc.gnu.org/) extension available in its [cpp](https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html) and in [Clang/LLVM](http://clang.llvm.org/docs/LanguageExtensions.html). So you are pretty safe in using it, and you might have trouble replacing it... – Basile Starynkevitch Nov 21 '14 at 13:09
  • 1
    @Barry: I disagree. I've seen this technique quite a few times already (without counter - the numbers were simply included if needed) and would consider it more or less usual. – Jan Hudec Nov 21 '14 at 13:14
  • 1
    Possible drawback of using COUNTER is that it may be used in some included files before, so COUNTER may start from arbitrary value not necessary 0 – user396672 Nov 21 '14 at 13:17

1 Answers1

1

You may generate something like this:

enum genericEnum
{

    MY_ENUM_BASE=0,

    FIRST,
    PAST_FIRST= (FIRST<<1)-1,

    SECOND,
    PAST_SECOND= (SECOND<<1)-1,

    THIRD,
    PAST_THIRD= (THIRD<<1)-1,

    FOURTH,
    PAST_FOURTH= (FOURTH<<1)-1,

};

using standard macroprocessor without using COUNTER, i.e. defining MAKE_ENUM as

#define MAKE_ENUM(NAME) NAME, PAST##_NAME= (NAME<<1)-1,
user396672
  • 3,106
  • 1
  • 21
  • 31