Commit f68ee33914f414bf92f8d44a678ce10f6dcd5b1e

Authored by Georg Hopp
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.
... ... @@ -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, &params);
  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