c_mem_safety/handle.h

54 lines
1.3 KiB
C

#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
};
#define creat(TNAME, VNAME, VINIT) \
[[gnu::always_inline]] inline void VNAME##_cleanuper(struct TNAME *v) { \
TNAME##_lifetime_handler(HANDLE_DESTR, v, NULL); \
} \
[[gnu::cleanup(VNAME##_cleanuper)]] struct TNAME VNAME; \
TNAME##_lifetime_handler(HANDLE_CREAT, & VNAME, VINIT);
#define handle(TNAME) \
static inline void TNAME##_lifetime_handler( \
enum HANDLE_STATE state, \
struct TNAME *this, \
void *data)
/*
* EXAMPLE:
*
* struct Meaning {
* int a;
* int b;
* };
* // You should not typedef this EVER!
*
* handle(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(Meaning, d, &initializer);
* }
*
* Rem.: Unrelated trick, but you can typedef struct A A; // both typedef and forward declare
*/
#endif // MAG_HANDLE_H