💾 Archived View for gmi.noulin.net › gitRepositories › objects › file › main.c.gmi captured on 2023-07-10 at 18:02:30. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
main.c (3641B)
1 #include <stdlib.h> 2 #include <stdio.h> 3 #include <string.h> 4 5 // Generics 6 #define freeO(obj) obj.f->free(&obj) 7 #define freeOPointer(obj) obj->f->free(obj) 8 #define deleteO(obj) obj->f->terminate(&obj) 9 #define isOType(obj, className) ((baset *) obj)->type == className 10 11 // Class: base 12 typedef struct base baset; 13 14 typedef void (*basePrintt)(baset *self, char *string); 15 16 typedef struct { 17 basePrintt print; 18 } baseFunctionst; 19 20 struct base { 21 const char *type; 22 baseFunctionst *f; 23 }; 24 25 // END base 26 27 // Class: class 28 typedef struct class classt; 29 30 // for object inheriting class, cast to classt to be able to use this class functions and generics 31 #define cClass(self) ( (classt*) self ) 32 33 static const char classtName[] = "class"; 34 35 typedef void (*classPrintt)(classt *self, char *string); 36 typedef void (*freeClasstt)(classt *self); 37 typedef void (*terminateClasstt)(classt **self); 38 typedef classt* (*duplicateClasstt)(classt **self); 39 40 /* use this define in child classes and add the new function after this class functions */ 41 #define CLASSFUNCTIONST \ 42 terminateClasstt terminate;\ 43 duplicateClasstt duplicate;\ 44 freeClasstt free 45 46 typedef struct { 47 // base class 48 classPrintt print; 49 // base class end 50 CLASSFUNCTIONST; 51 } classFunctionst; 52 53 static classFunctionst *classF = NULL; 54 55 struct class { 56 // base class 57 const char *type; 58 classFunctionst *f; 59 // base class end 60 61 int a; 62 char *s; 63 }; 64 65 // Initiate/Terminate Objects 66 #define createclasst(obj) classt obj; initiateclasst(&obj) 67 #define createAllocateclasst(obj) classt *obj; initiateAllocateclasst(&obj) 68 69 // initialize class methods, call registerMethodsClass from classes inheriting this class 70 void registerMethodsClass(classFunctionst *f); 71 72 void initiateclasst(classt *self); 73 void freeclasst(classt *self); 74 void terminateclasst(classt **self); 75 classt* duplicateclasst(classt **self); 76 77 // Prototypes 78 void print(classt *self, char *s); 79 80 void initiateAllocateclasst(classt **self) { 81 82 (*self) = malloc(sizeof(classt)); 83 initiateclasst(*self); 84 } 85 86 void initiateclasst(classt *self) { 87 88 if (!classF) { 89 classF = malloc(sizeof(classFunctionst)); 90 registerMethodsClass(classF); 91 } 92 self->f = classF; 93 self->a = 0; 94 self->s = NULL; 95 96 // class name 97 self->type = classtName; 98 } 99 100 void registerMethodsClass(classFunctionst *f) { 101 102 f->free = freeclasst; 103 f->terminate = terminateclasst; 104 f->duplicate = duplicateclasst; 105 f->print = print; 106 107 } 108 109 void freeclasst(classt *self) { 110 if (self->s) 111 free(self->s); 112 } 113 114 void terminateclasst(classt **self) { 115 116 (*self)->f->free(*self); 117 free((*self)); 118 *self = NULL; 119 } 120 121 classt* duplicateclasst(classt **self) { 122 123 createAllocateclasst(r); 124 125 r->a = (*self)->a; 126 if ((*self)->s) 127 r->s = strdup((*self)->s); 128 return r; 129 } 130 131 // Members 132 void print(classt *self, char *s) { 133 self->s = strdup(s); 134 printf(self->s); 135 } 136 137 // END class 138 139 void main() { 140 141 printf("Size of class: %d", sizeof(classt)); 142 143 createclasst(obj1); 144 obj1.f->print(&obj1, "\nRegular Object\n"); 145 printf("\ndirect access %s", obj1.s); 146 obj1.f->free(&obj1); 147 148 createAllocateclasst(obj2); 149 obj2->f->print(obj2, "\nObject in heap\n"); 150 obj2->f->terminate(&obj2); 151 152 // initiate alternative 153 classt obj3; 154 initiateclasst(&obj3); 155 obj3.f->print(&obj3, "\n\nObj 3\n"); 156 freeO(obj3); 157 158 classt *obj4; 159 initiateAllocateclasst(&obj4); 160 obj4->f->print(obj4, "\nOBJ 4\n"); 161 deleteO(obj4); 162 163 // unknown object 164 void *unObj = &obj3; 165 baset *o; 166 o = (baset *) unObj; 167 printf("\nObject type: %s\n", o->type); 168 o->f->print(o, "\nOBJ UNKNOWN\n"); 169 170 if (isOType(unObj, classtName)) { 171 printf("Object type: %s\n", ((baset *) unObj)->type); 172 } 173 }