objects

objects in c
git clone https://noulin.net/git/objects.git
Log | Files | Refs | README | LICENSE

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 }