Skip to content

Instantly share code, notes, and snippets.

@enfiskutensykkel
Created December 7, 2017 15:16
Show Gist options
  • Save enfiskutensykkel/7f4900ab8d28c1ab6bce26281d77b1a8 to your computer and use it in GitHub Desktop.
Save enfiskutensykkel/7f4900ab8d28c1ab6bce26281d77b1a8 to your computer and use it in GitHub Desktop.
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
struct __attribute__((packed)) class_object
{
// TODO* handle
void *super;
void (*destructor)(void*, void*);
size_t data_size;
void *data_ptr;
};
#define object_reference(object) \
((struct class_object*) (((char*) object) - sizeof(struct class_object)))
#define super(object) \
((struct class_object*) object_reference(object)->super)->data_ptr
// TODO: define handle(object)
void __delete_object(void *object, void *ptr) // TODO: remove ptr and use handle
{
if (ptr != object) // just omit warning
{
free(ptr);
}
}
void __create_object(void *object)
{
struct class_object *this = object;
this->super = object;
this->destructor = __delete_object;
this->data_size = 0;
this->data_ptr = NULL;
}
#define define_class(name, base, type) \
struct class_##name \
{ \
struct class_object header; \
type data; \
struct class_##base base_type; \
}
#define class(name, base, type) \
struct class_##name; \
\
void __delete_##name(void *object, void *ptr) \
{ \
struct class_object *this = object; \
delete_##name(this->data_ptr); \
__delete_##base(this->super, ptr); \
} \
\
type * __create_##name(void *object) \
{ \
size_t class_size = sizeof(type); \
size_t class_offset = sizeof(struct class_object); \
struct class_object *this = object; \
\
if (object == NULL) \
{ \
return NULL; \
} \
\
this->super = ((char*) object) + class_offset + class_size; \
this->destructor = __delete_##name; \
this->data_size = class_size; \
this->data_ptr = ((char*) object) + class_offset; \
\
__create_##base(this->super); \
\
create_##name(this->data_ptr); \
\
return this->data_ptr; \
} \
\
define_class(name, base, type)
#define new(name) \
__create_##name(malloc(sizeof(struct class_##name))) // TODO: pass (null, malloc)
#define del(object) \
object_reference(object)->destructor(object_reference(object), object_reference(object))
struct A
{
int member;
};
void create_A(struct A *this)
{
this->member = 2;
printf("A's ctor, member=%d\n", this->member);
}
void delete_A(struct A *this)
{
printf("A's dtor, member=%d\n", this->member);
}
class(A, object, struct A);
struct B
{
int member;
};
void create_B(struct B *this)
{
((struct A*) super(this))->member = this->member = 3;
}
void delete_B(struct B *this)
{
printf("B's dtor, B::member=%d A::member=%d\n", this->member, ((struct A*) super(this))->member);
}
class(B, A, struct B);
int main()
{
struct B *b = new(B);
b->member = 5;
del(b);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment