Skip to content

Instantly share code, notes, and snippets.

@christophercrouzet
Created November 16, 2019 21:45
Show Gist options
  • Save christophercrouzet/db9bbb07d427381253a91210e7ddc68d to your computer and use it in GitHub Desktop.
Save christophercrouzet/db9bbb07d427381253a91210e7ddc68d to your computer and use it in GitHub Desktop.
Designated Initializer Macro for C99 and C++
#include <stdio.h>
/* -------------------------------------------------------------------------- */
#define EXPAND(x) x
#define CONCAT_(a, b) a##b
#define CONCAT(a, b) CONCAT_(a, b)
#define ARG( \
_0, _1, _2, _3, _4, _5, _6, _7, \
_8, _9, _10, _11, _12, _13, _14, _15, \
_16, ...) _16
#define COUNT_ARGS(...) \
EXPAND(ARG( \
__VA_ARGS__, \
16, 15, 14, 13, 12, 11, 10, 9, \
8, 7, 6, 5, 4, 3, 2, 1, \
0,))
#define APPLY_1(x, first) x(first)
#define APPLY_2(x, first, ...) x(first) APPLY_1(x, __VA_ARGS__)
#define APPLY_3(x, first, ...) x(first) APPLY_2(x, __VA_ARGS__)
#define APPLY_4(x, first, ...) x(first) APPLY_3(x, __VA_ARGS__)
#define APPLY_5(x, first, ...) x(first) APPLY_4(x, __VA_ARGS__)
#define APPLY_6(x, first, ...) x(first) APPLY_5(x, __VA_ARGS__)
#define APPLY_7(x, first, ...) x(first) APPLY_6(x, __VA_ARGS__)
#define APPLY_8(x, first, ...) x(first) APPLY_7(x, __VA_ARGS__)
#define APPLY_9(x, first, ...) x(first) APPLY_8(x, __VA_ARGS__)
#define APPLY_10(x, first, ...) x(first) APPLY_9(x, __VA_ARGS__)
#define APPLY_11(x, first, ...) x(first) APPLY_10(x, __VA_ARGS__)
#define APPLY_12(x, first, ...) x(first) APPLY_11(x, __VA_ARGS__)
#define APPLY_13(x, first, ...) x(first) APPLY_12(x, __VA_ARGS__)
#define APPLY_14(x, first, ...) x(first) APPLY_13(x, __VA_ARGS__)
#define APPLY_15(x, first, ...) x(first) APPLY_14(x, __VA_ARGS__)
#define APPLY_16(x, first, ...) x(first) APPLY_15(x, __VA_ARGS__)
#define APPLY(x, ...) \
EXPAND( \
CONCAT(APPLY_, COUNT_ARGS(__VA_ARGS__))(x, __VA_ARGS__))
#ifdef __cplusplus
#define STRUCT_MEMBER_ASSIGN(x) out x;
#define STRUCT_INITIALIZE_STATIC(id, type, ...) \
static const type id##_initialize() \
{ \
type out = {}; \
APPLY(STRUCT_MEMBER_ASSIGN, __VA_ARGS__); \
return out; \
} \
static const type id = id##_initialize()
#else
#define STRUCT_MEMBER_ASSIGN(x) x,
#define STRUCT_INITIALIZE_STATIC(id, type, ...) \
static const type id = { APPLY(STRUCT_MEMBER_ASSIGN, __VA_ARGS__) }
#endif
/* -------------------------------------------------------------------------- */
struct my_struct {
int foo;
int bar;
};
STRUCT_INITIALIZE_STATIC(my_data, struct my_struct, .foo=123, .bar=456);
/* -------------------------------------------------------------------------- */
int
main()
{
printf("foo: %d, bar: %d\n", my_data.foo, my_data.bar);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment