fork download
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. /*** Object types */
  6.  
  7. typedef struct s_obj s_obj;
  8. typedef struct s_string s_string;
  9. typedef struct s_integer s_integer;
  10.  
  11. /*** Function types */
  12.  
  13. typedef void f_any();
  14. typedef f_any * f_interface(s_obj *, f_any *);
  15.  
  16. typedef char * f_tostring(s_obj *);
  17.  
  18. /*** Function declarations */
  19.  
  20. f_tostring tostring;
  21.  
  22. void init_string(s_string *);
  23. f_interface string_interface;
  24. f_tostring string_tostring;
  25.  
  26. void init_integer(s_integer *);
  27. f_tostring integer_tostring;
  28. f_interface integer_interface;
  29.  
  30. /*** Struct/union definitions */
  31.  
  32. struct s_obj {
  33. f_interface * get_interface;
  34. };
  35.  
  36. struct s_string {
  37. s_obj obj[1];
  38. char * text;
  39. };
  40.  
  41. struct s_integer {
  42. s_obj obj[1];
  43. int i;
  44. };
  45.  
  46. /*** Function definitions */
  47.  
  48. int main(void) {
  49. char * tmp;
  50. s_string my_string;
  51. s_integer my_integer;
  52.  
  53. init_string(&my_string);
  54. my_string.text = "My string!";
  55. tmp = tostring(my_string.obj);
  56. puts(tmp);
  57. free(tmp);
  58.  
  59. init_integer(&my_integer);
  60. my_integer.i = 42;
  61. tmp = tostring(my_integer.obj);
  62. puts(tmp);
  63. free(tmp);
  64.  
  65. return EXIT_SUCCESS;
  66. }
  67.  
  68. /* You must 'free' the storage allocated by 'tostring'! */
  69. char * tostring(s_obj * obj) {
  70. f_tostring * func;
  71.  
  72. func = (f_tostring *) obj->get_interface(obj, (f_any *) tostring);
  73. return func(obj);
  74. }
  75.  
  76. void init_string(s_string * string) {
  77. string->obj->get_interface = string_interface;
  78. string->text = NULL;
  79. return;
  80. }
  81.  
  82. f_any * string_interface(s_obj * obj, f_any * func) {
  83. /* Unused */
  84. (void) obj;
  85.  
  86. if (0);
  87. /* 'tostring' case */
  88. else if (func == (f_any *) tostring)
  89. return (f_any *) string_tostring;
  90. /* ...Other cases... */
  91. /* Unsupported interface */
  92. exit(EXIT_FAILURE);
  93. }
  94.  
  95. char * string_tostring(s_obj * obj) {
  96. s_string * this = (void *) obj;
  97. char * new;
  98. int len;
  99.  
  100. len = strlen(this->text) + 1;
  101. new = malloc(len);
  102. if (!new)
  103. return new;
  104.  
  105. memcpy(new, this->text, len);
  106. return new;
  107. }
  108.  
  109. void init_integer(s_integer * integer) {
  110. integer->obj->get_interface = integer_interface;
  111. integer->i = 0;
  112. return;
  113. }
  114.  
  115. f_any * integer_interface(s_obj * obj, f_any * func) {
  116. /* Unused */
  117. (void) obj;
  118.  
  119. if (0);
  120. /* 'tostring' case */
  121. else if (func == (f_any *) tostring)
  122. return (f_any *) integer_tostring;
  123. /* ...Other cases... */
  124. /* Unsupported interface */
  125. exit(EXIT_FAILURE);
  126. }
  127.  
  128. char * integer_tostring(s_obj * obj) {
  129. s_integer * this = (void *) obj;
  130. char tmp[50];
  131. char * new;
  132. int len;
  133.  
  134. sprintf(tmp, "%d", this->i);
  135. len = strlen(tmp) + 1;
  136. new = malloc(len);
  137. if (!new)
  138. return new;
  139.  
  140. memcpy(new, tmp, len);
  141. return new;
  142. }
  143.  
Success #stdin #stdout 0.02s 1852KB
stdin
Standard input is empty
stdout
My string!
42