2

I'm using a technique similar to this to associated information and/or actions with enumerators. It works pretty well, but there's a minor issue of needing to effectively list every constant twice, once in the header file in the enum declaration, and once in the source file in the lookup table. I'm wondering if there's any good way, probably with preprocessor trickery (Boost.Preprocessor is acceptable), to "automate" it so that I can enter the enum constants and associated values etc in just one place and have all the necessary stuff (perhaps even the lookup struct itself) get generated.

I'd prefer a method that maintains vaguely enum-style syntax, if possible; eg, something like DECLARE_ENUM(...) {E_CONST(...), E_CONST(...)};. I've seen some sites mentioning the idea of double-including the header file in order to achieve this, i.e. something like this:

#include "my_enum.hpp"
#undef ENUM_HPP // undefine the include guard
#undef E_CONST
#define E_CONST(...) /* something here */
#include "my_enum.hpp"

...but I'm not sure how useful that technique would be here. In particular, there is more than just the enum defined in the header; the lookup table struct is also there, along with a couple of other related enums and supporting functions.

I'm already using a macro to define the elements in the lookup table (it uses C99 initializers so that the entries will always be in the right place even if I rearrange the order of the enum constants).

A solution that can be applied to multiple enums would be nice as well.

I'm using clang (Apple-3.1) for this and am not particularly worried about portability.

I had an attempt somewhere that I threw away... I can't remember why it didn't work. Maybe I can find it in Time Machine...

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
celticminstrel
  • 1,637
  • 13
  • 21
  • possible duplicate of [Enum to string : return the enum integer value if invalid / not found](http://stackoverflow.com/questions/10175260/enum-to-string-return-the-enum-integer-value-if-invalid-not-found) – Matthieu M. Jul 06 '12 at 06:57
  • In the duplicate linked, I posted an answer using Boost.Preprocessor to generate the enum-to-string conversion (it can be extended for string-to-enum as well). Another question was more centered around external scripting and code generation: http://stackoverflow.com/questions/201593/is-there-a-simple-script-to-convert-c-enum-to-string – Matthieu M. Jul 06 '12 at 06:58
  • Thanks, I'll see what ideas I can get from those two questions. (Actually, I remember seeing that second one before, I think.) – celticminstrel Jul 06 '12 at 07:17
  • possible duplicate of [Easy way to use variables of enum types as string in C?](http://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c) – Bo Persson Jul 06 '12 at 07:25
  • No, this question isn't about getting the name of an enum as a string; it's about reducing code duplication inherent in the process of defining the construct that allows getting the name of an enum as a string. – celticminstrel Jul 06 '12 at 07:40
  • @BoPersson: Nice, Suma's answer is pretty cool. – Matthieu M. Jul 06 '12 at 08:04

3 Answers3

2

Using the preprocessor trick, you would define your enums in a different file (say, enum_foo.def). It would be an unguarded file that gets #included.

ENUM_FOO_DEF(ALPHA, 9, 2)
ENUM_FOO_DEF(BETA, 10, 3)
ENUM_FOO_DEF(GAMMA, 12, 7)
ENUM_FOO_DEF(DELTA, 13, 11)
//...

Then in your source file, you would do something along the lines of:

enum FooEnum {
    #define ENUM_FOO_DEF(X,Y,Z) FOO_E_ ## X,
    #include "enum_foo.def"
    #undef ENUM_FOO_DEF
    FOO_E_MAX
};

And you can do something similar to populate your table of enum attributes.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • Hm. Maybe. I'll contemplate this idea for a bit. Maybe I can use something in Boost.Preprocessor to make it look a bit nicer. – celticminstrel Jul 06 '12 at 07:12
1

Look at my gist for string enums https://gist.github.com/3058317

PSyton
  • 908
  • 11
  • 18
  • 1
    It is recommended to put more than a simple link, because link rot. On the idea itself: it's fairly heavy handed and kinda kills the idea that an enum is a compile-time constant and does not include any runtime overhead. You could also do better with some preprocessing tricks to avoid repeating the macro name over and over. – Matthieu M. Jul 06 '12 at 06:55
  • I think this is a little more than I need in this particular case, though it's something to keep in mind. – celticminstrel Jul 06 '12 at 07:10
  • @ Matthieu M: I know that idea has disadvantages but it can be improved. – PSyton Jul 06 '12 at 09:44
0

Maybe you should write your own code generator which takes some data file with the names and associated values and generates the header file and data table, probably as a standalone C module.

This program will be trivial to write, but immensely powerful for your use.

wallyk
  • 56,922
  • 16
  • 83
  • 148