Advertisement
tyler569

C "classes" with vtable

Sep 1st, 2018
393
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.86 KB | None | 0 0
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. struct class_typeinfo {
  6.     char *name;
  7. };
  8. typedef struct class_typeinfo class_typeinfo;
  9.  
  10. #define METHODS(methods...) methods
  11. #define MEMBERS(members...) members
  12.  
  13. #define CLASS_VTBL(name) _##name##_vtable_
  14. #define CLASS_MTHD(name, method) _##name##_##method##_
  15.  
  16. #define CLASS_DECL(name, methods, members)  \
  17. typedef struct name name;                   \
  18. struct CLASS_VTBL(name) {                   \
  19.     void (*init)(name *);                   \
  20.     void (*destroy)(name *);                \
  21.     class_typeinfo typeinfo;                \
  22.     methods                                 \
  23. };                                          \
  24. struct CLASS_VTBL(name) CLASS_VTBL(name);   \
  25. struct name {                               \
  26.     struct CLASS_VTBL(name) vtable;         \
  27.     members                                 \
  28. };
  29.  
  30. #define ARGS(args...) args
  31. #define IMPLEMENT(class, method, return_t, args, body...) \
  32. return_t CLASS_MTHD(class, method)(args) {  \
  33.     body                                    \
  34. }
  35.  
  36. #define CTOR(class, body...)                \
  37. void _##class##_init##_(class *self) {      \
  38.     body                                    \
  39. }
  40. #define DTOR(class, body...)                \
  41. void _##class##_destroy##_(class *self) {   \
  42.     body                                    \
  43. }
  44.  
  45. #define NEW(class)                          \
  46. class *tmpname = malloc(sizeof(class));     \
  47. tmpname->vtable = CLASS_VTBL(class);        \
  48. tmpname->vtable.init(tmpname);
  49.  
  50. #define METHODCALL(object, method, args...) \
  51.     object->vtable.method(object, ## args)
  52.  
  53.  
  54. CLASS_DECL(foo,
  55. METHODS(
  56.     int (*inc)(foo *self);
  57.     int (*dec)(foo *self);
  58.     void (*set)(foo *self, int new_value);
  59.     int (*get)(foo *self);
  60. ),
  61. MEMBERS(
  62.     int local;
  63. )
  64. );
  65.  
  66. CTOR(foo,
  67.     self->local = 0;
  68. );
  69.  
  70. DTOR(foo, {});
  71.  
  72. IMPLEMENT(foo, inc, int, ARGS(foo *self),
  73.     self->local += 1;
  74.     return self->local;
  75. );
  76. IMPLEMENT(foo, dec, int, ARGS(foo *self),
  77.     self->local -= 1;
  78.     return self->local;
  79. );
  80. IMPLEMENT(foo, set, void, ARGS(foo *self, int new_value),
  81.     self->local = new_value;
  82. );
  83. IMPLEMENT(foo, get, int, ARGS(foo *self),
  84.     return self->local;
  85. );
  86.  
  87. int main() {
  88.  
  89.     // until I figure out how to actually put these in the struct AOT.
  90.     CLASS_VTBL(foo).init = _foo_init_;
  91.     CLASS_VTBL(foo).destroy = _foo_destroy_;
  92.     CLASS_VTBL(foo).inc = _foo_inc_;
  93.     CLASS_VTBL(foo).dec = _foo_dec_;
  94.     CLASS_VTBL(foo).set = _foo_set_;
  95.     CLASS_VTBL(foo).get = _foo_get_;
  96.  
  97.     NEW(foo);
  98.     foo *obj = tmpname;
  99.  
  100.     printf("obj->local starts at %i\n", obj->local);
  101.  
  102.     METHODCALL(obj, inc);
  103.     METHODCALL(obj, inc);
  104.     METHODCALL(obj, dec);
  105.  
  106.     printf("obj->inc() returns %i\n", METHODCALL(obj, inc));
  107.  
  108.     METHODCALL(obj, set, 10);
  109.  
  110.     printf("obj->get() after setting to 10 is %i\n", METHODCALL(obj, get));
  111. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement