#if !defined(_RTTI_TYPEINFO_H_) #define _RTTI_TYPEINFO_H_ 1 #include #include #include #include #include #include #define RTTI_MAGIC (0x5254544949545452) #define var void* #define RTTI_SIZE_ROUNDUP(sz) \ ((((sz + sizeof(void*) - 1)) / (sizeof(void*))) * sizeof(void*)) #define RTTI_OBJ_HEADER_SIZE RTTI_SIZE_ROUNDUP(sizeof(meta_obj_t)) /** Object format ** ** +=====================+===================+===================+ ** | | | <- public data > | ** +=====================+===================+===================+ ** **/ #define RTTI_OBJ_TO_DATA(T, obj) ((T*)((obj)->data)) #define RTTI_DATA_TO_OBJ(v) \ (((v) == NULL) ? NULL : ((meta_obj_t*)(((char*)v) - RTTI_OBJ_HEADER_SIZE))) #define RTTI_OBJ_TO_PRIV(obj) ((obj)->privdata) #define RTTI_GET_METHOD(result, obj, intf, method) \ do { \ typeinfo_t* type_ = NULL; \ \ (result) = NULL; \ \ if ((obj) == NULL) { \ break; \ } \ \ type_ = obj->type; \ if (type_ == NULL) { \ break; \ } \ \ if (type_->interfaces.intf == NULL) { \ break; \ } \ \ (result) = type_->interfaces.intf->method; \ } while (0) #define RTTI_OBJ_INVALID(obj) (((obj) == NULL) || ((obj)->magic != RTTI_MAGIC)) struct meta_obj_; struct typeinfo_; typedef struct meta_obj_ meta_obj_t; typedef struct typeinfo_ typeinfo_t; /* calculate the size of data */ typedef size_t (*datasize_fn_t)(va_list); /* object life cycle */ typedef int (*obj_init_fn_t)(meta_obj_t*, va_list); typedef void (*obj_destroy_fn_t)(meta_obj_t*); /* lock/unlock */ enum { RTTI_LOCK_READ = 0, RTTI_LOCK_WRITE }; typedef int (*lock_fn_t)(meta_obj_t*, uint64_t); typedef void (*unlock_fn_t)(meta_obj_t*); typedef struct { lock_fn_t lock; unlock_fn_t unlock; } intf_lock_t; /* convert to string */ typedef char* (*to_string_fn_t)(meta_obj_t*, va_list); typedef struct { to_string_fn_t toString; } intf_tostring_t; /* iterator function */ #define RTTI_ITER_NO_DATA (0) #define RTTI_ITER_OK (1) typedef struct { meta_obj_t* obj; var data; } iterator_t; typedef int (*iter_make_fn_t)(iterator_t*); typedef int (*iter_next_fn_t)(iterator_t*, void**); typedef int (*iter_reset_fn_t)(iterator_t*); typedef void (*iter_destroy_fn_t)(iterator_t*); typedef struct { iter_make_fn_t make; iter_next_fn_t next; iter_reset_fn_t reset; iter_destroy_fn_t destroy; } intf_iterator_t; /* reference and deref */ typedef int32_t (*reference_fn_t)(meta_obj_t*); typedef void (*dereference_fn_t)(meta_obj_t*); typedef struct { reference_fn_t reference; dereference_fn_t dereference; } intf_reference_t; /* hash */ typedef int32_t (*hash_fn_t)(meta_obj_t*); typedef struct { hash_fn_t hash; } intf_hash_t; /* length */ typedef int64_t (*length_fn_t)(meta_obj_t*); typedef struct { length_fn_t length; } intf_length_t; typedef struct { intf_lock_t* lock; intf_tostring_t* toString; intf_iterator_t* iter; intf_reference_t* reference; intf_hash_t* hash; intf_length_t* length; } interface_table_t; struct typeinfo_ { char* name; size_t privateSize; datasize_fn_t dataSize; obj_init_fn_t init; obj_destroy_fn_t destroy; interface_table_t interfaces; }; struct meta_obj_ { uint64_t magic; typeinfo_t* type; void* privdata; void* data; }; extern var makeInstance(typeinfo_t*, ...); extern void destroy(var); extern int is_rtti_obj(var); extern int lock(var, uint64_t); extern void unlock(var); extern char* toString(var, ...); extern int iter_make(iterator_t*, var); extern int iter_next(iterator_t*, void**); extern int iter_reset(iterator_t*); extern void iter_destroy(iterator_t*); extern int32_t hash(var); extern int64_t length(var); extern int32_t reference(var); extern void dereference(var); #endif