1 2 #define FE_0(WHAT, _) 3 #define FE_1(WHAT, X, _) WHAT(X,1) 4 #define FE_2(WHAT, X, ...) WHAT(X,2)FE_1(WHAT, __VA_ARGS__) 5 #define FE_3(WHAT, X, ...) WHAT(X,3)FE_2(WHAT, __VA_ARGS__) 6 #define FE_4(WHAT, X, ...) WHAT(X,4)FE_3(WHAT, __VA_ARGS__) 7 #define FE_5(WHAT, X, ...) WHAT(X,5)FE_4(WHAT, __VA_ARGS__) 8 #define FE_6(WHAT, X, ...) WHAT(X,6)FE_5(WHAT, __VA_ARGS__) 9 #define FE_7(WHAT, X, ...) WHAT(X,7)FE_6(WHAT, __VA_ARGS__) 10 #define FE_8(WHAT, X, ...) WHAT(X,8)FE_7(WHAT, __VA_ARGS__) 11 #define FE_9(WHAT, X, ...) WHAT(X,9)FE_8(WHAT, __VA_ARGS__) 12 13 #define GET_MACRO(_0_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,NAME,...) NAME 14 #define FOR_EACH(action,...) \ 15 GET_MACRO(__VA_ARGS__,FE_9,FE_8,FE_7,FE_6,FE_5,FE_4,FE_3,FE_2,FE_1,FE_0)(action,__VA_ARGS__) 16 #define ARG_AND_NAME(X, I) ,X _##I 17 #define NAME_ONLY(X, I) , _##I 18 #define ARG_ONLY(X, I) ,X 19 #define ARGS_AND_NAMES(...) FOR_EACH(ARG_AND_NAME,__VA_ARGS__) 20 #define NAMES_ONLY(...) FOR_EACH(NAME_ONLY,__VA_ARGS__) 21 #define ARGS_ONLY(...) FOR_EACH(ARG_ONLY,__VA_ARGS__) 22 23 #define HXT_FUNCTION_MEMBER_ASSIGN(derivedType,member, ...) \ 24 {\ 25 HXTStatus(*castcheck)(HXT##derivedType* ARGS_ONLY(__VA_ARGS__)) = hxt##derivedType##member;\ 26 c->member = (HXTStatus(*)(void* ARGS_ONLY(__VA_ARGS__)))castcheck;\ 27 } 28 29 #define HXT_FUNCTION_MEMBER_DECLARE(derivedType, member, ...) \ 30 HXTStatus(*member)(void* ARGS_ONLY(__VA_ARGS__)) 31 32 #define HXT_FUNCTION_MEMBER_IMPLEMENT(derivedType, member, ...) \ 33 HXTStatus hxt##derivedType##member(HXT##derivedType *c ARGS_AND_NAMES(__VA_ARGS__)) { \ 34 return c->c->member(c->data NAMES_ONLY(__VA_ARGS__)); \ 35 } 36 37 #define HXT_DECLARE_DERIVED_CLASS(baseType, derivedType) \ 38 static HXT##baseType##Class *hxt##derivedType##Class;\ 39 HXTStatus hxt##derivedType##Register() \ 40 { \ 41 HXT_CHECK(hxtMalloc(&hxt##derivedType##Class, sizeof(HXT##baseType##Class))); \ 42 HXT##baseType##Class *c = hxt##derivedType##Class; \ 43 HXT##baseType##_MEMBERS(HXT_FUNCTION_MEMBER_ASSIGN, derivedType) \ 44 HXTStatus(*castcheck)(HXT##derivedType**) = hxt##derivedType##Delete; \ 45 c->Delete = (HXTStatus(*)(void**))castcheck; \ 46 return HXT_STATUS_OK;\ 47 } \ 48 \ 49 HXTStatus hxt##baseType##Get##derivedType(HXT##baseType *b, HXT##derivedType **d) { \ 50 if (b->c == hxt##derivedType##Class) { \ 51 *d = b->data; \ 52 } \ 53 else { \ 54 *d = NULL; \ 55 } \ 56 return HXT_STATUS_OK; \ 57 } 58 59 #define HXT_DECLARE_INTERFACE(baseType) \ 60 typedef struct { \ 61 HXT##baseType##_MEMBERS(HXT_FUNCTION_MEMBER_DECLARE,) \ 62 HXTStatus (*Delete)(void **); \ 63 } HXT##baseType##Class; \ 64 struct HXT##baseType##Struct { \ 65 HXT##baseType##Class *c;\ 66 void *data; \ 67 }; \ 68 HXT##baseType##_MEMBERS(HXT_FUNCTION_MEMBER_IMPLEMENT,baseType) \ 69 HXTStatus hxt##baseType##Delete(HXT##baseType **pp) {\ 70 HXT_CHECK((*pp)->c->Delete(&(*pp)->data));\ 71 HXT_CHECK(hxtFree(pp));\ 72 return HXT_STATUS_OK;\ 73 } \ 74 HXTStatus hxt##baseType##Create(HXT##baseType **pp, HXT##baseType##Class *c, void *data) {\ 75 HXT_CHECK(hxtMalloc(pp, sizeof(HXT##baseType))); \ 76 (*pp)->c = c; \ 77 (*pp)->data = data; \ 78 return HXT_STATUS_OK;\ 79 } 80