使用下面的宏,您可以做到这一点。
enum { ENUM_FLAGS(A, B, C) };
虽然宏相当冗长,但调用它却不是,这可能是在构建时生成标头的合理替代方案。
适用于现代编译器 - GCC/Clang/MSVC/IntelC++。
/** generated with:
* \code{.py}
* enum_flag_bits = 32
* for i in range(enum_flag_bits):
* args = [(chr(ord('a') + (c % 26)) + (chr(ord('0') + (c // 26)))) for c in range(i + 1)]
* print("#define _VA_ENUM_FLAGS_%d(%s) \\\n " % (i + 1, ", ".join(args)), end="")
* if i != 0:
* print("_VA_ENUM_FLAGS_%d(%s) " % (i, ", ".join(args[:-1])), end="")
* print("%s = %s," % (args[-1], "(1u << %d)" % i))
* \endcode
*/
#define _VA_ENUM_FLAGS_1(a0) \
a0 = (1u << 0),
#define _VA_ENUM_FLAGS_2(a0, b0) \
_VA_ENUM_FLAGS_1(a0) b0 = (1u << 1),
#define _VA_ENUM_FLAGS_3(a0, b0, c0) \
_VA_ENUM_FLAGS_2(a0, b0) c0 = (1u << 2),
#define _VA_ENUM_FLAGS_4(a0, b0, c0, d0) \
_VA_ENUM_FLAGS_3(a0, b0, c0) d0 = (1u << 3),
#define _VA_ENUM_FLAGS_5(a0, b0, c0, d0, e0) \
_VA_ENUM_FLAGS_4(a0, b0, c0, d0) e0 = (1u << 4),
#define _VA_ENUM_FLAGS_6(a0, b0, c0, d0, e0, f0) \
_VA_ENUM_FLAGS_5(a0, b0, c0, d0, e0) f0 = (1u << 5),
#define _VA_ENUM_FLAGS_7(a0, b0, c0, d0, e0, f0, g0) \
_VA_ENUM_FLAGS_6(a0, b0, c0, d0, e0, f0) g0 = (1u << 6),
#define _VA_ENUM_FLAGS_8(a0, b0, c0, d0, e0, f0, g0, h0) \
_VA_ENUM_FLAGS_7(a0, b0, c0, d0, e0, f0, g0) h0 = (1u << 7),
#define _VA_ENUM_FLAGS_9(a0, b0, c0, d0, e0, f0, g0, h0, i0) \
_VA_ENUM_FLAGS_8(a0, b0, c0, d0, e0, f0, g0, h0) i0 = (1u << 8),
#define _VA_ENUM_FLAGS_10(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0) \
_VA_ENUM_FLAGS_9(a0, b0, c0, d0, e0, f0, g0, h0, i0) j0 = (1u << 9),
#define _VA_ENUM_FLAGS_11(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0) \
_VA_ENUM_FLAGS_10(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0) k0 = (1u << 10),
#define _VA_ENUM_FLAGS_12(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0) \
_VA_ENUM_FLAGS_11(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0) l0 = (1u << 11),
#define _VA_ENUM_FLAGS_13(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0) \
_VA_ENUM_FLAGS_12(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0) m0 = (1u << 12),
#define _VA_ENUM_FLAGS_14(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0) \
_VA_ENUM_FLAGS_13(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0) n0 = (1u << 13),
#define _VA_ENUM_FLAGS_15(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0) \
_VA_ENUM_FLAGS_14(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0) o0 = (1u << 14),
#define _VA_ENUM_FLAGS_16(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0) \
_VA_ENUM_FLAGS_15(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0) p0 = (1u << 15),
#define _VA_ENUM_FLAGS_17(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0) \
_VA_ENUM_FLAGS_16(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0) q0 = (1u << 16),
#define _VA_ENUM_FLAGS_18(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0) \
_VA_ENUM_FLAGS_17(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0) r0 = (1u << 17),
#define _VA_ENUM_FLAGS_19(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0) \
_VA_ENUM_FLAGS_18(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0) s0 = (1u << 18),
#define _VA_ENUM_FLAGS_20(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0) \
_VA_ENUM_FLAGS_19(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0) t0 = (1u << 19),
#define _VA_ENUM_FLAGS_21(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0) \
_VA_ENUM_FLAGS_20(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0) u0 = (1u << 20),
#define _VA_ENUM_FLAGS_22(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0) \
_VA_ENUM_FLAGS_21(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0) v0 = (1u << 21),
#define _VA_ENUM_FLAGS_23(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0) \
_VA_ENUM_FLAGS_22(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0) w0 = (1u << 22),
#define _VA_ENUM_FLAGS_24(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0) \
_VA_ENUM_FLAGS_23(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0) x0 = (1u << 23),
#define _VA_ENUM_FLAGS_25(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0) \
_VA_ENUM_FLAGS_24(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0) y0 = (1u << 24),
#define _VA_ENUM_FLAGS_26(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0) \
_VA_ENUM_FLAGS_25(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0) z0 = (1u << 25),
#define _VA_ENUM_FLAGS_27(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0, a1) \
_VA_ENUM_FLAGS_26(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0) a1 = (1u << 26),
#define _VA_ENUM_FLAGS_28(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0, a1, b1) \
_VA_ENUM_FLAGS_27(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0, a1) b1 = (1u << 27),
#define _VA_ENUM_FLAGS_29(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0, a1, b1, c1) \
_VA_ENUM_FLAGS_28(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0, a1, b1) c1 = (1u << 28),
#define _VA_ENUM_FLAGS_30(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0, a1, b1, c1, d1) \
_VA_ENUM_FLAGS_29(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0, a1, b1, c1) d1 = (1u << 29),
#define _VA_ENUM_FLAGS_31(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0, a1, b1, c1, d1, e1) \
_VA_ENUM_FLAGS_30(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0, a1, b1, c1, d1) e1 = (1u << 30),
#define _VA_ENUM_FLAGS_32(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1) \
_VA_ENUM_FLAGS_31(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, v0, w0, x0, y0, z0, a1, b1, c1, d1, e1) f1 = (1u << 31),
/* reusable ENUM_FLAGS macro */
#define ENUM_FLAGS(...) VA_NARGS_CALL_OVERLOAD(_VA_ENUM_FLAGS_, __VA_ARGS__)
使用这里VA_NARGS_CALL_OVERLOAD
定义的:
/* varargs macros (keep first so others can use) */
/* --- internal helpers --- */
#define _VA_NARGS_GLUE(x, y) x y
#define _VA_NARGS_RETURN_COUNT(\
_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, _10_, _11_, _12_, _13_, _14_, _15_, _16_, \
_17_, _18_, _19_, _20_, _21_, _22_, _23_, _24_, _25_, _26_, _27_, _28_, _29_, _30_, _31_, _32_, \
_33_, _34_, _35_, _36_, _37_, _38_, _39_, _40_, _41_, _42_, _43_, _44_, _45_, _46_, _47_, _48_, \
_49_, _50_, _51_, _52_, _53_, _54_, _55_, _56_, _57_, _58_, _59_, _60_, _61_, _62_, _63_, _64_, \
count, ...) count
#define _VA_NARGS_EXPAND(args) _VA_NARGS_RETURN_COUNT args
/* 64 args max */
#define _VA_NARGS_COUNT(...) _VA_NARGS_EXPAND((__VA_ARGS__, \
64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, \
48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, \
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \
16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
#define _VA_NARGS_OVERLOAD_MACRO2(name, count) name##count
#define _VA_NARGS_OVERLOAD_MACRO1(name, count) _VA_NARGS_OVERLOAD_MACRO2(name, count)
#define _VA_NARGS_OVERLOAD_MACRO(name, count) _VA_NARGS_OVERLOAD_MACRO1(name, count)
/* --- expose for re-use --- */
#define VA_NARGS_CALL_OVERLOAD(name, ...) \
_VA_NARGS_GLUE(_VA_NARGS_OVERLOAD_MACRO(name, _VA_NARGS_COUNT(__VA_ARGS__)), (__VA_ARGS__))