Commit f68ee33914f414bf92f8d44a678ce10f6dcd5b1e
1 parent
988ce39e
Modify TR_INSTANCE to get variable argument list for the initialization values, …
…effectively remove the need for this ugly stray closing curly bracket. Add TR_objectInit function which allows to call the constructor on an already existing object. Remove not used variable argument list on _TR_CALL and fix corresponding makros.
Showing
3 changed files
with
70 additions
and
38 deletions
| ... | ... | @@ -118,23 +118,25 @@ |
| 118 | 118 | |
| 119 | 119 | |
| 120 | 120 | /** |
| 121 | - * NEW. Create a static instance of a class. | |
| 121 | + * Create a static instance of a class. | |
| 122 | 122 | * This is new and currently it is only possible to create |
| 123 | 123 | * instances for class that does not need a constructor. |
| 124 | 124 | * |
| 125 | - * \todo | |
| 126 | - * This macro requires to close the initializer | |
| 127 | - * with an extra curly brancket. This is not nice...find a | |
| 128 | - * way to prevent this. | |
| 129 | - * \todo | |
| 130 | 125 | * This does not call any constructor with any value...this |
| 131 | - * has to be fixed. | |
| 126 | + * has to be fixed. // When this macro is used within a global | |
| 127 | + * (static) context this can't be fixed. No function can be | |
| 128 | + * called from there. Instead I add a TR_objectInit function which | |
| 129 | + * takes an object name (created on either the stack or the | |
| 130 | + * heap) and a variable argument list and calls its constructor | |
| 131 | + * with the arguments. | |
| 132 | 132 | */ |
| 133 | -#define TR_INSTANCE(class, name) \ | |
| 134 | - struct c_##class##_object _##name; \ | |
| 135 | - class name = &(_##name.data); \ | |
| 136 | - struct c_##class##_object _##name = { \ | |
| 137 | - &c_##class, | |
| 133 | +#define TR_INSTANCE(class, name, ...) \ | |
| 134 | + struct c_##class##_object _##name; \ | |
| 135 | + class name = &(_##name.data); \ | |
| 136 | + struct c_##class##_object _##name = { \ | |
| 137 | + &c_##class, \ | |
| 138 | + { ##__VA_ARGS__ } \ | |
| 139 | + } | |
| 138 | 140 | |
| 139 | 141 | /** |
| 140 | 142 | * I initialize _ (the class's base or parent class) |
| ... | ... | @@ -185,7 +187,7 @@ |
| 185 | 187 | * |
| 186 | 188 | * /see TR_CLASS_MAGIC |
| 187 | 189 | */ |
| 188 | -#define TR_IS_OBJECT(obj) \ | |
| 190 | +#define TR_IS_OBJECT(obj) \ | |
| 189 | 191 | ((TR_GET_CLASS((obj)))->magic == TR_CLASS_MAGIC) |
| 190 | 192 | |
| 191 | 193 | /** |
| ... | ... | @@ -204,7 +206,7 @@ |
| 204 | 206 | * |
| 205 | 207 | * \cond PRIVATE |
| 206 | 208 | */ |
| 207 | -#define _TR_CALL(_class,_iface,method,...) \ | |
| 209 | +#define _TR_CALL(_class,_iface,method) \ | |
| 208 | 210 | do { \ |
| 209 | 211 | TR_class_ptr class = _class; \ |
| 210 | 212 | iface = (struct i_##_iface *)TR_IFACE_GET(class, &i_##_iface); \ |
| ... | ... | @@ -226,11 +228,11 @@ |
| 226 | 228 | * \todo actually i use gcc feature ## for variadoc... think about |
| 227 | 229 | * a way to make this standard. |
| 228 | 230 | */ |
| 229 | -#define TR_CALL(object,_iface,method,...) \ | |
| 230 | - do { \ | |
| 231 | - struct i_##_iface * iface; \ | |
| 232 | - _TR_CALL(TR_GET_CLASS(object), _iface, method, ##__VA_ARGS__); \ | |
| 233 | - iface->method(object, ##__VA_ARGS__); \ | |
| 231 | +#define TR_CALL(object,_iface,method,...) \ | |
| 232 | + do { \ | |
| 233 | + struct i_##_iface * iface; \ | |
| 234 | + _TR_CALL(TR_GET_CLASS(object), _iface, method); \ | |
| 235 | + iface->method(object, ##__VA_ARGS__); \ | |
| 234 | 236 | } while(0) |
| 235 | 237 | |
| 236 | 238 | /** |
| ... | ... | @@ -240,11 +242,11 @@ |
| 240 | 242 | * |
| 241 | 243 | * \see TR_CALL |
| 242 | 244 | */ |
| 243 | -#define TR_RETCALL(object,_iface,method,ret,...) \ | |
| 244 | - do { \ | |
| 245 | - struct i_##_iface * iface; \ | |
| 246 | - _TR_CALL(TR_GET_CLASS(object), _iface, method, ##__VA_ARGS__); \ | |
| 247 | - ret = iface->method(object, ##__VA_ARGS__); \ | |
| 245 | +#define TR_RETCALL(object,_iface,method,ret,...) \ | |
| 246 | + do { \ | |
| 247 | + struct i_##_iface * iface; \ | |
| 248 | + _TR_CALL(TR_GET_CLASS(object), _iface, method); \ | |
| 249 | + ret = iface->method(object, ##__VA_ARGS__); \ | |
| 248 | 250 | } while(0) |
| 249 | 251 | |
| 250 | 252 | /** |
| ... | ... | @@ -253,13 +255,13 @@ |
| 253 | 255 | * |
| 254 | 256 | * \see TR_CALL |
| 255 | 257 | */ |
| 256 | -#define TR_PARENTCALL(object,_iface,method,...) \ | |
| 257 | - do { \ | |
| 258 | - struct i_##_iface * iface; \ | |
| 259 | - TR_class_ptr pc_class = TR_GET_CLASS((object)); \ | |
| 260 | - assert(TR_HAS_PARENT(pc_class)); \ | |
| 261 | - _TR_CALL(pc_class->parent, _iface, method, ##__VA_ARGS__); \ | |
| 262 | - iface->method(object, ##__VA_ARGS__); \ | |
| 258 | +#define TR_PARENTCALL(object,_iface,method,...) \ | |
| 259 | + do { \ | |
| 260 | + struct i_##_iface * iface; \ | |
| 261 | + TR_class_ptr pc_class = TR_GET_CLASS((object)); \ | |
| 262 | + assert(TR_HAS_PARENT(pc_class)); \ | |
| 263 | + _TR_CALL(pc_class->parent, _iface, method); \ | |
| 264 | + iface->method(object, ##__VA_ARGS__); \ | |
| 263 | 265 | } while(0) |
| 264 | 266 | |
| 265 | 267 | /* |
| ... | ... | @@ -268,13 +270,13 @@ |
| 268 | 270 | * |
| 269 | 271 | * \see TR_RETCALL |
| 270 | 272 | */ |
| 271 | -#define TR_PARENTRETCALL(object,_iface,method,ret,...) \ | |
| 272 | - do { \ | |
| 273 | - struct i_##_iface * iface; \ | |
| 274 | - TR_class_ptr pc_class = TR_GET_CLASS((object)); \ | |
| 275 | - assert(TR_HAS_PARENT(pc_class)); \ | |
| 276 | - _TR_CALL(pc_class->parent, _iface, method, ##__VA_ARGS__); \ | |
| 277 | - ret = iface->method(object, ##__VA_ARGS__); \ | |
| 273 | +#define TR_PARENTRETCALL(object,_iface,method,ret,...) \ | |
| 274 | + do { \ | |
| 275 | + struct i_##_iface * iface; \ | |
| 276 | + TR_class_ptr pc_class = TR_GET_CLASS((object)); \ | |
| 277 | + assert(TR_HAS_PARENT(pc_class)); \ | |
| 278 | + _TR_CALL(pc_class->parent, _iface, method); \ | |
| 279 | + ret = iface->method(object, ##__VA_ARGS__); \ | |
| 278 | 280 | } while(0) |
| 279 | 281 | |
| 280 | 282 | ... | ... |
| ... | ... | @@ -72,6 +72,16 @@ void * TR_classNew(TR_class_ptr, ...); |
| 72 | 72 | void * TR_classNewv(TR_class_ptr, va_list *); |
| 73 | 73 | |
| 74 | 74 | /** |
| 75 | + * Interface caller function for i_class::ctor. | |
| 76 | + * This is called when an instance of a class is created | |
| 77 | + * with TR_INSTANCE (created on the stack). | |
| 78 | + * Never called directly. | |
| 79 | + * | |
| 80 | + * \see TR_delete | |
| 81 | + */ | |
| 82 | +int TR_objectInit(void *, ...); | |
| 83 | + | |
| 84 | +/** | |
| 75 | 85 | * Interface caller function for i_class::dtor. |
| 76 | 86 | * Never called directly. |
| 77 | 87 | * | ... | ... |
| ... | ... | @@ -122,4 +122,24 @@ TR_classClone(void * _object) |
| 122 | 122 | } |
| 123 | 123 | /** endcond */ |
| 124 | 124 | |
| 125 | +/** | |
| 126 | + * Interface caller function for i_class::ctor. | |
| 127 | + * Call the constructor on an existing object identified by name. | |
| 128 | + * In fact it calls first the destructor to ensure that all | |
| 129 | + * possibly previously acquired resource are cleaned. | |
| 130 | + */ | |
| 131 | +int | |
| 132 | +TR_objectInit(void * object, ...) | |
| 133 | +{ | |
| 134 | + int ret; | |
| 135 | + va_list params; | |
| 136 | + | |
| 137 | + va_start(params, object); | |
| 138 | + TR_CALL(object, TR_Class, dtor); | |
| 139 | + TR_RETCALL(object, TR_Class, ctor, ret, ¶ms); | |
| 140 | + va_end(params); | |
| 141 | + | |
| 142 | + return ret; | |
| 143 | +} | |
| 144 | + | |
| 125 | 145 | // vim: set ts=4 sw=4: | ... | ... |
Please
register
or
login
to post a comment