Created
November 16, 2019 21:45
-
-
Save christophercrouzet/db9bbb07d427381253a91210e7ddc68d to your computer and use it in GitHub Desktop.
Designated Initializer Macro for C99 and C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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