, Boost, .
, .
-, . :
ReflEnum(MyEnum,
(first)
(second , 42)
(third)
)
:
enum MyEnum
{
first,
second = 42,
third,
};
const char *EnumToString_MyEnum(enum MyEnum param)
{
switch (param)
{
case first:
return "first";
case second:
return "second";
case third:
return "third";
default:
return "<invalid>";
}
}
, :
#include <stdio.h>
ReflEnum(MyEnum,
(first)
(second , 42)
(third)
)
int main()
{
enum MyEnum foo = second;
puts(EnumToString_MyEnum(foo));
puts(EnumToString_MyEnum(43));
puts(EnumToString_MyEnum(9001));
}
.
. , Boost.
:
#define ReflEnum_impl_Item(...) PPUTILS_VA_CALL(ReflEnum_impl_Item_, __VA_ARGS__)(__VA_ARGS__)
#define ReflEnum_impl_Item_1(name) name,
#define ReflEnum_impl_Item_2(name, value) name = value,
#define ReflEnum_impl_Case(...) case PPUTILS_VA_FIRST(__VA_ARGS__): return PPUTILS_STR(PPUTILS_VA_FIRST(__VA_ARGS__));
#define ReflEnum(name, seq) \
enum name {PPUTILS_SEQ_APPLY(seq, ReflEnum_impl_Item)}; \
const char *EnumToString_##name(enum name param) \
{ \
switch (param) \
{ \
PPUTILS_SEQ_APPLY(seq, ReflEnum_impl_Case) \
default: return "<invalid>"; \
} \
}
string- > enum; , .
:
, script, . .
Boost 64, 4.
#define PPUTILS_E(...) __VA_ARGS__
#define PPUTILS_VA_FIRST(...) PPUTILS_VA_FIRST_IMPL_(__VA_ARGS__,)
#define PPUTILS_VA_FIRST_IMPL_(x, ...) x
#define PPUTILS_PARENS(...) (__VA_ARGS__)
#define PPUTILS_DEL_PARENS(...) PPUTILS_E __VA_ARGS__
#define PPUTILS_CC(a, b) PPUTILS_CC_IMPL_(a,b)
#define PPUTILS_CC_IMPL_(a, b) a##b
#define PPUTILS_CALL(macro, ...) macro(__VA_ARGS__)
#define PPUTILS_VA_SIZE(...) PPUTILS_VA_SIZE_IMPL_(__VA_ARGS__,4,3,2,1,0)
#define PPUTILS_VA_SIZE_IMPL_(i1,i2,i3,i4,size,...) size
#define PPUTILS_STR(...) PPUTILS_STR_IMPL_(__VA_ARGS__)
#define PPUTILS_STR_IMPL_(...) #__VA_ARGS__
#define PPUTILS_VA_CALL(name, ...) PPUTILS_CC(name, PPUTILS_VA_SIZE(__VA_ARGS__))
#define PPUTILS_SEQ_CALL(name, seq) PPUTILS_CC(name, PPUTILS_SEQ_SIZE(seq))
#define PPUTILS_SEQ_DEL_FIRST(seq) PPUTILS_SEQ_DEL_FIRST_IMPL_ seq
#define PPUTILS_SEQ_DEL_FIRST_IMPL_(...)
#define PPUTILS_SEQ_FIRST(seq) PPUTILS_DEL_PARENS(PPUTILS_VA_FIRST(PPUTILS_SEQ_FIRST_IMPL_ seq,))
#define PPUTILS_SEQ_FIRST_IMPL_(...) (__VA_ARGS__),
#define PPUTILS_SEQ_SIZE(seq) PPUTILS_CC(PPUTILS_SEQ_SIZE_0 seq, _VAL)
#define PPUTILS_SEQ_SIZE_0(...) PPUTILS_SEQ_SIZE_1
#define PPUTILS_SEQ_SIZE_1(...) PPUTILS_SEQ_SIZE_2
#define PPUTILS_SEQ_SIZE_2(...) PPUTILS_SEQ_SIZE_3
#define PPUTILS_SEQ_SIZE_3(...) PPUTILS_SEQ_SIZE_4
#define PPUTILS_SEQ_SIZE_4(...) PPUTILS_SEQ_SIZE_5
#define PPUTILS_SEQ_SIZE_0_VAL 0
#define PPUTILS_SEQ_SIZE_1_VAL 1
#define PPUTILS_SEQ_SIZE_2_VAL 2
#define PPUTILS_SEQ_SIZE_3_VAL 3
#define PPUTILS_SEQ_SIZE_4_VAL 4
#define PPUTILS_SEQ_APPLY(seq, macro) PPUTILS_SEQ_CALL(PPUTILS_SEQ_APPLY_, seq)(macro, seq)
#define PPUTILS_SEQ_APPLY_0(macro, seq)
#define PPUTILS_SEQ_APPLY_1(macro, seq) PPUTILS_CALL(macro, PPUTILS_SEQ_FIRST(seq))
#define PPUTILS_SEQ_APPLY_2(macro, seq) PPUTILS_CALL(macro, PPUTILS_SEQ_FIRST(seq)) PPUTILS_SEQ_CALL(PPUTILS_SEQ_APPLY_, PPUTILS_SEQ_DEL_FIRST(seq))(macro, PPUTILS_SEQ_DEL_FIRST(seq))
#define PPUTILS_SEQ_APPLY_3(macro, seq) PPUTILS_CALL(macro, PPUTILS_SEQ_FIRST(seq)) PPUTILS_SEQ_CALL(PPUTILS_SEQ_APPLY_, PPUTILS_SEQ_DEL_FIRST(seq))(macro, PPUTILS_SEQ_DEL_FIRST(seq))
#define PPUTILS_SEQ_APPLY_4(macro, seq) PPUTILS_CALL(macro, PPUTILS_SEQ_FIRST(seq)) PPUTILS_SEQ_CALL(PPUTILS_SEQ_APPLY_, PPUTILS_SEQ_DEL_FIRST(seq))(macro, PPUTILS_SEQ_DEL_FIRST(seq))