#ifndef MAG_HANDLE_H #define MAG_HANDLE_H #ifdef __cplusplus #error "handle.h does not work with C++ compilers, you must compile these files with GCC directly!" #endif /** Tells your constructor/destructor handler function about the state */ enum HANDLE_STATE { HANDLE_CREAT, HANDLE_DESTR, }; /** * This creates a "handle". Basically a struct with given constructor and destructor + RAII. * * Usage: * * struct Meaning { * int a; * int b; * }; * // You can typedef if you want, change code accordingly! * * handle(struct Meaning) { * if(state == HANDLE_CREAT) { * this->a = *(int*) data; * this->b = 2 * } else { * printf("%d\n", this->a + this->b); * } * } * * // Now you can use a handle in your local scopes * // Should print 42: * int main() { * int initializer = 40; * creat(struct Data, d, &initializer); * } * * Rem.: Unrelated trick, but you can typedef struct A A; // both typedef and forward declare */ #define creat(TNAME, VNAME, VINIT) \ [[gnu::always_inline]] inline void F(TNAME *v) { \ TNAME##_lifetime_handler(HANDLE_DESTR, v, NULL); \ } \ [[gnu::cleanup(F)]] TNAME VNAME; \ TNAME##_lifetime_handler(HANDLE_CREAT, VNAME, VINIT); #define handle(TNAME) \ static void [[gnu::always_inline]] inline TNAME##_lifetime_handler( \ HANDLE_STATE state, \ TNAME *this, \ void *data) #endif // MAG_HANDLE_H