Created
December 7, 2017 15:16
-
-
Save enfiskutensykkel/7f4900ab8d28c1ab6bce26281d77b1a8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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