The clang developers have an extremely interesting technique for metaprogramming which may be worth considering.
In my compiler, I need to implement a bunch of unary operators. I want an enumeration for them, but there's also other stuff I might want to do with the same list of operators.
How can I do this?
First, I'll put all of the data in one file, which I call unary_operators.inc:
1
2
3
4
5
6
7
8
9
10
11
12
13 | UNARY_OPERATOR(uo_post_inc, "++")
UNARY_OPERATOR(uo_post_dec, "--")
UNARY_OPERATOR(uo_pre_inc, "++")
UNARY_OPERATOR(uo_pre_dec, "--")
UNARY_OPERATOR(uo_ref, "&")
UNARY_OPERATOR(uo_deref, "*")
UNARY_OPERATOR(uo_plus, "+")
UNARY_OPERATOR(uo_minus, "-")
UNARY_OPERATOR(uo_b_not, "~")
UNARY_OPERATOR(uo_l_not, "!")
UNARY_OPERATOR_COUNT(uo_count)
#undef UNARY_OPERATOR
#undef UNARY_OPERATOR_COUNT
|
The reason for the undefs will become clear soon. Now, if I need the enumerated type, I can do this:
| enum unary_operator_t {
#define UNARY_OPERATOR(t,s) k_##t,
#define UNARY_OPERATOR_COUNT(t) k_##t
#include "unary_operators.inc"
};
|
Or perhaps I want to be able to resolve them as strings:
| const char*
sUnaryOperatorNames[] = {
#define UNARY_OPERATOR(t,s) s,
#define UNARY_OPERATOR_COUNT(t) #t
#include "unary_operators.inc"
};
|
Game engines often have custom metaobject protocols because neither C nor C++ have one that is in any way suitable. This is one way to do it which avoids the multiple-maintenance problem and also avoids the need for a separate tool.