summaryrefslogtreecommitdiff
path: root/includes/oo.h
blob: b75812f6699e29a3fe47f7adc82c2233bda5b838 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#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)
#define METHOD_ARG(T, N, ...) CONCAT3(T, _, N) (T self, __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