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,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 | * This is new and currently it is only possible to create | 122 | * This is new and currently it is only possible to create |
123 | * instances for class that does not need a constructor. | 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 | * This does not call any constructor with any value...this | 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 | * I initialize _ (the class's base or parent class) | 142 | * I initialize _ (the class's base or parent class) |
@@ -185,7 +187,7 @@ | @@ -185,7 +187,7 @@ | ||
185 | * | 187 | * |
186 | * /see TR_CLASS_MAGIC | 188 | * /see TR_CLASS_MAGIC |
187 | */ | 189 | */ |
188 | -#define TR_IS_OBJECT(obj) \ | 190 | +#define TR_IS_OBJECT(obj) \ |
189 | ((TR_GET_CLASS((obj)))->magic == TR_CLASS_MAGIC) | 191 | ((TR_GET_CLASS((obj)))->magic == TR_CLASS_MAGIC) |
190 | 192 | ||
191 | /** | 193 | /** |
@@ -204,7 +206,7 @@ | @@ -204,7 +206,7 @@ | ||
204 | * | 206 | * |
205 | * \cond PRIVATE | 207 | * \cond PRIVATE |
206 | */ | 208 | */ |
207 | -#define _TR_CALL(_class,_iface,method,...) \ | 209 | +#define _TR_CALL(_class,_iface,method) \ |
208 | do { \ | 210 | do { \ |
209 | TR_class_ptr class = _class; \ | 211 | TR_class_ptr class = _class; \ |
210 | iface = (struct i_##_iface *)TR_IFACE_GET(class, &i_##_iface); \ | 212 | iface = (struct i_##_iface *)TR_IFACE_GET(class, &i_##_iface); \ |
@@ -226,11 +228,11 @@ | @@ -226,11 +228,11 @@ | ||
226 | * \todo actually i use gcc feature ## for variadoc... think about | 228 | * \todo actually i use gcc feature ## for variadoc... think about |
227 | * a way to make this standard. | 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 | } while(0) | 236 | } while(0) |
235 | 237 | ||
236 | /** | 238 | /** |
@@ -240,11 +242,11 @@ | @@ -240,11 +242,11 @@ | ||
240 | * | 242 | * |
241 | * \see TR_CALL | 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 | } while(0) | 250 | } while(0) |
249 | 251 | ||
250 | /** | 252 | /** |
@@ -253,13 +255,13 @@ | @@ -253,13 +255,13 @@ | ||
253 | * | 255 | * |
254 | * \see TR_CALL | 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 | } while(0) | 265 | } while(0) |
264 | 266 | ||
265 | /* | 267 | /* |
@@ -268,13 +270,13 @@ | @@ -268,13 +270,13 @@ | ||
268 | * | 270 | * |
269 | * \see TR_RETCALL | 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 | } while(0) | 280 | } while(0) |
279 | 281 | ||
280 | 282 |
@@ -72,6 +72,16 @@ void * TR_classNew(TR_class_ptr, ...); | @@ -72,6 +72,16 @@ void * TR_classNew(TR_class_ptr, ...); | ||
72 | void * TR_classNewv(TR_class_ptr, va_list *); | 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 | * Interface caller function for i_class::dtor. | 85 | * Interface caller function for i_class::dtor. |
76 | * Never called directly. | 86 | * Never called directly. |
77 | * | 87 | * |
@@ -122,4 +122,24 @@ TR_classClone(void * _object) | @@ -122,4 +122,24 @@ TR_classClone(void * _object) | ||
122 | } | 122 | } |
123 | /** endcond */ | 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 | // vim: set ts=4 sw=4: | 145 | // vim: set ts=4 sw=4: |
Please
register
or
login
to post a comment