Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

C + OOP = <3

Name: Anonymous 2021-04-09 11:40

oop.h:
#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);
}

Name: Anonymous 2021-04-09 11:44

else
free (r);
fixed:
else
{
free (r);
return 0;
}

Name: Anonymous 2021-04-09 11:58

<i>> args[static n]</i>

That is some GCC extension. You fail.

Name: Anonymous 2021-04-09 12:12


Don't change these.
Name: Email:
Entire Thread Thread List