Chris_M_Thomasson

Experimental Crude VTable Attempt, pre-alpha... ;^)

Jul 25th, 2017
281
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.06 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5.  
  6. /* Object Interface
  7. __________________________________________________*/
  8. typedef void(*ct_object_fp_destroy) (void*);
  9. typedef void(*ct_object_fp_print) (void*, FILE*);
  10.  
  11. struct ct_object_vtable
  12. {
  13.     ct_object_fp_destroy fp_destroy;
  14.     ct_object_fp_print fp_print;
  15. };
  16.  
  17. #define ct_object_vtable(mp_self) \
  18.     ((((struct ct_object_vtable*)(*((void**)(mp_self)))))
  19.  
  20. #define ct_object_print(mp_self, mp_file) \
  21.     (ct_object_vtable(mp_self)->fp_print((mp_self), (mp_file))))
  22.  
  23. #define ct_object_destroy(mp_self) \
  24.     (ct_object_vtable(mp_self)->fp_destroy((mp_self))))
  25.  
  26.  
  27. /* Person Interface
  28. __________________________________________________*/
  29. struct ct_person_vtable
  30. {
  31.     struct ct_object_vtable m_object;
  32. };
  33.  
  34. static void ct_person_print(void* raw_self, FILE* file);
  35. static void ct_person_destroy(void* raw_self);
  36.  
  37. static struct ct_person_vtable const g_ct_person_vtable = {
  38.     {
  39.         ct_person_destroy,
  40.         ct_person_print
  41.     }
  42. };
  43.  
  44.  
  45. /* Person Impl
  46. __________________________________________________*/
  47. struct ct_person
  48. {
  49.     struct ct_person_vtable const* m_vtable;
  50.     char* name;
  51. };
  52.  
  53. static int
  54. ct_person_create(
  55.     struct ct_person* const self,
  56.     char const* name
  57. ) {
  58.     size_t name_size = strlen(name) + 1;
  59.  
  60.     self->name = calloc(1, name_size);
  61.  
  62.     if (self->name)
  63.     {
  64.         strcpy(self->name, name);
  65.  
  66.         // setup vtable
  67.         self->m_vtable = &g_ct_person_vtable;
  68.  
  69.         printf("(%p:ct_person_create):(name:%s)\n",
  70.             (void*)self, self->name);
  71.  
  72.         return 0;
  73.     }
  74.  
  75.     return -1;
  76. }
  77.  
  78. static void
  79. ct_person_print(
  80.     void* raw_self,
  81.     FILE* file
  82. ) {
  83.     struct ct_person* const self = raw_self;
  84.  
  85.     fprintf(file, "(%p:ct_person_print):(name:%s)\n",
  86.         (void*)self, self->name);
  87. }
  88.  
  89. static void
  90. ct_person_destroy(
  91.     void* raw_self
  92. ) {
  93.     struct ct_person* const self = raw_self;
  94.  
  95.     printf("(%p:ct_person_destroy):(name:%s)\n",
  96.         (void*)self, self->name);
  97.  
  98.     free(self->name);
  99. }
  100.  
  101.  
  102.  
  103. /* Employee Interface
  104. __________________________________________________*/
  105. static void ct_employee_print(void* raw_self, FILE* file);
  106. static void ct_employee_destroy(void* raw_self);
  107.  
  108. static struct ct_person_vtable const g_ct_employee_vtable = {
  109.     {
  110.         ct_employee_destroy,
  111.         ct_employee_print
  112.     }
  113. };
  114.  
  115.  
  116. /* Employee Impl
  117. __________________________________________________*/
  118. struct ct_employee
  119. {
  120.     struct ct_person m_person;
  121.     int id;
  122. };
  123.  
  124. static int
  125. ct_employee_create(
  126.     struct ct_employee* const self,
  127.     char const* name,
  128.     int id
  129. ) {
  130.     int status = ct_person_create(&self->m_person, name);
  131.  
  132.     if (!status)
  133.     {
  134.         // setup vtable
  135.         self->m_person.m_vtable = &g_ct_employee_vtable;
  136.  
  137.         self->id = id;
  138.  
  139.         return 0;
  140.     }
  141.  
  142.     return status;
  143. }
  144.  
  145. static void
  146. ct_employee_print(
  147.     void* raw_self,
  148.     FILE* file
  149. ) {
  150.     struct ct_employee* const self = raw_self;
  151.  
  152.     fprintf(file, "(%p:ct_employee_print):(id:%d)\n",
  153.         (void*)self, self->id);
  154.  
  155.     // explicit chain
  156.     ct_person_print(&self->m_person, file);
  157. }
  158.  
  159. static void
  160. ct_employee_destroy(
  161.     void* raw_self
  162. ) {
  163.     struct ct_employee* const self = raw_self;
  164.  
  165.     printf("(%p:ct_employee_destroy):(id:%d)\n",
  166.         (void*)self, self->id);
  167.  
  168.     // explicit chain
  169.     ct_person_destroy(&self->m_person);
  170. }
  171.  
  172.  
  173. /* Testing 123...
  174. __________________________________________________*/
  175. int main(void)
  176. {
  177.     struct ct_employee employee;
  178.  
  179.     if (!ct_employee_create(&employee, "Chris M. Thomasson", 103))
  180.     {
  181.         struct ct_person* const person = &employee.m_person;
  182.  
  183.         ct_object_print(&employee, stdout);
  184.         ct_object_destroy(person);
  185.     }
  186.  
  187.     printf("\n_______________________________________\n");
  188.  
  189.     if (!ct_employee_create(&employee, "Jane Doe", 1203))
  190.     {
  191.         struct ct_person* const person = &employee.m_person;
  192.  
  193.         ct_object_print(person, stdout);
  194.         ct_object_destroy(person);
  195.     }
  196.  
  197.     return 0;
  198. }
Advertisement
Add Comment
Please, Sign In to add comment