#ifndef OO_H #define OO_H #define NAMEOF_(X) #X #define NAMEOF(X) NAMEOF_(X) #define __CONCAT(x, y) x ## y #define CONCAT2(x, y) __CONCAT(x, y) #define CONCAT3(x, y, z) CONCAT2(CONCAT2(x, y), z) #define CONCAT4(x, y, z, w) CONCAT2(CONCAT2(x, y), CONCAT2(z, w)) #define CATCH_SELF_NULL(MNAME) CATCH_SELF_NULL_(MNAME) #define CATCH_SELF_NULL_(MNAME) do { \ if (NULL == self) { \ fprintf(stderr, "[FATAL] " #MNAME " -- self is null\n"); \ exit(139); \ } \ } while (0); // end of utils #define SIZEOF_OBJ(T) sizeof(DEFINE_OBJECT_STRUCTURE(T)) #define DEFINE_OBJECT_STRUCTURE(N) struct CONCAT3(__oo_, N, _struct) #define DEFINE_OBJECT_PTR(N) typedef DEFINE_OBJECT_STRUCTURE(N) * N #define DEFINE_OBJECT(N) DEFINE_OBJECT_STRUCTURE(N); DEFINE_OBJECT_PTR(N); #define CONSTRUCTOR(T) T CONCAT2(T, _alloc)() #define CONSTRUCTOR_IMPLEMENT(T) CONSTRUCTOR(T) { \ T ptr = (T)malloc(SIZEOF_OBJ(T)); \ if (NULL == ptr) { \ perror("Could not allocate new '" NAMEOF(T) "' instance"); \ exit(1); \ } \ return ptr; \ } #define METHOD(T, N, ...) CONCAT3(T, _, N) (T self __VA_OPT__(,) __VA_ARGS__) #define GETTER(T, MT, M) MT CONCAT4(T, _, M, _get) (T self) #define SETTER(T, MT, M) void CONCAT4(T, _, M, _set) (T self, MT v) #define GETTER_IMPLEMENT(T, MT, M) GETTER(T, MT, M) { \ CATCH_SELF_NULL(CONCAT4(T, _, M, _get)); \ return self-> M; \ } #define SETTER_IMPLEMENT(T, MT, M) SETTER(T, MT, M) { \ CATCH_SELF_NULL(CONCAT4(T, _, M, _set)); \ self-> M = v; \ } #endif