-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathobject.h
155 lines (109 loc) · 3 KB
/
object.h
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
* object.h
* Copyright (C) 2018 Ilja Kartašov <ik@lowenware.com>
*
*/
#ifndef OBJECT_H_B477DE05_FC3C_42CD_A812_BBCCF314D4DD
#define OBJECT_H_B477DE05_FC3C_42CD_A812_BBCCF314D4DD
#define CSTUFF_GET_MACRO(_1, _2, NAME, ...) NAME
#define CSTUFF_STRINGIFYX( X ) #X
#define CSTUFF_STRINGIFY(X) CSTUFF_STRINGIFYX(X)
#include <stdint.h>
#include <stdbool.h>
#include <sys/types.h>
// common macroses
#define DECLARE_TYPES( CLASS_NAME ) \
extern struct CLASS_NAME##_class g_##CLASS_NAME##_class; \
typedef struct CLASS_NAME##_class * CLASS_NAME##_class_t; \
typedef struct CLASS_NAME * CLASS_NAME##_t; \
#define DECLARE_FROM( CLASS_NAME, PARENT_CLASS ) \
struct CLASS_NAME ## _class \
{ \
struct PARENT_CLASS##_class parent; \
}; \
DECLARE_TYPES( CLASS_NAME )
#define DECLARE_CLASS(...) \
CSTUFF_GET_MACRO( \
__VA_ARGS__, \
DECLARE_FROM, \
DECLARE_TYPES, \
PLACEHOLDER \
)(__VA_ARGS__)
#define DEFINE_CLASS_TOP(CLASS_NAME) \
static int \
CLASS_NAME ##_init(CLASS_NAME##_t); \
\
static void \
CLASS_NAME ##_free(CLASS_NAME##_t); \
\
struct CLASS_NAME##_class \
g_##CLASS_NAME##_class = CLASS_NAME##_class_init(CLASS_NAME); \
#define DEFINE_CLASS_FROM(CLASS_NAME, PARENT_CLASS) \
static int \
CLASS_NAME##_init(CLASS_NAME##_t); \
\
static void \
CLASS_NAME##_free(CLASS_NAME##_t); \
\
struct CLASS_NAME##_class g_##CLASS_NAME##_class = { \
.parent = PARENT_CLASS##_class_init(CLASS_NAME) \
}; \
#define DEFINE_CLASS(...) \
CSTUFF_GET_MACRO( \
__VA_ARGS__, \
DEFINE_CLASS_FROM, \
DEFINE_CLASS_TOP, \
PLACEHOLDER \
)(__VA_ARGS__)
// object macroses
#define cast( OBJECT, CLASS_NAME ) ((CLASS_NAME##_t)(OBJECT))
#define SUPER_OBJECT_CLASS( X, CLASS_NAME ) (\
(CLASS_NAME##_class_t) OBJECT(X)->object_class \
) \
#define SUPER_CLASS( CLASS_NAME ) ( (object_class_t) &g_##CLASS_NAME##_class )
#define super(...) \
CSTUFF_GET_MACRO( \
__VA_ARGS__, \
SUPER_OBJECT_CLASS, \
SUPER_CLASS, \
PLACEHOLDER \
)(__VA_ARGS__)
// ----------------------------------------------------------------------------
#define object_class_init(CLASS_NAME) \
{ \
.name = CSTUFF_STRINGIFY(CLASS_NAME), \
.init = (object_init_t) CLASS_NAME##_init, \
.free = (object_free_t) CLASS_NAME##_free \
} \
#define OBJECT( X ) cast( X, object )
DECLARE_CLASS(object)
typedef int
(*object_init_t)(object_t self);
typedef void
(*object_free_t)(object_t self);
// begin class declaration
struct object_class
{
const char * name;
object_init_t init;
object_free_t free;
};
// end class declaration
struct object
{
/* public */
object_class_t object_class;
/* private */
uint32_t _links;
};
#define object_new( CLASS_NAME ) \
(CLASS_NAME##_t) object_allocate( \
(object_class_t) &g_##CLASS_NAME##_class, sizeof(struct CLASS_NAME) \
) \
object_t
object_allocate(object_class_t object_class, size_t size);
void *
object_link(object_t self);
void
object_unlink(object_t self);
#endif /* !OBJECT_H */