Name: Anonymous 2021-04-09 11:40
oop.h:
oop.c:
string.h:
string.c:
int.h:
int.c:
main.c:
#include <stddef.h>
struct type
{
/* 0 if type itself
* &interface_type if an interface */
const struct type *parent;
const char *name;
/* interfaces */
size_t n;
const struct interface **interfaces;
/* ctor */
void *(*ctor)(size_t n,
const void *[n]);
};
struct interface
{
const struct type *type;
const char *name;
};
struct Object_base
{
const struct type *type;
void (*dtor)(void *);
};
struct Object_full
{
struct Object_base base;
void *parent_impl;
void **impls;
};
struct Object_nointerfaces
{
struct Object_base base;
void *parent_impl;
};
struct Object_noparent
{
struct Object_base base;
void **impls;
};
extern const struct type interface_type[1];
#define NEW(type, ...) (type)->ctor(sizeof((const void *[]){__VA_ARGS__}) / sizeof(const void *), (const void *[]){__VA_ARGS__})
extern const struct type *getType (const void *p);
extern void delete (void *p);
oop.c:
#include "oop.h"
#include <assert.h>
const struct type interface_type[1] = {{0, "Base interface type", 0, 0}};
const struct type *
getType (const void *p)
{
const struct Object_base *obj = p;
assert (obj);
return obj->type;
}
void
delete (void *p)
{
struct Object_base *p2 = p;
if (p2)
p2->dtor (p);
}
string.h:
struct String;
extern struct type String[1];
extern char *getCString (const struct String *);
string.c:
#include "oop.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
static void *ctor (size_t n,
const void *args[n]);
const struct type String[1] = {{0, "String", 0, 0, ctor}};
struct String
{
struct Object_base obj;
size_t n;
char *s;
};
static void
dtor (void *p)
{
struct String *s = p;
if (s)
{
assert (getType (s) == String);
free (s->s);
free (p);
}
}
static void *
ctor (size_t n,
const void *args[n])
{
struct String *r;
assert (n == 1);
assert (args[0]);
r = malloc (sizeof *r);
if (r)
{
r->obj.type = String;
r->obj.dtor = dtor;
r->n = strlen (args[0]);
r->s = malloc (r->n + 1);
if (r->s)
memcpy (r->s, args[0], r->n + 1);
else
free (r);
}
return r;
}
char *
getCString (const struct String *s)
{
assert (getType (s) == String);
return s->s;
}
int.h:
struct Int;
extern struct type Int[1];
extern int getInt (const struct Int *);
int.c:
#include "oop.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
static void *ctor (size_t n,
const void *args[n]);
const struct type Int[1] = {{0, "Integer", 0, 0, ctor}};
struct Int
{
struct Object_base obj;
int i;
};
static void
dtor (void *p)
{
struct Int *i = p;
if (i)
{
assert (getType (i) == Int);
free (i);
}
}
static void *
ctor (size_t n,
const void *args[static n])
{
struct Int *r;
assert (n == 1);
assert (args);
assert (args[0]);
r = malloc (sizeof *r);
if (r)
{
const int *i = args[0];
r->obj.type = Int;
r->obj.dtor = dtor;
r->i = *i;
}
return r;
}
int
getInt (const struct Int *i)
{
assert (i);
assert (getType (i) == Int);
return i->i;
}
main.c:
#include "oop.h"
#include "string.h"
#include "int.h"
#include <stdio.h>
#define PRINT(...) print((const void *[]){__VA_ARGS__, 0})
void
print (const void **p)
{
for (; *p; p++)
{
const struct type *type = getType (*p);
if (type == String)
{
const struct String *s = *p;
printf ("%s", getCString (s));
}
else if (type == Int)
{
const struct Int *i = *p;
printf ("%d", getInt (i));
}
}
}
int
main (void)
{
void *s1 = NEW (String, "aaa");
void *i = NEW (Int, (int []){5});
void *s2 = NEW (String, "bbb\n");
PRINT (s1, i, s2);
delete (s1);
delete (i);
delete (s2);
}