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